Skip to content

Commit 658affe

Browse files
ChihebBENCHEIKH1Chiheb Bencheikhsheremet-va
authored
fix(reporters): print parent describe suites when the passed-test list is hidden (fix #10606) (#10768)
Co-authored-by: Chiheb Bencheikh <[email protected]> Co-authored-by: Vladimir <[email protected]>
1 parent 99e596d commit 658affe

4 files changed

Lines changed: 125 additions & 1 deletion

File tree

packages/vitest/src/node/reporters/base.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export abstract class BaseReporter implements Reporter {
5858
private _filesInWatchMode = new Map<string, number>()
5959
private _timeStart = formatTimeString(new Date())
6060
private _perProjectBenchmarks = new Map<string, Map<string, TestBenchmarkTask>>()
61+
private _printedSuites = new Set<string>()
6162

6263
constructor(options: BaseOptions = {}) {
6364
this.isTTY = options.isTTY ?? isTTY
@@ -157,6 +158,8 @@ export abstract class BaseReporter implements Reporter {
157158
return
158159
}
159160

161+
this._printedSuites.clear()
162+
160163
let testsCount = 0
161164
let failedCount = 0
162165
let skippedCount = 0
@@ -234,11 +237,13 @@ export abstract class BaseReporter implements Reporter {
234237
const inlineBenchmarks: TestBenchmark[] = benchmarks.filter(b => b.tasks.length > 0)
235238

236239
if (testResult.state === 'failed') {
240+
this.printAncestorSuites(test)
237241
this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test.task, separator)}`) + suffix)
238242
}
239243

240244
// also print slow tests
241245
else if (duration > this.ctx.config.slowTestThreshold) {
246+
this.printAncestorSuites(test)
242247
this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, separator)}${suffix}`)
243248
}
244249

@@ -247,6 +252,7 @@ export abstract class BaseReporter implements Reporter {
247252
}
248253

249254
else if (this.renderSucceed || moduleState === 'failed' || inlineBenchmarks.length) {
255+
this.printAncestorSuites(test)
250256
this.log(` ${padding}${this.getStateSymbol(test)} ${this.getTestName(test.task, separator)}${suffix}`)
251257
}
252258

@@ -292,13 +298,43 @@ export abstract class BaseReporter implements Reporter {
292298
return
293299
}
294300

301+
this.printSuiteEntry(testSuite)
302+
}
303+
304+
private printSuiteEntry(testSuite: TestSuite): void {
305+
if (this._printedSuites.has(testSuite.id)) {
306+
return
307+
}
308+
this._printedSuites.add(testSuite.id)
309+
295310
const indentation = ' '.repeat(getIndentation(testSuite.task))
296311
const tests = Array.from(testSuite.children.allTests())
297312
const state = this.getStateSymbol(testSuite)
298313

299314
this.log(` ${indentation}${state} ${testSuite.name} ${c.dim(`(${tests.length})`)}`)
300315
}
301316

317+
// When a test line is emitted while renderSucceed is off (e.g. slow tests
318+
// or inline benchmarks in CI), its parent describe suites were never printed
319+
// by the outer visitor. Walk up and print any that are still missing so the
320+
// nesting matches what the TTY output would show.
321+
private printAncestorSuites(test: TestCase): void {
322+
if (this.renderSucceed) {
323+
return
324+
}
325+
326+
const suites: TestSuite[] = []
327+
let parent = test.parent
328+
while (parent.type === 'suite' && !this._printedSuites.has(parent.id)) {
329+
suites.push(parent)
330+
parent = parent.parent
331+
}
332+
333+
for (let i = suites.length - 1; i >= 0; i--) {
334+
this.printSuiteEntry(suites[i])
335+
}
336+
}
337+
302338
protected getTestName(test: Task, _separator?: string): string {
303339
return test.name
304340
}

