fix(locators): properly escape slash inside attributes (#20510)

Fixes #20471.
This commit is contained in:
Dmitry Gozman 2023-01-30 13:27:41 -08:00 committed by GitHub
parent a1c264c476
commit c27ad35299
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 1 deletions

View File

@ -78,5 +78,5 @@ export function escapeForAttributeSelector(value: string, exact: boolean): strin
// cssEscape(value).replace(/\\ /g, ' ')
// However, our attribute selectors do not conform to CSS parsing spec,
// so we escape them differently.
return `"${value.replace(/["]/g, '\\"')}"${exact ? 's' : 'i'}`;
return `"${value.replace(/\\/g, '\\\\').replace(/["]/g, '\\"')}"${exact ? 's' : 'i'}`;
}

View File

@ -192,6 +192,13 @@ world</label><input id=control />`);
await expect(page.getByPlaceholder('hello my\nworld')).toHaveAttribute('id', 'control');
await expect(page.getByAltText('hello my\nworld')).toHaveAttribute('id', 'control');
await expect(page.getByTitle('hello my\nworld')).toHaveAttribute('id', 'control');
await page.setContent(`<div id=target title="my title">Text here</div>`);
await expect.soft(page.getByTitle('my title', { exact: true })).toHaveCount(1, { timeout: 500 });
await expect.soft(page.getByTitle('my t\itle', { exact: true })).toHaveCount(1, { timeout: 500 });
await expect.soft(page.getByTitle('my t\\itle', { exact: true })).toHaveCount(0, { timeout: 500 });
await expect.soft(page.getByTitle('my t\\\itle', { exact: true })).toHaveCount(0, { timeout: 500 });
await expect.soft(page.getByTitle('my t\\\\itle', { exact: true })).toHaveCount(0, { timeout: 500 });
});
it('getByRole escaping', async ({ page }) => {
@ -225,4 +232,17 @@ it('getByRole escaping', async ({ page }) => {
expect.soft(await page.getByRole('link', { name: ' he \n llo 56 ', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
`<a href="https://playwright.dev">he llo 56</a>`,
]);
expect.soft(await page.getByRole('button', { name: 'Click me', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
`<button>Click me</button>`,
]);
expect.soft(await page.getByRole('button', { name: 'Click \me', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
`<button>Click me</button>`,
]);
expect.soft(await page.getByRole('button', { name: 'Click \\me', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
]);
expect.soft(await page.getByRole('button', { name: 'Click \\\me', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
]);
expect.soft(await page.getByRole('button', { name: 'Click \\\\me', exact: true }).evaluateAll(els => els.map(e => e.outerHTML))).toEqual([
]);
});