fix(list reporter): do not break after output without trailing eol (#34410)

This commit is contained in:
Dmitry Gozman 2025-01-21 18:30:09 +00:00 committed by GitHub
parent 333e994e7d
commit 888feb06be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 2 deletions

View File

@ -129,6 +129,8 @@ class ListReporter extends TerminalReporter {
if (this._needNewLine) {
this._needNewLine = false;
process.stdout.write('\n');
++this._lastRow;
this._lastColumn = 0;
}
}
@ -210,6 +212,7 @@ class ListReporter extends TerminalReporter {
process.stdout.write('\n');
}
++this._lastRow;
this._lastColumn = 0;
}
private _updateLine(row: number, text: string, prefix: string) {

View File

@ -75,16 +75,20 @@ export class WorkerMain extends ProcessRunner {
process.on('unhandledRejection', reason => this.unhandledError(reason));
process.on('uncaughtException', error => this.unhandledError(error));
process.stdout.write = (chunk: string | Buffer) => {
process.stdout.write = (chunk: string | Buffer, cb?: any) => {
this.dispatchEvent('stdOut', stdioChunkToParams(chunk));
this._currentTest?._tracing.appendStdioToTrace('stdout', chunk);
if (typeof cb === 'function')
process.nextTick(cb);
return true;
};
if (!process.env.PW_RUNNER_DEBUG) {
process.stderr.write = (chunk: string | Buffer) => {
process.stderr.write = (chunk: string | Buffer, cb?: any) => {
this.dispatchEvent('stdErr', stdioChunkToParams(chunk));
this._currentTest?._tracing.appendStdioToTrace('stderr', chunk);
if (typeof cb === 'function')
process.nextTick(cb);
return true;
};
}

View File

@ -229,6 +229,7 @@ export function cleanEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
// END: Reserved CI
PW_TEST_HTML_REPORT_OPEN: undefined,
PLAYWRIGHT_HTML_OPEN: undefined,
PW_TEST_DEBUG_REPORTERS: undefined,
PW_TEST_REPORTER: undefined,
PW_TEST_REPORTER_WS_ENDPOINT: undefined,
PW_TEST_SOURCE_TRANSFORM: undefined,

View File

@ -258,6 +258,51 @@ for (const useIntermediateMergeReport of [false, true] as const) {
expect(text).toContain('1) a.test.ts:3:15 passes outer 1.0 inner 1.1 ──');
expect(result.exitCode).toBe(1);
});
test('print stdio', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.ts': `
import { test, expect } from '@playwright/test';
test('passes', async ({}) => {
await new Promise(resolve => process.stdout.write('line1', () => resolve()));
await new Promise(resolve => process.stdout.write('line2\\n', () => resolve()));
await new Promise(resolve => process.stderr.write(Buffer.from(''), () => resolve()));
});
test('passes 2', async ({}) => {
await new Promise(resolve => process.stdout.write('partial', () => resolve()));
});
test('passes 3', async ({}) => {
await new Promise(resolve => process.stdout.write('full\\n', () => resolve()));
});
test('passes 4', async ({}) => {
});
`,
}, { reporter: 'list' }, { PW_TEST_DEBUG_REPORTERS: '1', PLAYWRIGHT_FORCE_TTY: '80' });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(4);
const expected = [
'#0 : 1 a.test.ts:3:15 passes',
'line1line2',
`#0 : ${POSITIVE_STATUS_MARK} 1 a.test.ts:3:15 passes`,
'',
'#3 : 2 a.test.ts:9:15 passes 2',
`partial#3 : ${POSITIVE_STATUS_MARK} 2 a.test.ts:9:15 passes 2`,
'',
'#5 : 3 a.test.ts:13:15 passes 3',
'full',
`#5 : ${POSITIVE_STATUS_MARK} 3 a.test.ts:13:15 passes 3`,
'#7 : 4 a.test.ts:17:15 passes 4',
`#7 : ${POSITIVE_STATUS_MARK} 4 a.test.ts:17:15 passes 4`,
];
const lines = result.output.split('\n');
const firstIndex = lines.indexOf(expected[0]);
expect(firstIndex, 'first line should be there').not.toBe(-1);
for (let i = 0; i < expected.length; ++i)
expect(lines[firstIndex + i]).toContain(expected[i]);
});
});
}