diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index 4d6ed941e92f..e8a5abf68106 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -131,7 +131,7 @@ export abstract class BaseReporter implements Reporter { for (const test of tests) { const { duration, retryCount, repeatCount } = test.result || {} const padding = this.getTestIndentation(test) - let suffix = '' + let suffix = this.getDurationPrefix(test) if (retryCount != null && retryCount > 0) { suffix += c.yellow(` (retry x${retryCount})`) @@ -142,7 +142,7 @@ export abstract class BaseReporter implements Reporter { } if (test.result?.state === 'fail') { - this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test, c.dim(' > '))}${this.getDurationPrefix(test)}`) + suffix) + this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test, c.dim(' > '))}`) + suffix) // print short errors, full errors will be at the end in summary test.result?.errors?.forEach((error) => { @@ -156,10 +156,7 @@ export abstract class BaseReporter implements Reporter { // also print slow tests else if (duration && duration > this.ctx.config.slowTestThreshold) { - this.log( - ` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test, c.dim(' > '))}` - + ` ${c.yellow(Math.round(duration) + c.dim('ms'))}${suffix}`, - ) + this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test, c.dim(' > '))} ${suffix}`) } else if (this.ctx.config.hideSkippedTests && (test.mode === 'skip' || test.result?.state === 'skip')) { @@ -194,14 +191,14 @@ export abstract class BaseReporter implements Reporter { return ' ' } - private getDurationPrefix(task: Task) { + protected getDurationPrefix(task: Task): string { if (!task.result?.duration) { return '' } const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow - : c.gray + : c.green return color(` ${Math.round(task.result.duration)}${c.dim('ms')}`) } diff --git a/packages/vitest/src/node/reporters/benchmark/tableRender.ts b/packages/vitest/src/node/reporters/benchmark/tableRender.ts index 646d48db5e93..266bea30242a 100644 --- a/packages/vitest/src/node/reporters/benchmark/tableRender.ts +++ b/packages/vitest/src/node/reporters/benchmark/tableRender.ts @@ -137,8 +137,10 @@ export function renderTable( suffix += c.dim(c.gray(' [skipped]')) } - if (duration != null && duration > options.slowTestThreshold) { - suffix += c.yellow(` ${Math.round(duration)}${c.dim('ms')}`) + if (duration != null) { + const color = duration > options.slowTestThreshold ? c.yellow : c.green + + suffix += color(` ${Math.round(duration)}${c.dim('ms')}`) } if (options.showHeap && task.result?.heap != null) { diff --git a/packages/vitest/src/node/reporters/verbose.ts b/packages/vitest/src/node/reporters/verbose.ts index 4577cabb358d..522011b0349f 100644 --- a/packages/vitest/src/node/reporters/verbose.ts +++ b/packages/vitest/src/node/reporters/verbose.ts @@ -18,7 +18,6 @@ export class VerboseReporter extends DefaultReporter { return } - const duration = task.result.duration let title = ` ${getStateSymbol(task)} ` if (task.file.projectName) { @@ -26,10 +25,7 @@ export class VerboseReporter extends DefaultReporter { } title += getFullName(task, c.dim(' > ')) - - if (duration != null && duration > this.ctx.config.slowTestThreshold) { - title += c.yellow(` ${Math.round(duration)}${c.dim('ms')}`) - } + title += super.getDurationPrefix(task) if (this.ctx.config.logHeapUsage && task.result.heap != null) { title += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`) diff --git a/test/reporters/tests/default.test.ts b/test/reporters/tests/default.test.ts index 4075d1620764..a21c9fdb6a59 100644 --- a/test/reporters/tests/default.test.ts +++ b/test/reporters/tests/default.test.ts @@ -22,41 +22,37 @@ describe('default reporter', async () => { }, }) - const rows = stdout.replace(/\d+ms/g, '[...]ms').split('\n') - rows.splice(0, rows.findIndex(row => row.includes('b1.test.ts'))) - rows.splice(rows.findIndex(row => row.includes('Test Files'))) - - expect(rows.join('\n').trim()).toMatchInlineSnapshot(` + expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(` "❯ b1.test.ts (13 tests | 1 failed) [...]ms - ✓ b1 passed > b1 test - ✓ b1 passed > b2 test - ✓ b1 passed > b3 test - ✓ b1 passed > nested b > nested b1 test - ✓ b1 passed > nested b > nested b2 test - ✓ b1 passed > nested b > nested b3 test - ✓ b1 failed > b1 test - ✓ b1 failed > b2 test - ✓ b1 failed > b3 test + ✓ b1 passed > b1 test [...]ms + ✓ b1 passed > b2 test [...]ms + ✓ b1 passed > b3 test [...]ms + ✓ b1 passed > nested b > nested b1 test [...]ms + ✓ b1 passed > nested b > nested b2 test [...]ms + ✓ b1 passed > nested b > nested b3 test [...]ms + ✓ b1 failed > b1 test [...]ms + ✓ b1 failed > b2 test [...]ms + ✓ b1 failed > b3 test [...]ms × b1 failed > b failed test [...]ms → expected 1 to be 2 // Object.is equality - ✓ b1 failed > nested b > nested b1 test - ✓ b1 failed > nested b > nested b2 test - ✓ b1 failed > nested b > nested b3 test + ✓ b1 failed > nested b > nested b1 test [...]ms + ✓ b1 failed > nested b > nested b2 test [...]ms + ✓ b1 failed > nested b > nested b3 test [...]ms ❯ b2.test.ts (13 tests | 1 failed) [...]ms - ✓ b2 passed > b1 test - ✓ b2 passed > b2 test - ✓ b2 passed > b3 test - ✓ b2 passed > nested b > nested b1 test - ✓ b2 passed > nested b > nested b2 test - ✓ b2 passed > nested b > nested b3 test - ✓ b2 failed > b1 test - ✓ b2 failed > b2 test - ✓ b2 failed > b3 test + ✓ b2 passed > b1 test [...]ms + ✓ b2 passed > b2 test [...]ms + ✓ b2 passed > b3 test [...]ms + ✓ b2 passed > nested b > nested b1 test [...]ms + ✓ b2 passed > nested b > nested b2 test [...]ms + ✓ b2 passed > nested b > nested b3 test [...]ms + ✓ b2 failed > b1 test [...]ms + ✓ b2 failed > b2 test [...]ms + ✓ b2 failed > b3 test [...]ms × b2 failed > b failed test [...]ms → expected 1 to be 2 // Object.is equality - ✓ b2 failed > nested b > nested b1 test - ✓ b2 failed > nested b > nested b2 test - ✓ b2 failed > nested b > nested b3 test" + ✓ b2 failed > nested b > nested b1 test [...]ms + ✓ b2 failed > nested b > nested b2 test [...]ms + ✓ b2 failed > nested b > nested b3 test [...]ms" `) }) @@ -164,7 +160,7 @@ describe('default reporter', async () => { }) expect(stdout).toContain('1 passed') - expect(stdout).toContain('✓ pass after retries (retry x3)') + expect(trimReporterOutput(stdout)).toContain('✓ pass after retries [...]ms (retry x3)') }) test('prints repeat count', async () => { @@ -175,6 +171,16 @@ describe('default reporter', async () => { }) expect(stdout).toContain('1 passed') - expect(stdout).toContain('✓ repeat couple of times (repeat x3)') + expect(trimReporterOutput(stdout)).toContain('✓ repeat couple of times [...]ms (repeat x3)') }) }, 120000) + +function trimReporterOutput(report: string) { + const rows = report.replace(/\d+ms/g, '[...]ms').split('\n') + + // Trim start and end, capture just rendered tree + rows.splice(0, 1 + rows.findIndex(row => row.includes('RUN v'))) + rows.splice(rows.findIndex(row => row.includes('Test Files'))) + + return rows.join('\n').trim() +} diff --git a/test/reporters/tests/merge-reports.test.ts b/test/reporters/tests/merge-reports.test.ts index 9dc10dd84fbc..bd0fab5027d9 100644 --- a/test/reporters/tests/merge-reports.test.ts +++ b/test/reporters/tests/merge-reports.test.ts @@ -91,7 +91,7 @@ test('merge reports', async () => { test 1-2 ❯ first.test.ts (2 tests | 1 failed)