test/e2e/test/reporters/agent.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ describe('agent reporter', async () => {
1818
const output = trimReporterOutput(stdout)
1919
expect(output).toMatchInlineSnapshot(`
2020
"❯ b1.test.ts (13 tests | 1 failed) [...]ms
21+
❯ b1 failed (7)
2122
× b failed test [...]ms
2223
❯ b2.test.ts (13 tests | 1 failed) [...]ms
24+
❯ b2 failed (7)
2325
× b failed test [...]ms"
2426
`)
2527

test/e2e/test/reporters/default.test.ts

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { RunnerTask } from 'vitest/node'
22
import { describe, expect, test } from 'vitest'
33
import { DefaultReporter } from 'vitest/node'
4-
import { runVitest, runVitestCli, StableTestFileOrderSorter } from '#test-utils'
4+
import { runInlineTests, runVitest, runVitestCli, StableTestFileOrderSorter } from '#test-utils'
55
import { trimReporterOutput } from './utils'
66

77
describe('default reporter', async () => {
@@ -18,30 +18,38 @@ describe('default reporter', async () => {
1818

1919
expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(`
2020
"❯ b1.test.ts (13 tests | 1 failed) [...]ms
21+
✓ b1 passed (6)
2122
✓ b1 test [...]ms
2223
✓ b2 test [...]ms
2324
✓ b3 test [...]ms
25+
✓ nested b (3)
2426
✓ nested b1 test [...]ms
2527
✓ nested b2 test [...]ms
2628
✓ nested b3 test [...]ms
29+
❯ b1 failed (7)
2730
✓ b1 test [...]ms
2831
✓ b2 test [...]ms
2932
✓ b3 test [...]ms
3033
× b failed test [...]ms
34+
✓ nested b (3)
3135
✓ nested b1 test [...]ms
3236
✓ nested b2 test [...]ms
3337
✓ nested b3 test [...]ms
3438
❯ b2.test.ts (13 tests | 1 failed) [...]ms
39+
✓ b2 passed (6)
3540
✓ b1 test [...]ms
3641
✓ b2 test [...]ms
3742
✓ b3 test [...]ms
43+
✓ nested b (3)
3844
✓ nested b1 test [...]ms
3945
✓ nested b2 test [...]ms
4046
✓ nested b3 test [...]ms
47+
❯ b2 failed (7)
4148
✓ b1 test [...]ms
4249
✓ b2 test [...]ms
4350
✓ b3 test [...]ms
4451
× b failed test [...]ms
52+
✓ nested b (3)
4553
✓ nested b1 test [...]ms
4654
✓ nested b2 test [...]ms
4755
✓ nested b3 test [...]ms"
@@ -66,6 +74,83 @@ describe('default reporter', async () => {
6674
`)
6775
})
6876

77+
// https://github.com/vitest-dev/vitest/issues/10606
78+
// With renderSucceed off (non-TTY / multi-file), slow tests and tests with
79+
// inline benchmarks are still logged. Their describe suites must be printed
80+
// above them so the nesting is not lost.
81+
test('prints parent describe suites for slow tests when renderSucceed is off', async () => {
82+
const { stdout, stderr } = await runInlineTests(
83+
{
84+
'slow.test.ts': /* ts */`
85+
import { describe, test } from 'vitest'
86+
87+
describe('outer', () => {
88+
describe('inner', () => {
89+
test('slow', async () => {
90+
await new Promise(resolve => setTimeout(resolve, 50))
91+
})
92+
})
93+
})
94+
`,
95+
},
96+
{
97+
reporters: [['default', { isTTY: false, summary: false }]],
98+
slowTestThreshold: 1,
99+
},
100+
)
101+
102+
expect(stderr).toBe('')
103+
expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(`
104+
"✓ slow.test.ts (1 test) [...]ms
105+
✓ outer (1)
106+
✓ inner (1)
107+
✓ slow [...]ms"
108+
`)
109+
})
110+
111+
test('prints parent describe suites for inline benchmarks when renderSucceed is off', async () => {
112+
const { stdout, stderr } = await runInlineTests(
113+
{
114+
'suite.bench.ts': /* ts */`
115+
import { describe, inject, test } from 'vitest'
116+
117+
describe('my first suite', () => {
118+
test('foo', async ({ bench }) => {
119+
await bench('foo', () => {}).run(inject('options'))
120+
})
121+
})
122+
123+
describe('my second suite', () => {
124+
test('foo', async ({ bench }) => {
125+
await bench('foo', () => {}).run(inject('options'))
126+
})
127+
})
128+
`,
129+
},
130+
{
131+
benchmark: { enabled: true },
132+
reporters: [['default', { isTTY: false, summary: false }]],
133+
provide: { options: { time: 0, iterations: 1, warmupTime: 0, warmupIterations: 0 } },
134+
},
135+
)
136+
137+
expect(stderr).toBe('')
138+
139+
// benchmark table rows carry runtime-specific numbers, so keep only the
140+
// reporter tree lines when asserting the nesting
141+
const tree = trimReporterOutput(stdout)
142+
.split('\n')
143+
.filter(line => /[×]/.test(line))
144+
.join('\n')
145+
expect(tree).toMatchInlineSnapshot(`
146+
"✓ |bench| suite.bench.ts (2 tests) [...]ms
147+
✓ my first suite (1)
148+
✓ foo [...]ms
149+
✓ my second suite (1)
150+
✓ foo [...]ms"
151+
`)
152+
})
153+
69154
test('show full test suite when only one file', async () => {
70155
const { stdout } = await runVitest({
71156
include: ['a.test.ts'],

test/e2e/test/reporters/merge-reports.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ test('merge reports', async () => {
108108
109109
❯ second.test.ts (3 tests | 1 failed) <time>
110110
× test 2-1 <time>
111+
✓ group (2)
111112
✓ test 2-2 <time>
112113
✓ test 2-3 <time>
113114

0 commit comments

Comments
 (0)