feat(junit): includeProjectInTestName option (#30233)

Fixes #30246.
This commit is contained in:
Dmitry Gozman 2024-04-04 11:04:51 -07:00 committed by GitHub
parent 88f2717e87
commit d5907f4b13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 6 deletions

View File

@ -33,11 +33,13 @@ class JUnitReporter extends EmptyReporter {
private outputFile: string | undefined;
private resolvedOutputFile: string | undefined;
private stripANSIControlSequences = false;
private includeProjectInTestName = false;
constructor(options: { outputFile?: string, stripANSIControlSequences?: boolean } = {}) {
constructor(options: { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean } = {}) {
super();
this.outputFile = options.outputFile || reportOutputNameFromEnv();
this.stripANSIControlSequences = options.stripANSIControlSequences || false;
this.includeProjectInTestName = options.includeProjectInTestName || false;
}
override printsToStdio() {
@ -98,6 +100,7 @@ class JUnitReporter extends EmptyReporter {
let failures = 0;
let duration = 0;
const children: XMLEntry[] = [];
const testCaseNamePrefix = projectName && this.includeProjectInTestName ? `[${projectName}] ` : '';
for (const test of suite.allTests()){
++tests;
@ -107,7 +110,7 @@ class JUnitReporter extends EmptyReporter {
++failures;
for (const result of test.results)
duration += result.duration;
await this._addTestCase(suite.title, test, children);
await this._addTestCase(suite.title, testCaseNamePrefix, test, children);
}
this.totalTests += tests;
@ -132,12 +135,12 @@ class JUnitReporter extends EmptyReporter {
return entry;
}
private async _addTestCase(suiteName: string, test: TestCase, entries: XMLEntry[]) {
private async _addTestCase(suiteName: string, namePrefix: string, test: TestCase, entries: XMLEntry[]) {
const entry = {
name: 'testcase',
attributes: {
// Skip root, project, file
name: test.titlePath().slice(3).join(' '),
name: namePrefix + test.titlePath().slice(3).join(' '),
// filename
classname: suiteName,
time: (test.results.reduce((acc, value) => acc + value.duration, 0)) / 1000

View File

@ -24,7 +24,7 @@ export type ReporterDescription =
['line'] |
['list'] | ['list', { printSteps?: boolean }] |
['github'] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean }] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean }] |
['json'] | ['json', { outputFile?: string }] |
['html'] | ['html', { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string }] |
['null'] |

View File

@ -280,6 +280,33 @@ for (const useIntermediateMergeReport of [false, true] as const) {
expect(result.exitCode).toBe(0);
});
test('should includeProjectInTestName', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': `
module.exports = {
projects: [ { name: 'project1' }, { name: 'project2' } ],
reporter: [['junit', { includeProjectInTestName: true }]]
};
`,
'a.test.js': `
import { test, expect } from '@playwright/test';
test('one', async ({}) => {
expect(1).toBe(1);
});
`,
}, { reporter: '' });
expect(result.exitCode).toBe(0);
const xml = parseXML(result.output);
expect(xml['testsuites']['testsuite'][0]['$']['name']).toBe('a.test.js');
expect(xml['testsuites']['testsuite'][0]['$']['hostname']).toBe('project1');
expect(xml['testsuites']['testsuite'][0]['$']['tests']).toBe('1');
expect(xml['testsuites']['testsuite'][0]['testcase'][0]['$']['name']).toBe('[project1] one');
expect(xml['testsuites']['testsuite'][1]['$']['name']).toBe('a.test.js');
expect(xml['testsuites']['testsuite'][1]['$']['hostname']).toBe('project2');
expect(xml['testsuites']['testsuite'][1]['$']['tests']).toBe('1');
expect(xml['testsuites']['testsuite'][1]['testcase'][0]['$']['name']).toBe('[project2] one');
});
test('should render existing attachments, but not missing ones', async ({ runInlineTest }) => {
test.skip(useIntermediateMergeReport, 'Blob report hashes attachment paths');
const result = await runInlineTest({

View File

@ -23,7 +23,7 @@ export type ReporterDescription =
['line'] |
['list'] | ['list', { printSteps?: boolean }] |
['github'] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean }] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean }] |
['json'] | ['json', { outputFile?: string }] |
['html'] | ['html', { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string }] |
['null'] |