Skip to content

Commit 1bf27f0

Browse files
authoredDec 9, 2024··
feat(ui): Make clicking on a test in the UI open the report section and scroll to the test failure if applicable (#6900)
1 parent f691ad7 commit 1bf27f0

File tree

7 files changed

+45
-16
lines changed

7 files changed

+45
-16
lines changed
 

‎packages/ui/client/auto-imports.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ declare global {
118118
const resolveComponent: typeof import('vue')['resolveComponent']
119119
const resolveRef: typeof import('@vueuse/core')['resolveRef']
120120
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
121+
const selectedTest: typeof import('./composables/params')['selectedTest']
121122
const setIframeViewport: typeof import('./composables/api')['setIframeViewport']
122123
const shallowReactive: typeof import('vue')['shallowReactive']
123124
const shallowReadonly: typeof import('vue')['shallowReadonly']
@@ -127,6 +128,7 @@ declare global {
127128
const showDashboard: typeof import('./composables/navigation')['showDashboard']
128129
const showLine: typeof import('./composables/codemirror')['showLine']
129130
const showNavigationPanel: typeof import('./composables/navigation')['showNavigationPanel']
131+
const showReport: typeof import('./composables/navigation')['showReport']
130132
const showRightPanel: typeof import('./composables/navigation')['showRightPanel']
131133
const showSource: typeof import('./composables/codemirror')['showSource']
132134
const syncRef: typeof import('@vueuse/core')['syncRef']

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {
1111
coverageVisible,
1212
dashboardVisible,
1313
disableCoverage,
14-
navigateTo,
1514
showCoverage,
1615
showDashboard,
16+
showReport,
1717
} from '~/composables/navigation'
1818
1919
function updateSnapshot() {
@@ -50,7 +50,7 @@ function expandTests() {
5050

5151
<template>
5252
<!-- TODO: have test tree so the folders are also nested: test -> filename -> suite -> test -->
53-
<Explorer border="r base" :on-item-click="navigateTo" :nested="true" @run="onRunAll">
53+
<Explorer border="r base" :on-item-click="showReport" :nested="true" @run="onRunAll">
5454
<template #header="{ filteredFiles }">
5555
<img w-6 h-6 src="/favicon.svg" alt="Vitest logo">
5656
<span font-light text-sm flex-1>Vitest</span>

‎packages/ui/client/components/explorer/ExplorerItem.vue

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const failedSnapshot = computed(() => {
5757
5858
function toggleOpen() {
5959
if (!expandable) {
60+
onItemClick?.(task.value!)
6061
return
6162
}
6263

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ErrorWithDiff, File, Suite, Task } from 'vitest'
44
import { browserState, config } from '~/composables/client'
55
import { isDark } from '~/composables/dark'
66
import { createAnsiToHtmlFilter } from '~/composables/error'
7+
import { selectedTest } from '~/composables/params'
78
import { escapeHtml } from '~/utils/escape'
89
910
const props = defineProps<{
@@ -127,12 +128,24 @@ function showScreenshotModal(task: Task) {
127128
timestamp.value = Date.now()
128129
showScreenshot.value = true
129130
}
131+
132+
watch(() => [selectedTest.value] as const, ([test]) => {
133+
if (test != null) {
134+
// Have to wrap the selector in [id=''] since #{test} will produce an invalid selector because the test ID is a number
135+
const testElement = document.querySelector(`[id='${test}'`)
136+
if (testElement != null) {
137+
nextTick(() => {
138+
testElement.scrollIntoView()
139+
})
140+
}
141+
}
142+
}, { flush: 'post' })
130143
</script>
131144

132145
<template>
133146
<div h-full class="scrolls">
134147
<template v-if="failed.length">
135-
<div v-for="task of failed" :key="task.id">
148+
<div v-for="task of failed" :id="task.id" :key="task.id">
136149
<div
137150
bg="red-500/10"
138151
text="red-500 sm"

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,10 @@ export function useCodeMirror(
6262
}
6363

6464
export async function showSource(task: Task) {
65-
navigateTo(task, task.location?.line ?? 0)
65+
navigateTo({
66+
file: task.file.id,
67+
line: task.location?.line ?? 0,
68+
view: 'editor',
69+
test: null,
70+
})
6671
}

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

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { File, Task } from '@vitest/runner'
2+
import type { Params } from './params'
23
import { client, config, findById } from './client'
34
import { testRunState } from './client/state'
4-
import { activeFileId, lineNumber, viewMode } from './params'
5+
import { activeFileId, lineNumber, selectedTest, viewMode } from './params'
56

67
export const currentModule = ref<File>()
78
export const dashboardVisible = ref(true)
@@ -99,20 +100,24 @@ export function showDashboard(show: boolean) {
99100
}
100101
}
101102

102-
export function navigateTo(task: Task, line: number | null = null) {
103-
activeFileId.value = task.file.id
104-
// reset line number
105-
lineNumber.value = null
106-
if (line != null) {
107-
nextTick(() => {
108-
lineNumber.value = line
109-
})
110-
viewMode.value = 'editor'
111-
}
112-
currentModule.value = findById(task.file.id)
103+
export function navigateTo({ file, line, view, test }: Params) {
104+
activeFileId.value = file
105+
lineNumber.value = line
106+
viewMode.value = view
107+
selectedTest.value = test
108+
currentModule.value = findById(file)
113109
showDashboard(false)
114110
}
115111

112+
export function showReport(task: Task) {
113+
navigateTo({
114+
file: task.file.id,
115+
test: task.type === 'test' ? task.id : null,
116+
line: null,
117+
view: null,
118+
})
119+
}
120+
116121
export function showCoverage() {
117122
coverageVisible.value = true
118123
dashboardVisible.value = false

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

+3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ export interface Params {
22
file: string
33
view: null | 'graph' | 'editor' | 'console'
44
line: null | number
5+
test: null | string
56
}
67

78
export const params = useUrlSearchParams<Params>('hash', {
89
initialValue: {
910
file: '',
1011
view: null,
1112
line: null,
13+
test: null,
1214
},
1315
})
1416

1517
export const activeFileId = toRef(params, 'file')
1618
export const viewMode = toRef(params, 'view')
1719
export const lineNumber = toRef(params, 'line')
20+
export const selectedTest = toRef(params, 'test')

0 commit comments

Comments
 (0)
Please sign in to comment.