From d193bd64c42b3d18aa9b89c9b40f43c47e47c362 Mon Sep 17 00:00:00 2001 From: Sergio Freire Date: Fri, 10 Jun 2022 09:25:52 +0100 Subject: [PATCH] feat(junit reporter): add option to force usage of CDATA sections for content in XML elements (#12744) Co-authored-by: Sergio Freire --- .../playwright-test/src/reporters/junit.ts | 12 ++++++---- tests/playwright-test/reporter-junit.spec.ts | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/playwright-test/src/reporters/junit.ts b/packages/playwright-test/src/reporters/junit.ts index c1b9afabab..f8b5d39ce5 100644 --- a/packages/playwright-test/src/reporters/junit.ts +++ b/packages/playwright-test/src/reporters/junit.ts @@ -201,10 +201,14 @@ const discouragedXMLCharacters = /[\u0001-\u0008\u000b-\u000c\u000e-\u001f\u007f function escape(text: string, stripANSIControlSequences: boolean, isCharacterData: boolean): string { if (stripANSIControlSequences) text = stripAnsiEscapes(text); - const escapeRe = isCharacterData ? /[&<]/g : /[&"<>]/g; - text = text.replace(escapeRe, c => ({ '&': '&', '"': '"', '<': '<', '>': '>' }[c]!)); - if (isCharacterData) - text = text.replace(/]]>/g, ']]>'); + + if (isCharacterData) { + text = '/g, ']]>') + ']]>'; + } else { + const escapeRe = /[&"'<>]/g; + text = text.replace(escapeRe, c => ({ '&': '&', '"': '"', "'": ''', '<': '<', '>': '>' }[c]!)); + } + text = text.replace(discouragedXMLCharacters, ''); return text; } diff --git a/tests/playwright-test/reporter-junit.spec.ts b/tests/playwright-test/reporter-junit.spec.ts index 05b443f79a..cdc25142d1 100644 --- a/tests/playwright-test/reporter-junit.spec.ts +++ b/tests/playwright-test/reporter-junit.spec.ts @@ -141,6 +141,28 @@ test('should render stdout without ansi escapes', async ({ runInlineTest }) => { expect(result.exitCode).toBe(0); }); +test('should render, by default, character data as CDATA sections', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'playwright.config.ts': ` + module.exports = { + reporter: [ ['junit'] ], + }; + `, + 'a.test.ts': ` + const { test } = pwt; + test('one', async ({}) => { + process.stdout.write('Hello world &"\\'<>]]>'); + }); + `, + }, { reporter: '' }); + const xml = parseXML(result.output); + const testcase = xml['testsuites']['testsuite'][0]['testcase'][0]; + expect(testcase['system-out'].length).toBe(1); + expect(testcase['system-out'][0].trim()).toBe('Hello world &"\'<>]]>'); + expect(result.output).toContain(`\n]]>]]>\n`); + expect(result.exitCode).toBe(0); +}); + test('should render skipped', async ({ runInlineTest }) => { const result = await runInlineTest({ 'a.test.js': `