Skip to content

Commit 342a2cf

Browse files
authored
fix(selectors): continue matching after first fail for combined selectors (#1185)
1 parent 342e79c commit 342a2cf

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/injected/injected.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,20 @@ class Injected {
6868
const parsed = this._parseSelector(selector);
6969
if (!(root as any)['querySelector'])
7070
throw new Error('Node is not queryable.');
71-
let element = root as SelectorRoot;
72-
for (const { engine, selector } of parsed) {
73-
const next = engine.query((element as Element).shadowRoot || element, selector);
74-
if (!next)
75-
return;
76-
element = next;
71+
return this._querySelectorRecursively(root as SelectorRoot, parsed, 0);
72+
}
73+
74+
private _querySelectorRecursively(root: SelectorRoot, parsed: ParsedSelector, index: number): Element | undefined {
75+
const current = parsed[index];
76+
root = (root as Element).shadowRoot || root;
77+
if (index === parsed.length - 1)
78+
return current.engine.query(root, current.selector);
79+
const all = current.engine.queryAll(root, current.selector);
80+
for (const next of all) {
81+
const result = this._querySelectorRecursively(next, parsed, index + 1);
82+
if (result)
83+
return result;
7784
}
78-
return element as Element;
7985
}
8086

8187
querySelectorAll(selector: string, root: Node): Element[] {

test/queryselector.spec.js

+5
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ module.exports.describe = function({testRunner, expect, selectors, FFOX, CHROMIU
126126
const text4 = await page.$eval('xpath=/html/body/section/div >> css=div >> css=span', e => e.textContent);
127127
expect(text4).toBe('Hello from root2');
128128
});
129+
it('should not stop at first failure with >> syntax', async({page, server}) => {
130+
await page.setContent('<div><span>Next</span><button>Previous</button><button>Next</button></div>');
131+
const html = await page.$eval('button >> "Next"', e => e.outerHTML);
132+
expect(html).toBe('<button>Next</button>');
133+
});
129134
});
130135

131136
describe('Page.$$eval', function() {

0 commit comments

Comments
 (0)