Skip to content

Commit

Permalink
fix(aria snapshots): normalize whitespace (#34285)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgozman authored Jan 10, 2025
1 parent 4f3a5e2 commit 1f2eb49
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
8 changes: 3 additions & 5 deletions packages/playwright-core/src/server/injected/ariaSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import * as roleUtils from './roleUtils';
import { getElementComputedStyle } from './domUtils';
import { escapeRegExp, longestCommonSubstring } from '@isomorphic/stringUtils';
import { escapeRegExp, longestCommonSubstring, normalizeWhiteSpace } from '@isomorphic/stringUtils';
import { yamlEscapeKeyIfNeeded, yamlEscapeValueIfNeeded } from './yaml';
import type { AriaProps, AriaRole, AriaTemplateNode, AriaTemplateRoleNode, AriaTemplateTextNode } from '@isomorphic/ariaSnapshot';

Expand Down Expand Up @@ -137,7 +137,7 @@ function toAriaNode(element: Element): AriaNode | null {
if (!role || role === 'presentation' || role === 'none')
return null;

const name = roleUtils.getElementAccessibleName(element, false) || '';
const name = normalizeWhiteSpace(roleUtils.getElementAccessibleName(element, false) || '');
const result: AriaNode = { role, name, children: [], element };

if (roleUtils.kAriaCheckedRoles.includes(role))
Expand Down Expand Up @@ -170,7 +170,7 @@ function normalizeStringChildren(rootA11yNode: AriaNode) {
const flushChildren = (buffer: string[], normalizedChildren: (AriaNode | string)[]) => {
if (!buffer.length)
return;
const text = normalizeWhitespaceWithin(buffer.join('')).trim();
const text = normalizeWhiteSpace(buffer.join(''));
if (text)
normalizedChildren.push(text);
buffer.length = 0;
Expand All @@ -196,8 +196,6 @@ function normalizeStringChildren(rootA11yNode: AriaNode) {
visit(rootA11yNode);
}

const normalizeWhitespaceWithin = (text: string) => text.replace(/[\u200b\s\t\r\n]+/g, ' ');

function matchesText(text: string, template: RegExp | string | undefined): boolean {
if (!template)
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class KeyParser {
const ch = this._peek();
if (ch === '"') {
this._next();
return this._readString();
return normalizeWhitespace(this._readString());
}

if (ch === '/') {
Expand Down
26 changes: 26 additions & 0 deletions tests/page/page-aria-snapshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,32 @@ it('should escape yaml text in text nodes', async ({ page }) => {
`);
});

it('should normalize whitespace', async ({ page }) => {
await page.setContent(`
<details>
<summary> one \n two <a href="#"> link &nbsp;\n 1 </a> </summary>
</details>
<input value=' hello &nbsp; world '>
`);

await checkAndMatchSnapshot(page.locator('body'), `
- group:
- text: one two
- link "link 1"
- textbox: hello world
`);

// Weird whitespace in the template should be normalized.
await expect(page.locator('body')).toMatchAriaSnapshot(`
- group:
- text: |
one
two
- link " link 1 "
- textbox: hello world
`);
});

it('should handle long strings', async ({ page }) => {
const s = 'a'.repeat(10000);
await page.setContent(`
Expand Down

0 comments on commit 1f2eb49

Please sign in to comment.