Skip to content

Commit 272296e

Browse files
hi-ogawaclaude
andauthored
fix(browser): print trace timeline of each attempt (#11695)
Co-authored-by: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a502265 commit 272296e

3 files changed

Lines changed: 21 additions & 15 deletions

File tree

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,13 +1533,15 @@ export abstract class BaseReporter implements Reporter {
15331533
screenshotPaths,
15341534
})
15351535

1536-
// TODO: print the trace of the attempt that produced this error instead of the last attempt,
1537-
// using `task.result.attempts` (https://github.com/vitest-dev/vitest/pull/11232)
1538-
for (const task of tasks) {
1539-
const timeline =
1540-
task.type === 'test' && formatTraceTimeline(task.artifacts, this.ctx.config.root)
1541-
if (timeline) {
1542-
this.error(`${timeline}\n`)
1536+
for (const [task, attempts] of attemptsByTask) {
1537+
for (const attempt of attempts) {
1538+
const timeline =
1539+
task.type === 'test' &&
1540+
attempt &&
1541+
formatTraceTimeline(task.artifacts, attempt, this.ctx.config.root)
1542+
if (timeline) {
1543+
this.error(`${timeline}\n`)
1544+
}
15431545
}
15441546
}
15451547

‎packages/vitest/src/node/reporters/renderers/trace-timeline.ts‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { TestArtifact } from '../../../runtime/runner/types'
1+
import type { TaskResultAttempt, TestArtifact } from '../../../runtime/runner/types'
22
import { relative } from 'pathe'
33
import c from 'tinyrainbow'
44
import { F_TREE_NODE_END, F_TREE_NODE_MIDDLE } from './figures'
@@ -10,8 +10,14 @@ interface TimelineRow {
1010

1111
const MAX_STEPS = 10
1212

13-
export function formatTraceTimeline(artifacts: TestArtifact[], root: string): string | undefined {
14-
const attempt = [...getTraceAttemptMap(artifacts).values()].at(-1)
13+
export function formatTraceTimeline(
14+
artifacts: TestArtifact[],
15+
{ retryIndex, repeatIndex }: TaskResultAttempt,
16+
root: string,
17+
): string | undefined {
18+
const attempt = getTraceAttemptMap(artifacts).get(
19+
getTraceAttemptKey({ retry: retryIndex, repeats: repeatIndex }),
20+
)
1521
if (!attempt) {
1622
return
1723
}
@@ -130,7 +136,7 @@ interface NormalizedBrowserTraceEntry extends BrowserTraceEntry {
130136
depth: number
131137
}
132138

133-
function getTraceAttemptKey(trace: BrowserTraceData): string {
139+
function getTraceAttemptKey(trace: Pick<BrowserTraceData, 'retry' | 'repeats'>): string {
134140
return `${trace.repeats}:${trace.retry}`
135141
}
136142

‎test/browser/specs/trace-timeline.test.ts‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ test('prints only the last steps of a long trace', async () => {
135135
`)
136136
})
137137

138-
test('prints trace timeline of the last retry', async () => {
138+
test('prints trace timeline of each attempt', async () => {
139139
const { stderr } = await runBrowserTests({
140140
'basic.test.ts': /* ts */ `
141141
import { expect, test } from 'vitest'
@@ -149,11 +149,9 @@ test('prints trace timeline of the last retry', async () => {
149149
`,
150150
})
151151

152-
// TODO: each attempt's error should print its own attempt's trace instead of the last one
153-
// https://github.com/vitest-dev/vitest/issues/11614
154152
expect(extractTimelines(stderr)).toMatchInlineSnapshot(`
155153
[
156-
"Trace (retry 1):
154+
"Trace:
157155
step locator start duration location
158156
click getByRole('button') +<time> <time> basic.test.ts:7",
159157
"Trace (retry 1):

0 commit comments

Comments
 (0)