fix(selectors): properly generate selectors for tricky ids (#5940)
This commit is contained in:
Родитель
0120896771
Коммит
3ce02a95c8
|
@ -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"]');
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче