fix(selector generator): escape all tag names in css selectors (#26659)

Fixes #26657.
This commit is contained in:
Dmitry Gozman 2023-08-23 12:32:08 -07:00 committed by GitHub
parent 46e33cd384
commit 44d3770559
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 2 deletions

View File

@ -265,7 +265,7 @@ function buildTextCandidates(injectedScript: InjectedScript, element: Element, i
candidates.push([{ engine: 'internal:text', selector: escaped, score: kTextScore }]);
candidates.push([{ engine: 'internal:text', selector: escapeForTextSelector(text, true), score: kTextScoreExact }]);
}
const cssToken: SelectorToken = { engine: 'css', selector: element.nodeName.toLowerCase(), score: kCSSTagNameScore };
const cssToken: SelectorToken = { engine: 'css', selector: cssEscape(element.nodeName.toLowerCase()), score: kCSSTagNameScore };
candidates.push([cssToken, { engine: 'internal:has-text', selector: escaped, score: kTextScore }]);
if (fullText.length <= 80)
candidates.push([cssToken, { engine: 'internal:has-text', selector: '/^' + escapeRegExp(fullText) + '$/', score: kTextScoreRegex }]);
@ -353,7 +353,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element, opt
if (!bestTokenForLevel)
bestTokenForLevel = token;
} else if (!bestTokenForLevel) {
bestTokenForLevel = nodeName;
bestTokenForLevel = cssEscape(nodeName);
}
tokens.unshift(bestTokenForLevel);
}

View File

@ -105,3 +105,17 @@ it('should escape class names', async ({ page }) => {
expect(error.message).toContain('<div class=\"foo bar:0');
expect(error.message).toContain('<div class=\"foo bar:1');
});
it('should escape tag names', async ({ page }) => {
await page.setContent(`
<q:template> </q:template>
<span>special test description</span>
<q:template hidden="" aria-hidden="true">
<span>special test description</span>
</q:template>
`);
const error = await expect(page.getByText('special test description')).toBeVisible().catch(e => e);
expect(error.message).toContain('strict mode violation');
expect(error.message).toContain(`getByText('special test description').first()`);
expect(error.message).toContain(`locator('q\\\\:template').filter({ hasText: 'special test description' })`);
});