diff --git a/packages/playwright/src/reporters/list.ts b/packages/playwright/src/reporters/list.ts index 94e507fd4b..ee43deff68 100644 --- a/packages/playwright/src/reporters/list.ts +++ b/packages/playwright/src/reporters/list.ts @@ -36,7 +36,7 @@ class ListReporter extends BaseReporter { constructor(options: { printSteps?: boolean } = {}) { super(); - this._printSteps = isTTY && getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options.printSteps); + this._printSteps = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options.printSteps); } override printsToStdio() { @@ -80,17 +80,17 @@ class ListReporter extends BaseReporter { if (step.category !== 'test.step') return; const testIndex = this._resultIndex.get(result) || ''; + const ordinal = ((result as any)[lastStepOrdinalSymbol] || 0) + 1; + (result as any)[lastStepOrdinalSymbol] = ordinal; + const stepIndex = `${testIndex}.${ordinal}`; + this._stepIndex.set(step, stepIndex); + if (!this._printSteps) { if (isTTY) this._updateLine(this._testRows.get(test)!, colors.dim(formatTestTitle(this.config, test, step)) + this._retrySuffix(result), this._testPrefix(testIndex, '')); return; } - const ordinal = ((result as any)[lastStepOrdinalSymbol] || 0) + 1; - (result as any)[lastStepOrdinalSymbol] = ordinal; - const stepIndex = `${testIndex}.${ordinal}`; - this._stepIndex.set(step, stepIndex); - if (isTTY) { this._maybeWriteNewLine(); this._stepRows.set(step, this._lastRow); @@ -109,7 +109,6 @@ class ListReporter extends BaseReporter { if (!this._printSteps) { if (isTTY) this._updateLine(this._testRows.get(test)!, colors.dim(formatTestTitle(this.config, test, step.parent)) + this._retrySuffix(result), this._testPrefix(testIndex, '')); - return; } const index = this._stepIndex.get(step)!; diff --git a/tests/playwright-test/reporter-list.spec.ts b/tests/playwright-test/reporter-list.spec.ts index 489e97feb7..52ac467d48 100644 --- a/tests/playwright-test/reporter-list.spec.ts +++ b/tests/playwright-test/reporter-list.spec.ts @@ -126,6 +126,35 @@ for (const useIntermediateMergeReport of [false, true] as const) { ]); }); + test('render steps in non-TTY mode', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('passes', async ({}) => { + await test.step('outer 1.0', async () => { + await test.step('inner 1.1', async () => {}); + await test.step('inner 1.2', async () => {}); + }); + await test.step('outer 2.0', async () => { + await test.step('inner 2.1', async () => {}); + await test.step('inner 2.2', async () => {}); + }); + }); + `, + }, { reporter: 'list' }, { PW_TEST_DEBUG_REPORTERS: '1', PLAYWRIGHT_LIST_PRINT_STEPS: '1' }); + const text = result.output; + const lines = text.split('\n').filter(l => l.match(/^\d :/)).map(l => l.replace(/[.\d]+m?s/, 'Xms')); + lines.pop(); // Remove last item that contains [v] and time in ms. + expect(lines).toEqual([ + '0 : .2 passes › outer 1.0 › inner 1.1 (Xms)', + '1 : .3 passes › outer 1.0 › inner 1.2 (Xms)', + '2 : .1 passes › outer 1.0 (Xms)', + '3 : .5 passes › outer 2.0 › inner 2.1 (Xms)', + '4 : .6 passes › outer 2.0 › inner 2.2 (Xms)', + '5 : .4 passes › outer 2.0 (Xms)', + ]); + }); + test('very long console line should not mess terminal', async ({ runInlineTest }) => { const TTY_WIDTH = 80; const result = await runInlineTest({