fix(selectors): properly generate selectors for tricky ids (#5940)

This commit is contained in:
Joel Einbinder 2021-03-25 18:43:33 -07:00 коммит произвёл GitHub
Родитель 0120896771
Коммит 3ce02a95c8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 13 добавлений и 3 удалений

Просмотреть файл

@ -171,7 +171,8 @@ function buildCandidates(injectedScript: InjectedScript, element: Element): Sele
const idAttr = element.getAttribute('id');
if (idAttr && !isGuidLike(idAttr))
candidates.push({ engine: 'css', selector: `#${idAttr}`, score: 100 });
candidates.push({ engine: 'css', selector: makeSelectorForId(idAttr), score: 100 });
candidates.push({ engine: 'css', selector: element.nodeName.toLocaleLowerCase(), score: 200 });
return candidates;
@ -209,6 +210,10 @@ function parentElementOrShadowHost(element: Element): Element | null {
return null;
}
function makeSelectorForId(id: string) {
return /^[a-zA-Z][a-zA-Z0-9\-\_]+$/.test(id) ? '#' + id : `[id="${id}"]`;
}
function cssFallback(injectedScript: InjectedScript, targetElement: Element): SelectorToken {
const kFallbackScore = 10000000;
const root: Node = targetElement.ownerDocument;
@ -230,7 +235,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element): Se
// Element ID is the strongest signal, use it.
let bestTokenForLevel: string = '';
if (element.id) {
const token = /^[a-zA-Z][a-zA-Z0-9\-\_]+$/.test(element.id) ? '#' + element.id : `[id="${element.id}"]`;
const token = makeSelectorForId(element.id);
const selector = uniqueCSSSelector(token);
if (selector)
return { engine: 'css', selector, score: kFallbackScore };

Просмотреть файл

@ -260,7 +260,7 @@ describe('selector generator', (suite, { mode }) => {
const [frame] = await Promise.all([
page.waitForEvent('frameattached'),
page.evaluate(() => {
return new Promise(f => {
return new Promise<void>(f => {
const iframe = document.createElement('iframe');
iframe.onload = () => {
iframe.contentDocument.body.innerHTML = '<div>Target</div>';
@ -279,4 +279,9 @@ describe('selector generator', (suite, { mode }) => {
expect(await generate(page, '[name=bar]')).toBe(`${tagName}[name="bar"]`);
}
});
it('should work with tricky ids', async ({page}) => {
await page.setContent(`<button id="this:is-my-tricky.id"><span></span></button>`);
expect(await generate(page, 'button')).toBe('[id="this:is-my-tricky.id"]');
});
});