fix(junit): produce a single system-out entry (#9091)

Instead of multiple `system-out` entries we produce a single one
with concatenated content. This is compatible with various junit xml
parsers in the wild.
This commit is contained in:
Dmitry Gozman 2021-09-22 15:28:57 -07:00 committed by GitHub
parent f0d23b5d4d
commit 568ec05a97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 24 deletions

View File

@ -145,30 +145,28 @@ class JUnitReporter implements Reporter {
text: stripAnsiEscapes(formatFailure(this.config, test)) text: stripAnsiEscapes(formatFailure(this.config, test))
}); });
} }
for (const result of test.results) {
for (const stdout of result.stdout) {
entry.children.push({
name: 'system-out',
text: stdout.toString()
});
}
const systemOut: string[] = [];
const systemErr: string[] = [];
for (const result of test.results) {
systemOut.push(...result.stdout.map(item => item.toString()));
systemErr.push(...result.stderr.map(item => item.toString()));
for (const attachment of result.attachments) { for (const attachment of result.attachments) {
if (attachment.path) { if (!attachment.path)
entry.children.push({ continue;
name: 'system-out', try {
text: `[[ATTACHMENT|${path.relative(this.config.rootDir, attachment.path)}]]` if (fs.existsSync(attachment.path))
}); systemOut.push(`\n[[ATTACHMENT|${path.relative(this.config.rootDir, attachment.path)}]]\n`);
} catch (e) {
} }
} }
for (const stderr of result.stderr) {
entry.children.push({
name: 'system-err',
text: stderr.toString()
});
}
} }
// Note: it is important to only produce a single system-out/system-err entry
// so that parsers in the wild understand it.
if (systemOut.length)
entry.children.push({ name: 'system-out', text: systemOut.join('') });
if (systemErr.length)
entry.children.push({ name: 'system-err', text: systemErr.join('') });
} }
} }

View File

@ -103,6 +103,8 @@ test('should render stdout', async ({ runInlineTest }) => {
const { test } = pwt; const { test } = pwt;
test('one', async ({}) => { test('one', async ({}) => {
console.log(colors.yellow('Hello world')); console.log(colors.yellow('Hello world'));
console.log('Hello again');
console.error('My error');
test.expect("abc").toBe('abcd'); test.expect("abc").toBe('abcd');
}); });
`, `,
@ -110,9 +112,10 @@ test('should render stdout', async ({ runInlineTest }) => {
const xml = parseXML(result.output); const xml = parseXML(result.output);
const testcase = xml['testsuites']['testsuite'][0]['testcase'][0]; const testcase = xml['testsuites']['testsuite'][0]['testcase'][0];
expect(testcase['system-out'].length).toBe(1); expect(testcase['system-out'].length).toBe(1);
expect(testcase['system-out'][0]).toContain('Hello world'); expect(testcase['system-out'][0]).toContain('[33mHello world[39m\nHello again');
expect(testcase['system-out'][0]).not.toContain('u00'); expect(testcase['system-out'][0]).not.toContain('u00');
expect(testcase['failure'][0]['_']).toContain(`> 9 | test.expect("abc").toBe('abcd');`); expect(testcase['system-err'][0]).toContain('My error');
expect(testcase['failure'][0]['_']).toContain(`> 11 | test.expect("abc").toBe('abcd');`);
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
@ -221,20 +224,29 @@ test('should render projects', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
}); });
test('should render attachments', async ({ runInlineTest }) => { test('should render existing attachments, but not missing ones', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test } = pwt;
test.use({ screenshot: 'on' }); test.use({ screenshot: 'on' });
test('one', async ({ page }) => { test('one', async ({ page }, testInfo) => {
await page.setContent('hello'); await page.setContent('hello');
const file = testInfo.outputPath('file.txt');
require('fs').writeFileSync(file, 'my file', 'utf8');
testInfo.attachments.push({ name: 'my-file', path: file, contentType: 'text/plain' });
testInfo.attachments.push({ name: 'my-file-missing', path: file + '-missing', contentType: 'text/plain' });
console.log('log here');
}); });
`, `,
}, { reporter: 'junit' }); }, { reporter: 'junit' });
const xml = parseXML(result.output); const xml = parseXML(result.output);
const testcase = xml['testsuites']['testsuite'][0]['testcase'][0]; const testcase = xml['testsuites']['testsuite'][0]['testcase'][0];
expect(testcase['system-out'].length).toBe(1); expect(testcase['system-out'].length).toBe(1);
expect(testcase['system-out'][0].trim()).toBe(`[[ATTACHMENT|test-results${path.sep}a-one${path.sep}test-finished-1.png]]`); expect(testcase['system-out'][0].trim()).toBe([
`log here`,
`\n[[ATTACHMENT|test-results${path.sep}a-one${path.sep}file.txt]]`,
`\n[[ATTACHMENT|test-results${path.sep}a-one${path.sep}test-finished-1.png]]`,
].join('\n'));
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
}); });