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"
`);
});