fix(merge): populate TestResult.stdout/stderr when merging (#23587)

This commit is contained in:
Yury Semikhatsky 2023-06-07 23:00:57 -07:00 committed by GitHub
parent 83cf6cc1e8
commit ded4a294f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 7 deletions

View File

@ -24,6 +24,8 @@ export type JsonLocation = Location;
export type JsonError = string;
export type JsonStackFrame = { file: string, line: number, column: number };
export type JsonStdIOType = 'stdout' | 'stderr';
export type JsonConfig = Pick<FullConfig, 'configFile' | 'globalTimeout' | 'maxFailures' | 'metadata' | 'rootDir' | 'version' | 'workers'> & {
listOnly: boolean;
};
@ -266,14 +268,17 @@ export class TeleReporterReceiver {
this._reporter.onError?.(error);
}
private _onStdIO(type: 'stdout' | 'stderr', testId: string | undefined, resultId: string | undefined, data: string, isBase64: boolean) {
private _onStdIO(type: JsonStdIOType, testId: string | undefined, resultId: string | undefined, data: string, isBase64: boolean) {
const chunk = isBase64 ? ((globalThis as any).Buffer ? Buffer.from(data, 'base64') : atob(data)) : data;
const test = testId ? this._tests.get(testId) : undefined;
const result = test && resultId ? test.resultsMap.get(resultId) : undefined;
if (type === 'stdout')
if (type === 'stdout') {
result?.stdout.push(chunk);
this._reporter.onStdOut?.(chunk, test, result);
else
} else {
result?.stderr.push(chunk);
this._reporter.onStdErr?.(chunk, test, result);
}
}
private _onEnd(result: FullResult): Promise<void> | undefined {

View File

@ -20,7 +20,7 @@ import type { SuitePrivate } from '../../types/reporterPrivate';
import type { FullConfig, FullResult, Location, Reporter, TestError, TestResult, TestStep } from '../../types/testReporter';
import { FullConfigInternal, FullProjectInternal } from '../common/config';
import type { Suite, TestCase } from '../common/test';
import type { JsonConfig, JsonEvent, JsonProject, JsonSuite, JsonTestCase, JsonTestEnd, JsonTestResultEnd, JsonTestResultStart, JsonTestStepEnd, JsonTestStepStart } from '../isomorphic/teleReceiver';
import type { JsonConfig, JsonEvent, JsonProject, JsonStdIOType, JsonSuite, JsonTestCase, JsonTestEnd, JsonTestResultEnd, JsonTestResultStart, JsonTestStepEnd, JsonTestStepStart } from '../isomorphic/teleReceiver';
import { serializeRegexPatterns } from '../isomorphic/teleReceiver';
export class TeleReporterEmitter implements Reporter {
@ -95,14 +95,14 @@ export class TeleReporterEmitter implements Reporter {
}
onStdOut(chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void {
this._onStdIO('stdio', chunk, test, result);
this._onStdIO('stdout', chunk, test, result);
}
onStdErr(chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void {
this._onStdIO('stderr', chunk, test, result);
}
private _onStdIO(type: 'stdio' | 'stderr', chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void {
private _onStdIO(type: JsonStdIOType, chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void {
const isBase64 = typeof chunk !== 'string';
const data = isBase64 ? chunk.toString('base64') : chunk;
this._messageSink({

View File

@ -314,7 +314,6 @@ test('total time is from test run not from merge', async ({ runInlineTest, merge
expect(exitCode).toBe(0);
expect(output).toContain('To open last HTML report run:');
// console.log(output);
await showReport();
@ -886,6 +885,68 @@ test('preserve config fields', async ({ runInlineTest, mergeReports }) => {
expect(json.quiet).toEqual(mergeConfig.quiet);
});
test('preserve stdout and stderr', async ({ runInlineTest, mergeReports }) => {
const reportDir = test.info().outputPath('blob-report');
const files = {
'echo-reporter.js': `
import fs from 'fs';
class EchoReporter {
log = [];
onStdOut(chunk, test, result) {
this.log.push('onStdOut: ' + chunk);
this.log.push('result.stdout: ' + result.stdout);
}
onStdErr(chunk, test, result) {
this.log.push('onStdErr: ' + chunk);
this.log.push('result.stderr: ' + result.stderr);
}
onTestEnd(test, result) {
this.log.push('onTestEnd');
this.log.push('result.stdout: ' + result.stdout);
this.log.push('result.stderr: ' + result.stderr);
}
onEnd() {
fs.writeFileSync('log.txt', this.log.join('\\n'));
}
}
module.exports = EchoReporter;
`,
'playwright.config.js': `
module.exports = {
reporter: [['blob']]
};
`,
'a.test.js': `
import { test, expect } from '@playwright/test';
test('a test', async ({}) => {
expect(1 + 1).toBe(2);
console.log('stdout text');
console.error('stderr text');
});
`,
};
await runInlineTest(files);
const { exitCode } = await mergeReports(reportDir, {}, { additionalArgs: ['--reporter', test.info().outputPath('echo-reporter.js')] });
expect(exitCode).toBe(0);
const log = fs.readFileSync(test.info().outputPath('log.txt')).toString();
expect(log).toBe(`onStdOut: stdout text
result.stdout: stdout text
onStdErr: stderr text
result.stderr: stderr text
onTestEnd
result.stdout: stdout text
result.stderr: stderr text
`);
});
test('preserve steps in html report', async ({ runInlineTest, mergeReports, showReport, page }) => {
const reportDir = test.info().outputPath('blob-report');
const files = {