diff --git a/packages/playwright-core/src/server/injected/roleSelectorEngine.ts b/packages/playwright-core/src/server/injected/roleSelectorEngine.ts
index b647f81b8e..293c10aa5f 100644
--- a/packages/playwright-core/src/server/injected/roleSelectorEngine.ts
+++ b/packages/playwright-core/src/server/injected/roleSelectorEngine.ts
@@ -147,8 +147,7 @@ function queryRole(scope: SelectorRoot, options: RoleEngineOptions, internal: bo
return;
}
if (options.name !== undefined) {
- // Always normalize whitespace in the accessible name.
- const accessibleName = normalizeWhiteSpace(getElementAccessibleName(element, !!options.includeHidden));
+ const accessibleName = getElementAccessibleName(element, !!options.includeHidden);
if (typeof options.name === 'string')
options.name = normalizeWhiteSpace(options.name);
// internal:role assumes that [name="foo"i] also means substring.
diff --git a/packages/playwright-core/src/server/injected/roleUtils.ts b/packages/playwright-core/src/server/injected/roleUtils.ts
index 50564fa31f..16743fd607 100644
--- a/packages/playwright-core/src/server/injected/roleUtils.ts
+++ b/packages/playwright-core/src/server/injected/roleUtils.ts
@@ -16,6 +16,7 @@
import type { AriaRole } from '@isomorphic/ariaSnapshot';
import { closestCrossShadow, elementSafeTagName, enclosingShadowRootOrDocument, getElementComputedStyle, isElementStyleVisibilityVisible, isVisibleTextNode, parentElementOrShadowHost } from './domUtils';
+import { normalizeWhiteSpace } from '../../utils/isomorphic/stringUtils';
function hasExplicitAccessibleName(e: Element) {
return e.hasAttribute('aria-label') || e.hasAttribute('aria-labelledby');
@@ -420,6 +421,8 @@ export function getElementAccessibleName(element: Element, includeHidden: boolea
}));
}
+ // Note: we always normalize whitespace in the accessible name to make it easier to work with.
+ accessibleName = normalizeWhiteSpace(accessibleName);
cache?.set(element, accessibleName);
}
return accessibleName;
@@ -452,6 +455,8 @@ export function getElementAccessibleDescription(element: Element, includeHidden:
accessibleDescription = asFlatString(element.getAttribute('title') || '');
}
+ // Note: we always normalize whitespace in the accessible description to make it easier to work with.
+ accessibleDescription = normalizeWhiteSpace(accessibleDescription);
cache?.set(element, accessibleDescription);
}
return accessibleDescription;
diff --git a/tests/library/role-utils.spec.ts b/tests/library/role-utils.spec.ts
index a02680ce86..a94cf67c2f 100644
--- a/tests/library/role-utils.spec.ts
+++ b/tests/library/role-utils.spec.ts
@@ -475,24 +475,9 @@ test('should ignore stylesheet from hidden aria-labelledby subtree', async ({ pa
expect.soft(await getNameAndRole(page, 'input')).toEqual({ role: 'textbox', name: 'hello' });
});
-test('should not include hidden pseudo into accessible name', async ({ page }) => {
- await page.setContent(`
-
-
- hello
-