fix(selectors): do not automatically enter shadow roots with >> (#1812)

Now that we have shadow-aware selector engines, this extra logic adds confusion
and does not help to actually query the element.
This commit is contained in:
Dmitry Gozman 2020-04-15 16:12:45 -07:00 committed by GitHub
parent f3451d9148
commit 56aa4c2e71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 24 deletions

View File

@ -56,7 +56,6 @@ class SelectorEvaluator {
private _querySelectorRecursively(root: SelectorRoot, selector: types.ParsedSelector, index: number): Element | undefined {
const current = selector[index];
root = (root as Element).shadowRoot || root;
if (index === selector.length - 1)
return this.engines.get(current.name)!.query(root, current.body);
const all = this.engines.get(current.name)!.queryAll(root, current.body);
@ -74,7 +73,7 @@ class SelectorEvaluator {
for (const { name, body } of selector) {
const newSet = new Set<Element>();
for (const prev of set) {
for (const next of this.engines.get(name)!.queryAll((prev as Element).shadowRoot || prev, body)) {
for (const next of this.engines.get(name)!.queryAll(prev, body)) {
if (newSet.has(next))
continue;
newSet.add(next);

View File

@ -103,22 +103,9 @@ describe('Page.$eval', function() {
});
it('should support spaces with >> syntax', async({page, server}) => {
await page.goto(server.PREFIX + '/deep-shadow.html');
const text = await page.$eval(' css:light = div >>css:light=div>>css:light = span ', e => e.textContent);
const text = await page.$eval(' css = div >>css=div>>css = span ', e => e.textContent);
expect(text).toBe('Hello from root2');
});
it('should enter shadow roots with >> syntax', async({page, server}) => {
await page.goto(server.PREFIX + '/deep-shadow.html');
const text1 = await page.$eval('css:light=div >> css:light=span', e => e.textContent);
expect(text1).toBe('Hello from root1');
const text2 = await page.$eval('css:light=div >> css:light=*:nth-child(2) >> css:light=span', e => e.textContent);
expect(text2).toBe('Hello from root2');
const nonExisting = await page.$('css:light=div div >> css:light=span');
expect(nonExisting).not.toBeTruthy();
const text3 = await page.$eval('css:light=section div >> css:light=span', e => e.textContent);
expect(text3).toBe('Hello from root1');
const text4 = await page.$eval('xpath=/html/body/section/div >> css:light=div >> css:light=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('<div><span>Next</span><button>Previous</button><button>Next</button></div>');
const html = await page.$eval('button >> "Next"', e => e.outerHTML);
@ -152,11 +139,6 @@ describe('Page.$$eval', function() {
const spansCount = await page.$$eval('css=div >> css=span', spans => spans.length);
expect(spansCount).toBe(3);
});
it('should enter shadow roots with >> syntax', async({page, server}) => {
await page.goto(server.PREFIX + '/deep-shadow.html');
const spansCount = await page.$$eval('css:light=div >> css:light=div >> css:light=span', spans => spans.length);
expect(spansCount).toBe(3);
});
});
describe('Page.$', function() {
@ -571,12 +553,13 @@ describe('css selector', () => {
const root2 = await page.$(`css=div div`);
expect(await root2.$eval(`css=#target`, e => e.textContent)).toBe('Hello from root2');
expect(await root2.$eval(`css:light=#target`, e => e.textContent)).toBe('Hello from root2');
expect(await root2.$(`css:light=#target`)).toBe(null);
const root2Shadow = await root2.evaluateHandle(r => r.shadowRoot);
expect(await root2Shadow.$eval(`css:light=#target`, e => e.textContent)).toBe('Hello from root2');
const root3 = (await page.$$(`css=div div`))[1];
expect(await root3.$eval(`text=root3`, e => e.textContent)).toBe('Hello from root3');
expect(await root3.$eval(`css=[attr*="value"]`, e => e.textContent)).toBe('Hello from root3 #2');
// TODO: the following should be null, but we implicitly enter shadow root.
expect(await root3.$(`css:light=[attr*="value"]`)).not.toBe(null);
expect(await root3.$(`css:light=[attr*="value"]`)).toBe(null);
});
});