From 4831f1b4c77ed9939552d136612d51adc6e48338 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 6 Oct 2026 08:25:38 -0700 Subject: [PATCH] =?UTF-8?q?Revert=20"feat(list=20reporter):=20add=20printW?= =?UTF-8?q?orkerIndex=20option=20to=20prefix=20output=20wit=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 91eeb0cfe92482f18ff8d40d746903ef23c0d8fd. --- docs/src/test-reporters-js.md | 11 ---- packages/playwright/src/reporters/list.ts | 62 +++++++-------------- packages/playwright/types/test.d.ts | 2 +- tests/playwright-test/reporter-list.spec.ts | 25 --------- utils/generate_types/overrides-test.d.ts | 2 +- 5 files changed, 22 insertions(+), 80 deletions(-) diff --git a/docs/src/test-reporters-js.md b/docs/src/test-reporters-js.md index e78805094e179..fec9c09ed1c56 100644 --- a/docs/src/test-reporters-js.md +++ b/docs/src/test-reporters-js.md @@ -117,16 +117,6 @@ export default defineConfig({ }); ``` -You can prefix every line of the output with the index of the worker that produced it: - -```js title="playwright.config.ts" -import { defineConfig } from '@playwright/test'; - -export default defineConfig({ - reporter: [['list', { printWorkerIndex: true }]], -}); -``` - List report supports the following configuration options and environment variables: | Environment Variable Name | Reporter Config Option| Description | Default @@ -134,7 +124,6 @@ List report supports the following configuration options and environment variabl | `PLAYWRIGHT_LIST_PRINT_STEPS` | `printSteps` | Whether to print each step on its own line. | `false` | `PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE` | `printFailuresInline` | Whether to print failure details immediately after a failed test instead of at the end. | `false` | `PLAYWRIGHT_LIST_OMIT_TAGS` | `omitTags` | Whether to omit test tags that are automatically appended to test titles. | `false` -| `PLAYWRIGHT_LIST_PRINT_WORKER_INDEX` | `printWorkerIndex` | Whether to prefix every line of the output with the index of the worker that produced it. | `false` | `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise. | `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise. | `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset diff --git a/packages/playwright/src/reporters/list.ts b/packages/playwright/src/reporters/list.ts index a6a31bbf50274..68db5a0ecafc4 100644 --- a/packages/playwright/src/reporters/list.ts +++ b/packages/playwright/src/reporters/list.ts @@ -39,7 +39,6 @@ class ListReporter extends TerminalReporter { private _needNewLine = false; private _printSteps: boolean; private _printFailuresInline: boolean; - private _printWorkerIndex: boolean; private _failureIndex = new Map(); private _paused = new Set(); @@ -48,7 +47,6 @@ class ListReporter extends TerminalReporter { super({ ...options, omitTags: getAsBooleanFromENV('PLAYWRIGHT_LIST_OMIT_TAGS', options?.omitTags), lastResult: printFailuresInline }); this._printSteps = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options?.printSteps); this._printFailuresInline = printFailuresInline; - this._printWorkerIndex = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_WORKER_INDEX', options?.printWorkerIndex); } override onBegin(suite: Suite) { @@ -68,19 +66,19 @@ class ListReporter extends TerminalReporter { return; this._maybeWriteNewLine(); this._testRows.set(test, this._lastRow); - const prefix = this._testPrefix(result, index, ''); + const prefix = this._testPrefix(index, ''); const line = this.screen.colors.dim(this.formatTestTitle(test)) + this._retrySuffix(result); this._appendLine(line, prefix); } override onStdOut(chunk: string | Buffer, test?: TestCase, result?: TestResult) { super.onStdOut(chunk, test, result); - this._dumpToStdio(chunk, this.screen.stdout, result); + this._dumpToStdio(test, chunk, this.screen.stdout, 'out'); } override onStdErr(chunk: string | Buffer, test?: TestCase, result?: TestResult) { super.onStdErr(chunk, test, result); - this._dumpToStdio(chunk, this.screen.stderr, result); + this._dumpToStdio(test, chunk, this.screen.stderr, 'err'); } private getStepIndex(testIndex: string, result: TestResult, step: TestStep): string { @@ -105,11 +103,11 @@ class ListReporter extends TerminalReporter { if (this._printSteps) { this._maybeWriteNewLine(); this._stepRows.set(step, this._lastRow); - const prefix = this._testPrefix(result, this.getStepIndex(testIndex, result, step), ''); + const prefix = this._testPrefix(this.getStepIndex(testIndex, result, step), ''); const line = test.title + this.screen.colors.dim(stepSuffix(step)); this._appendLine(line, prefix); } else { - this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step)) + this._retrySuffix(result), this._testPrefix(result, testIndex, '')); + this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step)) + this._retrySuffix(result), this._testPrefix(testIndex, '')); } } @@ -120,13 +118,13 @@ class ListReporter extends TerminalReporter { const testIndex = this._resultIndex.get(result) || ''; if (!this._printSteps) { if (this.screen.isTTY) - this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step.parent)) + this._retrySuffix(result), this._testPrefix(result, testIndex, '')); + this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step.parent)) + this._retrySuffix(result), this._testPrefix(testIndex, '')); return; } const index = this.getStepIndex(testIndex, result, step); const title = this.screen.isTTY ? test.title + this.screen.colors.dim(stepSuffix(step)) : this.formatTestTitle(test, step); - const prefix = this._testPrefix(result, index, ''); + const prefix = this._testPrefix(index, ''); let text = ''; if (step.error) text = this.screen.colors.red(title); @@ -164,25 +162,12 @@ class ListReporter extends TerminalReporter { } } - private _dumpToStdio(chunk: string | Buffer, stream: NodeJS.WriteStream, result: TestResult | undefined) { + private _dumpToStdio(test: TestCase | undefined, chunk: string | Buffer, stream: NodeJS.WriteStream, stdio: 'out' | 'err') { if (this.config.quiet) return; - let text = chunk.toString('utf-8'); - if (result) - text = this._prefixLines(text, this._workerPrefix(result), !this._needNewLine); + const text = chunk.toString('utf-8'); this._updateLineCountAndNewLineFlagForOutput(text); - stream.write(text); - } - - private _prefixLines(text: string, prefix: string, atLineStart: boolean) { - if (!prefix) - return text; - const lines = text.split('\n'); - return lines.map((line, i) => { - if (!line || (i === 0 && !atLineStart)) - return line; - return prefix + line; - }).join('\n'); + stream.write(chunk); } async onTestPaused(test: TestCase, result: TestResult) { @@ -195,12 +180,12 @@ class ListReporter extends TerminalReporter { this._updateTestLine(test, result); this._maybeWriteNewLine(); if (test.outcome() === 'unexpected') { - const errors = this._prefixLines(this.formatResultErrors(test, result), this._workerPrefix(result), true); + const errors = this.formatResultErrors(test, result); this.writeLine(errors); this._updateLineCountAndNewLineFlagForOutput(errors); markErrorsAsReported(result); } - this._appendLine(this.screen.colors.yellow(`Paused ${test.outcome() === 'unexpected' ? 'on error' : 'at test end'}. Press Ctrl+C to end.`), this._testPrefix(result, '', '')); + this._appendLine(this.screen.colors.yellow(`Paused ${test.outcome() === 'unexpected' ? 'on error' : 'at test end'}. Press Ctrl+C to end.`), this._testPrefix('', '')); await new Promise(() => {}); } @@ -212,10 +197,10 @@ class ListReporter extends TerminalReporter { this._updateTestLine(test, result); const isFailure = result.status !== 'skipped' && result.status !== test.expectedStatus; if (!wasPaused && this._printFailuresInline && isFailure) - this._printFailure(test, result); + this._printFailure(test); } - private _printFailure(test: TestCase, result: TestResult) { + private _printFailure(test: TestCase) { this._maybeWriteNewLine(); // Retries of the same test share one failure index. let index = this._failureIndex.get(test); @@ -223,7 +208,7 @@ class ListReporter extends TerminalReporter { index = this._failureIndex.size + 1; this._failureIndex.set(test, index); } - const message = this._prefixLines('\n' + this.formatFailure(test, index) + '\n', this._workerPrefix(result), true); + const message = '\n' + this.formatFailure(test, index) + '\n'; this._updateLineCountAndNewLineFlagForOutput(message); this.screen.stdout.write(message); } @@ -242,16 +227,16 @@ class ListReporter extends TerminalReporter { } if (result.status === 'skipped') { - prefix = this._testPrefix(result, index, this.screen.colors.green('-')); + prefix = this._testPrefix(index, this.screen.colors.green('-')); // Do not show duration for skipped. text = this.screen.colors.cyan(title) + this._retrySuffix(result); } else { const statusMark = result.status === 'passed' ? POSITIVE_STATUS_MARK : NEGATIVE_STATUS_MARK; if (result.status === test.expectedStatus) { - prefix = this._testPrefix(result, index, this.screen.colors.green(statusMark)); + prefix = this._testPrefix(index, this.screen.colors.green(statusMark)); text = title; } else { - prefix = this._testPrefix(result, index, this.screen.colors.red(statusMark)); + prefix = this._testPrefix(index, this.screen.colors.red(statusMark)); text = this.screen.colors.red(title); } text += this._retrySuffix(result) + this.screen.colors.dim(` (${msToString(result.duration)})`); @@ -304,17 +289,10 @@ class ListReporter extends TerminalReporter { this.screen.stdout.write(`\u001B[${this._lastRow - row}E`); } - private _workerPrefix(result: TestResult) { - if (!this._printWorkerIndex) - return ''; - const workerIndex = result.workerIndex >= 0 ? String(result.workerIndex) : ' '; - return this.screen.colors.dim(`[${workerIndex}]`) + ' '; - } - - private _testPrefix(result: TestResult, index: string, statusMark: string) { + private _testPrefix(index: string, statusMark: string) { const statusMarkLength = stripAnsiEscapes(statusMark).length; const indexLength = Math.ceil(Math.log10(this.totalTestCount + 1)); - return this._workerPrefix(result) + ' ' + statusMark + ' '.repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + ' '); + return ' ' + statusMark + ' '.repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + ' '); } private _retrySuffix(result: TestResult) { diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 1b6826812a531..57764cc38f4cd 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -21,7 +21,7 @@ export * from 'playwright-core'; export type BlobReporterOptions = { outputDir?: string, fileName?: string }; export type DotReporterOptions = { omitTags?: boolean }; export type LineReporterOptions = { omitTags?: boolean }; -export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean, omitTags?: boolean, printWorkerIndex?: boolean }; +export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean, omitTags?: boolean }; export type GitHubReporterOptions = { omitTags?: boolean }; export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean, includeRetries?: boolean, omitTags?: boolean }; export type JsonReporterOptions = { outputFile?: string }; diff --git a/tests/playwright-test/reporter-list.spec.ts b/tests/playwright-test/reporter-list.spec.ts index c2f78de3abace..dcda138cb8d96 100644 --- a/tests/playwright-test/reporter-list.spec.ts +++ b/tests/playwright-test/reporter-list.spec.ts @@ -373,31 +373,6 @@ for (const useIntermediateMergeReport of [false, true] as const) { expect(result.exitCode).toBe(0); }); - test('print worker index', async ({ runInlineTest }) => { - const result = await runInlineTest({ - 'playwright.config.ts': ` - module.exports = { reporter: [['list', { printWorkerIndex: true, printFailuresInline: true }]] }; - `, - 'a.test.ts': ` - import { test, expect } from '@playwright/test'; - test('fails', async ({}) => { - expect(1).toBe(2); - }); - test('passes', async ({}) => { - console.log('line1\\nline2'); - }); - `, - }, { workers: 1 }, { PW_TEST_DEBUG_REPORTERS: '1', PLAYWRIGHT_FORCE_TTY: '80' }); - expect(result.exitCode).toBe(1); - const lines = result.output.split('\n').map(l => l.replace(/^#\d+ : /, '')); - expect(lines.some(l => l.startsWith(`[0] ${NEGATIVE_STATUS_MARK} 1 a.test.ts:3:15 › fails`))).toBe(true); - expect(lines).toContain('[0] Error: expect(received).toBe(expected) // Object.is equality'); - expect(lines.some(l => /^\[0\] +at .*a.test.ts:4:23/.test(l))).toBe(true); - expect(lines).toContain('[1] line1'); - expect(lines).toContain('[1] line2'); - expect(lines.some(l => l.startsWith(`[1] ${POSITIVE_STATUS_MARK} 2 a.test.ts:6:15 › passes`))).toBe(true); - }); - test('print stdio', async ({ runInlineTest }) => { const result = await runInlineTest({ 'a.test.ts': ` diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 88cb51be18b76..df4d900bd8774 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -20,7 +20,7 @@ export * from 'playwright-core'; export type BlobReporterOptions = { outputDir?: string, fileName?: string }; export type DotReporterOptions = { omitTags?: boolean }; export type LineReporterOptions = { omitTags?: boolean }; -export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean, omitTags?: boolean, printWorkerIndex?: boolean }; +export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean, omitTags?: boolean }; export type GitHubReporterOptions = { omitTags?: boolean }; export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean, includeRetries?: boolean, omitTags?: boolean }; export type JsonReporterOptions = { outputFile?: string };