feat(selectors): always make xpath relative (#5252)
This makes `/foo` and `//foo` match starting with the scope, not the document, by turning them into `./foo` and `.//foo`.
This commit is contained in:
parent
e0f41bf1fd
commit
6c12f58058
|
|
@ -18,6 +18,8 @@ import { SelectorEngine, SelectorRoot } from './selectorEngine';
|
||||||
|
|
||||||
export const XPathEngine: SelectorEngine = {
|
export const XPathEngine: SelectorEngine = {
|
||||||
query(root: SelectorRoot, selector: string): Element | undefined {
|
query(root: SelectorRoot, selector: string): Element | undefined {
|
||||||
|
if (selector.startsWith('/'))
|
||||||
|
selector = '.' + selector;
|
||||||
const document = root instanceof Document ? root : root.ownerDocument;
|
const document = root instanceof Document ? root : root.ownerDocument;
|
||||||
if (!document)
|
if (!document)
|
||||||
return;
|
return;
|
||||||
|
|
@ -29,6 +31,8 @@ export const XPathEngine: SelectorEngine = {
|
||||||
},
|
},
|
||||||
|
|
||||||
queryAll(root: SelectorRoot, selector: string): Element[] {
|
queryAll(root: SelectorRoot, selector: string): Element[] {
|
||||||
|
if (selector.startsWith('/'))
|
||||||
|
selector = '.' + selector;
|
||||||
const result: Element[] = [];
|
const result: Element[] = [];
|
||||||
const document = root instanceof Document ? root : root.ownerDocument;
|
const document = root instanceof Document ? root : root.ownerDocument;
|
||||||
if (!document)
|
if (!document)
|
||||||
|
|
|
||||||
|
|
@ -184,3 +184,24 @@ it('should escape the scope with >>', async ({ page }) => {
|
||||||
await page.setContent(`<div><label>Test</label><input id='myinput'></div>`);
|
await page.setContent(`<div><label>Test</label><input id='myinput'></div>`);
|
||||||
expect(await page.$eval(`label >> xpath=.. >> input`, e => e.id)).toBe('myinput');
|
expect(await page.$eval(`label >> xpath=.. >> input`, e => e.id)).toBe('myinput');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('xpath should be relative', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<span class="find-me" id=target1>1</span>
|
||||||
|
<div>
|
||||||
|
<span class="find-me" id=target2>2</span>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
expect(await page.$eval(`//*[@class="find-me"]`, e => e.id)).toBe('target1');
|
||||||
|
|
||||||
|
const div = await page.$('div');
|
||||||
|
expect(await div.$eval(`xpath=./*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await div.$eval(`xpath=.//*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await div.$eval(`//*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await div.$eval(`xpath=/*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
|
||||||
|
expect(await page.$eval(`div >> xpath=./*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await page.$eval(`div >> xpath=.//*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await page.$eval(`div >> //*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
expect(await page.$eval(`div >> xpath=/*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue