mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-28 17:44:33 +03:00
chore: fix more aria escaping edge cases (#33460)
This commit is contained in:
parent
9d94ad152e
commit
d4ad520a9b
@ -168,7 +168,6 @@ export class KeyParser {
|
|||||||
escaped = false;
|
escaped = false;
|
||||||
} else if (ch === '\\') {
|
} else if (ch === '\\') {
|
||||||
escaped = true;
|
escaped = true;
|
||||||
result += ch;
|
|
||||||
} else if (ch === '"') {
|
} else if (ch === '"') {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,7 @@ import * as roleUtils from './roleUtils';
|
|||||||
import { getElementComputedStyle } from './domUtils';
|
import { getElementComputedStyle } from './domUtils';
|
||||||
import type { AriaRole } from './roleUtils';
|
import type { AriaRole } from './roleUtils';
|
||||||
import { escapeRegExp, longestCommonSubstring } from '@isomorphic/stringUtils';
|
import { escapeRegExp, longestCommonSubstring } from '@isomorphic/stringUtils';
|
||||||
import { yamlEscapeKeyIfNeeded, yamlEscapeValueIfNeeded, yamlQuoteFragment } from './yaml';
|
import { yamlEscapeKeyIfNeeded, yamlEscapeValueIfNeeded } from './yaml';
|
||||||
|
|
||||||
type AriaProps = {
|
type AriaProps = {
|
||||||
checked?: boolean | 'mixed';
|
checked?: boolean | 'mixed';
|
||||||
@ -318,8 +318,10 @@ export function renderAriaTree(ariaNode: AriaNode, options?: { mode?: 'raw' | 'r
|
|||||||
let key = ariaNode.role;
|
let key = ariaNode.role;
|
||||||
if (ariaNode.name) {
|
if (ariaNode.name) {
|
||||||
const name = renderString(ariaNode.name);
|
const name = renderString(ariaNode.name);
|
||||||
if (name)
|
if (name) {
|
||||||
key += ' ' + (name.startsWith('/') && name.endsWith('/') ? name : yamlQuoteFragment(name));
|
const stringifiedName = name.startsWith('/') && name.endsWith('/') ? name : JSON.stringify(name);
|
||||||
|
key += ' ' + stringifiedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ariaNode.checked === 'mixed')
|
if (ariaNode.checked === 'mixed')
|
||||||
key += ` [checked=mixed]`;
|
key += ` [checked=mixed]`;
|
||||||
|
@ -46,19 +46,6 @@ export function yamlEscapeValueIfNeeded(str: string): string {
|
|||||||
}) + '"';
|
}) + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function yamlQuoteFragment(str: string, quote = '"'): string {
|
|
||||||
return quote + str.replace(/['"]/g, c => {
|
|
||||||
switch (c) {
|
|
||||||
case '"':
|
|
||||||
return quote === '"' ? '\\"' : '"';
|
|
||||||
case '\'':
|
|
||||||
return quote === '\'' ? '\\\'' : '\'';
|
|
||||||
default:
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}) + quote;
|
|
||||||
}
|
|
||||||
|
|
||||||
function yamlStringNeedsQuotes(str: string): boolean {
|
function yamlStringNeedsQuotes(str: string): boolean {
|
||||||
if (str.length === 0)
|
if (str.length === 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -85,19 +85,18 @@ export async function toMatchAriaSnapshot(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const escapedExpected = escapePrivateUsePoints(expected);
|
const receivedText = typedReceived.raw;
|
||||||
const escapedReceived = escapePrivateUsePoints(typedReceived.raw);
|
|
||||||
const message = () => {
|
const message = () => {
|
||||||
if (pass) {
|
if (pass) {
|
||||||
if (notFound)
|
if (notFound)
|
||||||
return messagePrefix + `Expected: not ${this.utils.printExpected(escapedExpected)}\nReceived: ${escapedReceived}` + callLogText(log);
|
return messagePrefix + `Expected: not ${this.utils.printExpected(expected)}\nReceived: ${receivedText}` + callLogText(log);
|
||||||
const printedReceived = printReceivedStringContainExpectedSubstring(escapedReceived, escapedReceived.indexOf(escapedExpected), escapedExpected.length);
|
const printedReceived = printReceivedStringContainExpectedSubstring(receivedText, receivedText.indexOf(expected), expected.length);
|
||||||
return messagePrefix + `Expected: not ${this.utils.printExpected(escapedExpected)}\nReceived: ${printedReceived}` + callLogText(log);
|
return messagePrefix + `Expected: not ${this.utils.printExpected(expected)}\nReceived: ${printedReceived}` + callLogText(log);
|
||||||
} else {
|
} else {
|
||||||
const labelExpected = `Expected`;
|
const labelExpected = `Expected`;
|
||||||
if (notFound)
|
if (notFound)
|
||||||
return messagePrefix + `${labelExpected}: ${this.utils.printExpected(escapedExpected)}\nReceived: ${escapedReceived}` + callLogText(log);
|
return messagePrefix + `${labelExpected}: ${this.utils.printExpected(expected)}\nReceived: ${receivedText}` + callLogText(log);
|
||||||
return messagePrefix + this.utils.printDiffOrStringify(escapedExpected, escapedReceived, labelExpected, 'Received', false) + callLogText(log);
|
return messagePrefix + this.utils.printDiffOrStringify(expected, receivedText, labelExpected, 'Received', false) + callLogText(log);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,10 +117,6 @@ export async function toMatchAriaSnapshot(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapePrivateUsePoints(str: string) {
|
|
||||||
return escapeTemplateString(str).replace(/[\uE000-\uF8FF]/g, char => `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function unshift(snapshot: string): string {
|
function unshift(snapshot: string): string {
|
||||||
const lines = snapshot.split('\n');
|
const lines = snapshot.split('\n');
|
||||||
let whitespacePrefixLength = 100;
|
let whitespacePrefixLength = 100;
|
||||||
|
@ -436,10 +436,16 @@ test('should unpack escaped names', async ({ page }) => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<button>Click \\ me</button>
|
<button>Click " me</button>
|
||||||
`);
|
`);
|
||||||
await expect(page.locator('body')).toMatchAriaSnapshot(`
|
await expect(page.locator('body')).toMatchAriaSnapshot(`
|
||||||
- button "Click \\ me"
|
- button "Click \\\" me"
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
await page.setContent(`
|
||||||
|
<button>Click \\ me</button>
|
||||||
`);
|
`);
|
||||||
await expect(page.locator('body')).toMatchAriaSnapshot(`
|
await expect(page.locator('body')).toMatchAriaSnapshot(`
|
||||||
- button /Click \\\\ me/
|
- button /Click \\\\ me/
|
||||||
|
@ -166,6 +166,8 @@ test('should generate baseline with special characters', async ({ runInlineTest
|
|||||||
<button>Click: 123</button>
|
<button>Click: 123</button>
|
||||||
<button>Click ' me</button>
|
<button>Click ' me</button>
|
||||||
<button>Click: ' me</button>
|
<button>Click: ' me</button>
|
||||||
|
<button>Click " me</button>
|
||||||
|
<button>Click \\\\ me</button>
|
||||||
<li>Item: 1</li>
|
<li>Item: 1</li>
|
||||||
<li>Item {a: b}</li>
|
<li>Item {a: b}</li>
|
||||||
</ul>\`);
|
</ul>\`);
|
||||||
@ -179,7 +181,7 @@ test('should generate baseline with special characters', async ({ runInlineTest
|
|||||||
const data = fs.readFileSync(patchPath, 'utf-8');
|
const data = fs.readFileSync(patchPath, 'utf-8');
|
||||||
expect(data).toBe(`--- a/a.spec.ts
|
expect(data).toBe(`--- a/a.spec.ts
|
||||||
+++ b/a.spec.ts
|
+++ b/a.spec.ts
|
||||||
@@ -9,6 +9,14 @@
|
@@ -11,6 +11,16 @@
|
||||||
<li>Item: 1</li>
|
<li>Item: 1</li>
|
||||||
<li>Item {a: b}</li>
|
<li>Item {a: b}</li>
|
||||||
</ul>\`);
|
</ul>\`);
|
||||||
@ -190,6 +192,8 @@ test('should generate baseline with special characters', async ({ runInlineTest
|
|||||||
+ - 'button /Click: \\\\d+/'
|
+ - 'button /Click: \\\\d+/'
|
||||||
+ - button "Click ' me"
|
+ - button "Click ' me"
|
||||||
+ - 'button "Click: '' me"'
|
+ - 'button "Click: '' me"'
|
||||||
|
+ - button "Click \\\\" me"
|
||||||
|
+ - button "Click \\\\\\\\ me"
|
||||||
+ - listitem: \"Item: 1\"
|
+ - listitem: \"Item: 1\"
|
||||||
+ - listitem: \"Item {a: b}\"
|
+ - listitem: \"Item {a: b}\"
|
||||||
+ \`);
|
+ \`);
|
||||||
|
Loading…
Reference in New Issue
Block a user