diff --git a/src/injected/injected.ts b/src/injected/injected.ts index fa4d706f04..8fd3afd49c 100644 --- a/src/injected/injected.ts +++ b/src/injected/injected.ts @@ -68,14 +68,20 @@ class Injected { const parsed = this._parseSelector(selector); if (!(root as any)['querySelector']) throw new Error('Node is not queryable.'); - let element = root as SelectorRoot; - for (const { engine, selector } of parsed) { - const next = engine.query((element as Element).shadowRoot || element, selector); - if (!next) - return; - element = next; + return this._querySelectorRecursively(root as SelectorRoot, parsed, 0); + } + + private _querySelectorRecursively(root: SelectorRoot, parsed: ParsedSelector, index: number): Element | undefined { + const current = parsed[index]; + root = (root as Element).shadowRoot || root; + if (index === parsed.length - 1) + return current.engine.query(root, current.selector); + const all = current.engine.queryAll(root, current.selector); + for (const next of all) { + const result = this._querySelectorRecursively(next, parsed, index + 1); + if (result) + return result; } - return element as Element; } querySelectorAll(selector: string, root: Node): Element[] { diff --git a/test/queryselector.spec.js b/test/queryselector.spec.js index 02df00c7e0..5ed72303d6 100644 --- a/test/queryselector.spec.js +++ b/test/queryselector.spec.js @@ -126,6 +126,11 @@ module.exports.describe = function({testRunner, expect, selectors, FFOX, CHROMIU const text4 = await page.$eval('xpath=/html/body/section/div >> css=div >> css=span', e => e.textContent); expect(text4).toBe('Hello from root2'); }); + it('should not stop at first failure with >> syntax', async({page, server}) => { + await page.setContent('
Next
'); + const html = await page.$eval('button >> "Next"', e => e.outerHTML); + expect(html).toBe(''); + }); }); describe('Page.$$eval', function() {