Skip to content

Commit 602d215

Browse files
dvmhmdsdhi-ogawaOpenCode (gpt-5.6-sol)
authored
fix(ui): add suite level report view (#11038)
Co-authored-by: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Co-authored-by: OpenCode (gpt-5.6-sol) <noreply@opencode.ai> Co-authored-by: Hiroshi Ogawa <hi.ogawa.zz@gmail.com>
1 parent d4fe198 commit 602d215

8 files changed

Lines changed: 127 additions & 79 deletions

File tree

‎packages/ui/client/components/FileDetails.vue‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import type { RunnerTask, RunnerTestCase } from 'vitest'
2+
import type { RunnerTask } from 'vitest'
33
import type { Params } from '~/composables/params'
44
import { computed, ref } from 'vue'
55
import DetailsHeaderButtons from '~/components/DetailsHeaderButtons.vue'
@@ -25,10 +25,10 @@ import ViewTestReport from './views/ViewTestReport.vue'
2525
2626
const draft = ref(false)
2727
28-
const test = computed(() => {
29-
return selectedTest.value
30-
? client.state.idMap.get(selectedTest.value) as RunnerTestCase
31-
: undefined
28+
const selectedTask = computed(() => {
29+
return (selectedTest.value
30+
? client.state.idMap.get(selectedTest.value)
31+
: undefined) ?? current.value
3232
})
3333
3434
const failedSnapshot = computed(() => {
@@ -212,8 +212,10 @@ const tags = computed(() => {
212212
:file="current"
213213
data-testid="console"
214214
/>
215-
<ViewReport v-else-if="!viewMode && !test && current" :file="current" data-testid="report" />
216-
<ViewTestReport v-else-if="!viewMode && test" :test="test" data-testid="report" />
215+
<template v-else-if="!viewMode && selectedTask">
216+
<ViewTestReport v-if="selectedTask.type === 'test'" :test="selectedTask" data-testid="report" />
217+
<ViewReport v-else :suite="selectedTask" data-testid="report" />
218+
</template>
217219
</div>
218220
</div>
219221
</template>

‎packages/ui/client/components/views/ViewReport.spec.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe.todo('ViewReport', () => {
5757
beforeEach(async () => {
5858
await render(ViewReport, {
5959
props: {
60-
file: fileWithTextStacks,
60+
suite: fileWithTextStacks,
6161
},
6262
attrs: {
6363
'data-testid': viewReportTestId,
@@ -100,7 +100,7 @@ describe.todo('ViewReport', () => {
100100
],
101101
}
102102
const container = await render(ViewReport, {
103-
props: { file },
103+
props: { suite: file },
104104
})
105105
const taskError = container.getByTestId(taskErrorTestId)
106106
const preElements = taskError.element().querySelectorAll('pre')
@@ -149,7 +149,7 @@ describe.todo('ViewReport', () => {
149149
],
150150
}
151151
const container = await render(ViewReport, {
152-
props: { file },
152+
props: { suite: file },
153153
})
154154
const taskError = container.getByTestId(taskErrorTestId)
155155
const preElements = taskError.element().querySelectorAll('pre')
@@ -193,7 +193,7 @@ describe.todo('ViewReport', () => {
193193
it('test diff display', async () => {
194194
const component = await render(ViewReport, {
195195
props: {
196-
file: fileWithTextStacks,
196+
suite: fileWithTextStacks,
197197
},
198198
})
199199

‎packages/ui/client/components/views/ViewReport.vue‎

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import FailureScreenshot from '../FailureScreenshot.vue'
66
import ViewReportError from './ViewReportError.vue'
77
88
const props = defineProps<{
9-
file: RunnerTestFile
9+
suite: RunnerTestFile | RunnerTestSuite
1010
}>()
1111
1212
type LeveledTask = RunnerTask & {
@@ -30,29 +30,21 @@ function collectFailed(task: RunnerTask, level: number): LeveledTask[] {
3030
}
3131
3232
const failed = computed(() => {
33-
const file = props.file
34-
const failedFlatMap = file.tasks?.flatMap(t => collectFailed(t, 0)) ?? []
35-
const result = file.result
36-
const fileError = result?.errors?.[0]
37-
// we must check also if the test cannot compile
38-
if (fileError) {
39-
// create a dummy one
40-
const fileErrorTask: RunnerTestSuite & { level: number } = {
41-
id: file!.id,
42-
file: file!,
43-
name: file!.name,
44-
fullName: file!.name,
33+
const suite = props.suite
34+
const failedFlatMap = suite.tasks.flatMap(t => collectFailed(t, 0))
35+
// prepend suite level errors as same indent level as children errors
36+
if (suite.result?.errors?.length) {
37+
const taskError: LeveledTask = {
38+
...suite,
4539
level: 0,
46-
type: 'suite',
47-
mode: 'run',
48-
meta: {},
4940
tasks: [],
50-
result,
5141
}
52-
failedFlatMap.unshift(fileErrorTask)
42+
failedFlatMap.unshift(taskError)
5343
}
5444
return failedFlatMap
5545
})
46+
47+
const isFile = computed(() => 'filepath' in props.suite)
5648
</script>
5749

5850
<template>
@@ -78,17 +70,17 @@ const failed = computed(() => {
7870
v-for="(error, idx) of task.result.errors"
7971
:key="idx"
8072
:error="error"
81-
:filename="file.name"
73+
:filename="task.file.name"
8274
:root="config.root"
83-
:file-id="file.id"
75+
:file-id="task.file.id"
8476
/>
8577
</template>
8678
</div>
8779
</div>
8880
</template>
8981
<template v-else>
9082
<div bg="green-500/10" text="green-500 sm" p="x4 y2" m-2 rounded>
91-
All tests passed in this file
83+
All tests passed in this {{ isFile ? 'file' : 'suite' }}
9284
</div>
9385
</template>
9486
</div>

‎packages/ui/client/composables/navigation.ts‎

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,24 +127,14 @@ export function navigateTo({ file, line, view, test, column }: Omit<Params, 'tra
127127
}
128128

129129
export function clickOnTask(task: Task) {
130-
if (task.type === 'test') {
131-
if (viewMode.value === 'editor') {
132-
showTaskSource(task)
133-
}
134-
else {
135-
navigateTo({
136-
file: task.file.id,
137-
line: null,
138-
column: null,
139-
view: viewMode.value,
140-
test: task.id,
141-
})
142-
}
130+
const isFile = 'filepath' in task
131+
if (!isFile && viewMode.value === 'editor') {
132+
showTaskSource(task)
143133
}
144134
else {
145135
navigateTo({
146136
file: task.file.id,
147-
test: null,
137+
test: isFile ? null : task.id,
148138
line: null,
149139
view: viewMode.value,
150140
column: null,

‎packages/ui/client/composables/params.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { toRef, useUrlSearchParams } from '@vueuse/core'
22

33
export interface Params {
4+
// File.id
45
file: string
56
view: null | 'graph' | 'editor' | 'console'
67
line: null | number
8+
// Task.id of either Test or Suite (but not File)
79
test: null | string
810
column: null | number
911
traceAttempt: null | string
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { beforeAll, describe, expect, it } from 'vitest'
2+
3+
describe('successful suite', () => {
4+
it('successful child', () => {
5+
expect(true).toBe(true)
6+
})
7+
})
8+
9+
describe('hook failure suite', () => {
10+
beforeAll(() => {
11+
throw new Error('before-all-marker')
12+
})
13+
14+
it('blocked child', () => {})
15+
})
16+
17+
describe('child failure suite', () => {
18+
it('failing child', () => {
19+
throw new Error('direct-child-marker')
20+
})
21+
})
22+
23+
describe('nested failure suite', () => {
24+
describe('failing nested suite', () => {
25+
it('failing nested child', () => {
26+
throw new Error('nested-child-marker')
27+
})
28+
})
29+
})

‎test/ui/test/helper.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ export async function startHtmlReportPreview(
5656
}
5757
}
5858

59-
export async function assertTestCounts(page: Page, { pass, fail }: { pass: number; fail: number }) {
59+
export async function assertTestCounts(page: Page, { pass, fail, skip = 0 }: { pass: number; fail: number; skip?: number }) {
60+
const skipped = skip ? ` ${skip} Skip` : ''
6061
await expect
6162
.soft(page.getByTestId('tests-entry'))
6263
.toContainText(
63-
`${pass} Pass ${fail} Fail ${pass + fail} Total`,
64+
`${pass} Pass ${fail} Fail${skipped} ${pass + fail + skip} Total`,
6465
)
6566
}
6667

0 commit comments

Comments
 (0)