fix(selectors): properly generate selectors for tricky ids (#5940)
This commit is contained in:
parent
0120896771
commit
3ce02a95c8
|
|
@ -171,7 +171,8 @@ function buildCandidates(injectedScript: InjectedScript, element: Element): Sele
|
||||||
|
|
||||||
const idAttr = element.getAttribute('id');
|
const idAttr = element.getAttribute('id');
|
||||||
if (idAttr && !isGuidLike(idAttr))
|
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 });
|
candidates.push({ engine: 'css', selector: element.nodeName.toLocaleLowerCase(), score: 200 });
|
||||||
return candidates;
|
return candidates;
|
||||||
|
|
@ -209,6 +210,10 @@ function parentElementOrShadowHost(element: Element): Element | null {
|
||||||
return 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 {
|
function cssFallback(injectedScript: InjectedScript, targetElement: Element): SelectorToken {
|
||||||
const kFallbackScore = 10000000;
|
const kFallbackScore = 10000000;
|
||||||
const root: Node = targetElement.ownerDocument;
|
const root: Node = targetElement.ownerDocument;
|
||||||
|
|
@ -230,7 +235,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element): Se
|
||||||
// Element ID is the strongest signal, use it.
|
// Element ID is the strongest signal, use it.
|
||||||
let bestTokenForLevel: string = '';
|
let bestTokenForLevel: string = '';
|
||||||
if (element.id) {
|
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);
|
const selector = uniqueCSSSelector(token);
|
||||||
if (selector)
|
if (selector)
|
||||||
return { engine: 'css', selector, score: kFallbackScore };
|
return { engine: 'css', selector, score: kFallbackScore };
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ describe('selector generator', (suite, { mode }) => {
|
||||||
const [frame] = await Promise.all([
|
const [frame] = await Promise.all([
|
||||||
page.waitForEvent('frameattached'),
|
page.waitForEvent('frameattached'),
|
||||||
page.evaluate(() => {
|
page.evaluate(() => {
|
||||||
return new Promise(f => {
|
return new Promise<void>(f => {
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
iframe.onload = () => {
|
iframe.onload = () => {
|
||||||
iframe.contentDocument.body.innerHTML = '<div>Target</div>';
|
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"]`);
|
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"]');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue