diff --git a/packages/playwright-core/src/server/injected/yaml.ts b/packages/playwright-core/src/server/injected/yaml.ts index e87c6706dea79..7daebc574a5cf 100644 --- a/packages/playwright-core/src/server/injected/yaml.ts +++ b/packages/playwright-core/src/server/injected/yaml.ts @@ -62,12 +62,8 @@ function yamlStringNeedsQuotes(str: string): boolean { if (/^-\s/.test(str)) return true; - // Strings that start with a special indicator character need quotes - if (/^[&*\],].*/.test(str)) - return true; - - // Strings containing ':' followed by a space or at the end need quotes - if (/:(\s|$)/.test(str)) + // Strings containing ':' or '\n' followed by a space or at the end need quotes + if (/[\n:](\s|$)/.test(str)) return true; // Strings containing '#' preceded by a space need quotes (comment indicator) @@ -78,21 +74,17 @@ function yamlStringNeedsQuotes(str: string): boolean { if (/[\n\r]/.test(str)) return true; - // Strings starting with '?' or '!' (directives) need quotes - if (/^[?!]/.test(str)) - return true; - - // Strings starting with '>' or '|' (block scalar indicators) need quotes - if (/^[>|]/.test(str)) - return true; - - // Strings starting with quotes need quotes - if (/^["']/.test(str)) + // Strings starting with indicator characters or quotes need quotes + if (/^[&*\],?!>|@"'#%]/.test(str)) return true; // Strings containing special characters that could cause ambiguity if (/[{}`]/.test(str)) return true; + // Non-string types recognized by YAML + if (!isNaN(Number(str)) || ['y', 'n', 'yes', 'no', 'true', 'false', 'on', 'off', 'null'].includes(str.toLowerCase())) + return true; + return false; } diff --git a/tests/page/page-aria-snapshot.spec.ts b/tests/page/page-aria-snapshot.spec.ts index 6b37438419b7a..2289e59d74113 100644 --- a/tests/page/page-aria-snapshot.spec.ts +++ b/tests/page/page-aria-snapshot.spec.ts @@ -509,3 +509,57 @@ it('should handle long strings', async ({ page }) => { - region: ${s} `); }); + +it('should escape special yaml characters', async ({ page }) => { + await page.setContent(` + @hello@hello + ]hello]hello + hello\n + hello\n\n hello\n hello + #hello#hello + `); + + await checkAndMatchSnapshot(page.locator('body'), ` + - link "@hello" + - text: "@hello" + - link "]hello" + - text: "]hello" + - link "hello" + - text: hello + - link "hello" + - text: hello + - link "#hello" + - text: "#hello" + `); +}); + +it('should escape special yaml values', async ({ page }) => { + await page.setContent(` + trueFalse + NOyes + yN + onOff + nullNULL + 123123 + -1.2-1.2 + + `); + + await checkAndMatchSnapshot(page.locator('body'), ` + - link "true" + - text: "False" + - link "NO" + - text: "yes" + - link "y" + - text: "N" + - link "on" + - text: "Off" + - link "null" + - text: "NULL" + - link "123" + - text: "123" + - link "-1.2" + - text: "-1.2" + - textbox: "555" + `); +});