diff --git a/packages/playwright-core/src/server/injected/roleUtils.ts b/packages/playwright-core/src/server/injected/roleUtils.ts index d56075ea58..5b4e25940d 100644 --- a/packages/playwright-core/src/server/injected/roleUtils.ts +++ b/packages/playwright-core/src/server/injected/roleUtils.ts @@ -337,7 +337,7 @@ function trimFlatString(s: string): string { function asFlatString(s: string): string { // "Flat string" at https://w3c.github.io/accname/#terminology // Note that non-breaking spaces are preserved. - return s.split('\u00A0').map(chunk => chunk.replace(/\r\n/g, '\n').replace(/\s\s*/g, ' ')).join('\u00A0').trim(); + return s.split('\u00A0').map(chunk => chunk.replace(/\r\n/g, '\n').replace(/[\u200b\u00ad]/g, '').replace(/\s\s*/g, ' ')).join('\u00A0').trim(); } function queryInAriaOwned(element: Element, selector: string): Element[] { diff --git a/packages/playwright-core/src/utils/isomorphic/ariaSnapshot.ts b/packages/playwright-core/src/utils/isomorphic/ariaSnapshot.ts index 7ffe9b4de9..5fbc23ec44 100644 --- a/packages/playwright-core/src/utils/isomorphic/ariaSnapshot.ts +++ b/packages/playwright-core/src/utils/isomorphic/ariaSnapshot.ts @@ -220,7 +220,8 @@ export function parseAriaSnapshot(yaml: YamlLibrary, text: string, options: yaml const emptyFragment: AriaTemplateRoleNode = { kind: 'role', role: 'fragment' }; function normalizeWhitespace(text: string) { - return text.replace(/[\r\n\s\t]+/g, ' ').trim(); + // TODO: why is this different from normalizeWhitespace in stringUtils.ts? + return text.replace(/[\u200b\u00ad]/g, '').replace(/[\r\n\s\t]+/g, ' ').trim(); } export function valueOrRegex(value: string): string | AriaRegex { diff --git a/packages/playwright-core/src/utils/isomorphic/stringUtils.ts b/packages/playwright-core/src/utils/isomorphic/stringUtils.ts index ed81c9a033..5a7602c97a 100644 --- a/packages/playwright-core/src/utils/isomorphic/stringUtils.ts +++ b/packages/playwright-core/src/utils/isomorphic/stringUtils.ts @@ -83,7 +83,7 @@ export function cacheNormalizedWhitespaces() { export function normalizeWhiteSpace(text: string): string { let result = normalizedWhitespaceCache?.get(text); if (result === undefined) { - result = text.replace(/\u200b/g, '').trim().replace(/\s+/g, ' '); + result = text.replace(/[\u200b\u00ad]/g, '').trim().replace(/\s+/g, ' '); normalizedWhitespaceCache?.set(text, result); } return result; diff --git a/tests/library/role-utils.spec.ts b/tests/library/role-utils.spec.ts index 1b625a106a..777d32c58f 100644 --- a/tests/library/role-utils.spec.ts +++ b/tests/library/role-utils.spec.ts @@ -372,6 +372,13 @@ test('display:contents should be visible when contents are visible', async ({ pa await expect(page.getByRole('button')).toHaveCount(1); }); +test('should remove soft hyphens and zero-width spaces', async ({ page }) => { + await page.setContent(` + + `); + expect.soft(await getNameAndRole(page, 'button')).toEqual({ role: 'button', name: '123' }); +}); + test('label/labelled-by aria-hidden with descendants', async ({ page }) => { test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29796' }); diff --git a/tests/page/expect-to-have-text.spec.ts b/tests/page/expect-to-have-text.spec.ts index d10700e98b..45ab745579 100644 --- a/tests/page/expect-to-have-text.spec.ts +++ b/tests/page/expect-to-have-text.spec.ts @@ -71,6 +71,8 @@ test.describe('toHaveText with text', () => { await expect(locator).toHaveText('text CONTENT', { ignoreCase: true }); // Should support falsy ignoreCase. await expect(locator).not.toHaveText('TEXT', { ignoreCase: false }); + // Should normalize soft hyphens. + await expect(locator).toHaveText('T\u00ade\u00adxt content'); }); test('pass contain', async ({ page }) => { diff --git a/tests/page/page-aria-snapshot.spec.ts b/tests/page/page-aria-snapshot.spec.ts index 78bfb667d8..e5ba5a6c4b 100644 --- a/tests/page/page-aria-snapshot.spec.ts +++ b/tests/page/page-aria-snapshot.spec.ts @@ -515,6 +515,7 @@ it('should normalize whitespace', async ({ page }) => { one \n two link  \n 1 + `); await checkAndMatchSnapshot(page.locator('body'), ` @@ -522,6 +523,7 @@ it('should normalize whitespace', async ({ page }) => { - text: one two - link "link 1" - textbox: hello world + - button "helloworld" `); // Weird whitespace in the template should be normalized. @@ -532,6 +534,7 @@ it('should normalize whitespace', async ({ page }) => { two - link " link 1 " - textbox: hello world + - button "he\u00adlloworld\u200b" `); });