From 84daeafb3a850233504bf716b469c9bc636a87e6 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 19 Oct 2022 22:38:47 -0400 Subject: [PATCH] chore: use internal locator for role (#18187) --- packages/playwright-core/src/client/locator.ts | 2 +- .../playwright-core/src/server/injected/injectedScript.ts | 1 + .../src/server/injected/selectorGenerator.ts | 4 ++-- .../src/server/isomorphic/locatorGenerators.ts | 2 +- packages/playwright-core/src/server/selectors.ts | 2 +- tests/library/inspector/cli-codegen-1.spec.ts | 8 ++++---- tests/library/inspector/cli-codegen-2.spec.ts | 2 +- tests/library/inspector/cli-codegen-3.spec.ts | 4 ++-- tests/library/selector-generator.spec.ts | 8 ++++---- 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/playwright-core/src/client/locator.ts b/packages/playwright-core/src/client/locator.ts index a86c6157f2..a8a518cbf6 100644 --- a/packages/playwright-core/src/client/locator.ts +++ b/packages/playwright-core/src/client/locator.ts @@ -442,5 +442,5 @@ export function getByRoleSelector(role: string, options: ByRoleOptions = {}): st props.push(['name', isString(options.name) ? escapeForAttributeSelector(options.name, false) : String(options.name)]); if (options.pressed !== undefined) props.push(['pressed', String(options.pressed)]); - return `role=${role}${props.map(([n, v]) => `[${n}=${v}]`).join('')}`; + return `internal:role=${role}${props.map(([n, v]) => `[${n}=${v}]`).join('')}`; } diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index f689510f3f..7152e5ac2a 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -112,6 +112,7 @@ export class InjectedScript { this._engines.set('internal:label', this._createInternalLabelEngine()); this._engines.set('internal:text', this._createTextEngine(true, true)); this._engines.set('internal:attr', this._createNamedAttributeEngine()); + this._engines.set('internal:role', RoleEngine); for (const { name, engine } of customEngines) this._engines.set(name, engine); diff --git a/packages/playwright-core/src/server/injected/selectorGenerator.ts b/packages/playwright-core/src/server/injected/selectorGenerator.ts index 50e64ea3bd..3c65b2cd42 100644 --- a/packages/playwright-core/src/server/injected/selectorGenerator.ts +++ b/packages/playwright-core/src/server/injected/selectorGenerator.ts @@ -170,9 +170,9 @@ function buildCandidates(injectedScript: InjectedScript, element: Element, acces if (ariaRole) { const ariaName = getElementAccessibleName(element, false, accessibleNameCache); if (ariaName) - candidates.push({ engine: 'role', selector: `${ariaRole}[name=${escapeForAttributeSelector(ariaName, true)}]`, score: 3 }); + candidates.push({ engine: 'internal:role', selector: `${ariaRole}[name=${escapeForAttributeSelector(ariaName, true)}]`, score: 3 }); else - candidates.push({ engine: 'role', selector: ariaRole, score: 150 }); + candidates.push({ engine: 'internal:role', selector: ariaRole, score: 150 }); } if (element.getAttribute('alt') && ['APPLET', 'AREA', 'IMG', 'INPUT'].includes(element.nodeName)) diff --git a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts b/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts index 5f43bbc9cf..4fa3c86ecd 100644 --- a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts +++ b/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts @@ -55,7 +55,7 @@ function innerAsLocator(factory: LocatorFactory, selector: string, isFrameLocato tokens.push(factory.generateLocator(base, 'label', text, { exact })); continue; } - if (part.name === 'role') { + if (part.name === 'internal:role') { const attrSelector = parseAttributeSelector(part.body as string, true); const attrs: Record = {}; for (const attr of attrSelector.attributes!) diff --git a/packages/playwright-core/src/server/selectors.ts b/packages/playwright-core/src/server/selectors.ts index a05b88fd8f..88c5d5dd40 100644 --- a/packages/playwright-core/src/server/selectors.ts +++ b/packages/playwright-core/src/server/selectors.ts @@ -46,7 +46,7 @@ export class Selectors { 'data-test-id', 'data-test-id:light', 'data-test', 'data-test:light', 'nth', 'visible', 'internal:control', 'internal:has', - 'role', 'internal:attr', 'internal:label', 'internal:text' + 'role', 'internal:attr', 'internal:label', 'internal:text', 'internal:role', ]); this._builtinEnginesInMainWorld = new Set([ '_react', '_vue', diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts index d9deefd4fa..8b63d7817e 100644 --- a/tests/library/inspector/cli-codegen-1.spec.ts +++ b/tests/library/inspector/cli-codegen-1.spec.ts @@ -26,7 +26,7 @@ test.describe('cli codegen', () => { await recorder.setContentAndWait(``); const selector = await recorder.hoverOverElement('button'); - expect(selector).toBe('role=button[name=\"Submit\"]'); + expect(selector).toBe('internal:role=button[name=\"Submit\"]'); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), @@ -69,7 +69,7 @@ test.describe('cli codegen', () => { await page.waitForTimeout(1000); const selector = await recorder.hoverOverElement('button'); - expect(selector).toBe('role=button[name=\"Submit\"]'); + expect(selector).toBe('internal:role=button[name=\"Submit\"]'); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), @@ -149,7 +149,7 @@ test.describe('cli codegen', () => { `); const selector = await recorder.hoverOverElement('button'); - expect(selector).toBe('role=button[name=\"Submit\"]'); + expect(selector).toBe('internal:role=button[name=\"Submit\"]'); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), @@ -540,7 +540,7 @@ test.describe('cli codegen', () => { await recorder.setContentAndWait('link'); const selector = await recorder.hoverOverElement('a'); - expect(selector).toBe('role=link[name=\"link\"]'); + expect(selector).toBe('internal:role=link[name=\"link\"]'); const [popup, sources] = await Promise.all([ page.context().waitForEvent('page'), diff --git a/tests/library/inspector/cli-codegen-2.spec.ts b/tests/library/inspector/cli-codegen-2.spec.ts index c22b32bc8e..9b62a12468 100644 --- a/tests/library/inspector/cli-codegen-2.spec.ts +++ b/tests/library/inspector/cli-codegen-2.spec.ts @@ -333,7 +333,7 @@ test.describe('cli codegen', () => { await recorder.setContentAndWait(`link`); const selector = await recorder.hoverOverElement('a'); - expect(selector).toBe('role=link[name=\"link\"]'); + expect(selector).toBe('internal:role=link[name=\"link\"]'); await page.click('a', { modifiers: [platform === 'darwin' ? 'Meta' : 'Control'] }); const sources = await recorder.waitForOutput('JavaScript', 'page1'); diff --git a/tests/library/inspector/cli-codegen-3.spec.ts b/tests/library/inspector/cli-codegen-3.spec.ts index c2ae7c467b..e04720f508 100644 --- a/tests/library/inspector/cli-codegen-3.spec.ts +++ b/tests/library/inspector/cli-codegen-3.spec.ts @@ -28,7 +28,7 @@ test.describe('cli codegen', () => { `); const selector = await recorder.hoverOverElement('button'); - expect(selector).toBe('role=button[name=\"Submit\"] >> nth=0'); + expect(selector).toBe('internal:role=button[name=\"Submit\"] >> nth=0'); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), @@ -63,7 +63,7 @@ test.describe('cli codegen', () => { `); const selector = await recorder.hoverOverElement('button >> nth=1'); - expect(selector).toBe('role=button[name=\"Submit\"] >> nth=1'); + expect(selector).toBe('internal:role=button[name=\"Submit\"] >> nth=1'); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), diff --git a/tests/library/selector-generator.spec.ts b/tests/library/selector-generator.spec.ts index e243d793ca..57f0c0222d 100644 --- a/tests/library/selector-generator.spec.ts +++ b/tests/library/selector-generator.spec.ts @@ -35,7 +35,7 @@ it.describe('selector generator', () => { it('should prefer role=button over inner span', async ({ page }) => { await page.setContent(`
`); - expect(await generate(page, 'div')).toBe('role=button'); + expect(await generate(page, 'div')).toBe('internal:role=button'); }); it('should generate text and normalize whitespace', async ({ page }) => { @@ -50,7 +50,7 @@ it.describe('selector generator', () => { it('should generate text for ', async ({ page }) => { await page.setContent(``); - expect(await generate(page, 'input')).toBe('role=button[name=\"Click me\"]'); + expect(await generate(page, 'input')).toBe('internal:role=button[name=\"Click me\"]'); }); it('should trim text', async ({ page }) => { @@ -319,7 +319,7 @@ it.describe('selector generator', () => { await page.setContent(``); await page.$eval('button', button => button.setAttribute('aria-label', `!#'!?:`)); - expect(await generate(page, 'button')).toBe(`role=button[name="!#'!?:"]`); + expect(await generate(page, 'button')).toBe(`internal:role=button[name="!#'!?:"]`); expect(await page.$(`role=button[name="!#'!?:"]`)).toBeTruthy(); await page.setContent(`
`); @@ -343,7 +343,7 @@ it.describe('selector generator', () => { it('should accept valid aria-label for candidate consideration', async ({ page }) => { await page.setContent(``); - expect(await generate(page, 'button')).toBe('role=button[name=\"ariaLabel\"]'); + expect(await generate(page, 'button')).toBe('internal:role=button[name=\"ariaLabel\"]'); }); it('should ignore empty role for candidate consideration', async ({ page }) => {