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': `