[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

feat(ui): improve summary and update all snapshots (#593)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>

authored by

Michel EDIGHOFFER
Anthony Fu
and committed by
GitHub
(Jan 22, 2022, 3:58 AM +0800) c23be109 d0440b60

+52 -12
+2
packages/ui/types.ts
··· 9 9 */ 10 10 data: any 11 11 } 12 + 13 + export type RunState = 'idle' | 'running'
+3
packages/ws-client/src/index.ts
··· 60 60 onUserConsoleLog(log) { 61 61 ctx.state.updateUserLog(log) 62 62 }, 63 + onFinished(files) { 64 + handlers.onFinished?.(files) 65 + }, 63 66 }, 64 67 { 65 68 post: msg => ctx.ws.send(msg),
+12 -1
packages/ui/client/components/Navigation.vue
··· 1 1 <script setup lang="ts"> 2 + import { hasFailedSnapshot } from '@vitest/ws-client' 2 3 import { currentModule, dashboardVisible, showDashboard } from '../composables/navigation' 3 - import { findById } from '../composables/client' 4 + import { client, findById } from '../composables/client' 4 5 import type { Task } from '#types' 5 6 import { isDark, toggleDark } from '~/composables' 6 7 import { files, runAll } from '~/composables/client' 7 8 import { activeFileId } from '~/composables/params' 9 + 10 + const failedSnapshot = computed(() => files.value && hasFailedSnapshot(files.value)) 11 + const updateSnapshot = () => client.rpc.updateSnapshot() 8 12 9 13 function onItemClick(task: Task) { 10 14 activeFileId.value = task.id ··· 12 16 showDashboard(false) 13 17 } 14 18 const toggleMode = computed(() => isDark.value ? 'light' : 'dark') 19 + 15 20 </script> 16 21 17 22 <template> ··· 28 33 animate-count-1 29 34 icon="i-carbon-dashboard" 30 35 @click="showDashboard(true)" 36 + /> 37 + <IconButton 38 + v-if="failedSnapshot" 39 + v-tooltip.bottom="'Update all failed snapshot(s)'" 40 + icon="i-carbon-result-old" 41 + @click="updateSnapshot()" 31 42 /> 32 43 <IconButton 33 44 v-tooltip.bottom="filteredTests ? (filteredTests.length === 0 ? 'No test to run (clear filter)' : 'Rerun filtered') : 'Rerun all'"
+1 -1
packages/ui/client/components/Suites.vue
··· 17 17 <div class="flex text-lg"> 18 18 <IconButton 19 19 v-if="failedSnapshot" 20 - v-tooltip.bottom="'Update failed snapshots'" 20 + v-tooltip.bottom="`Update failed snapshot(s) of ${current.name}`" 21 21 icon="i-carbon-result-old" 22 22 @click="updateSnapshot()" 23 23 />
+5 -4
packages/ui/client/components/TasksList.vue
··· 1 1 <script setup lang="ts"> 2 2 import type { ComputedRef } from 'vue' 3 3 import type { File, Task } from '#types' 4 - import { findById } from '~/composables/client' 4 + import { findById, testRunState } from '~/composables/client' 5 5 import { activeFileId } from '~/composables/params' 6 6 7 7 const props = withDefaults(defineProps<{ ··· 38 38 && !success.value.includes(task) 39 39 && !skipped.value.includes(task), 40 40 )) 41 + const throttledRunning = useThrottle(running, 250) 41 42 </script> 42 43 43 44 <script lang="ts"> ··· 94 95 :on-item-click="onItemClick" 95 96 /> 96 97 </DetailsPanel> 97 - <DetailsPanel v-if="running.length"> 98 + <DetailsPanel v-if="running.length || testRunState === 'running'"> 98 99 <template #summary> 99 100 <div text-yellow5> 100 - RUNNING ({{ running.length }}) 101 + RUNNING ({{ throttledRunning.length }}) 101 102 </div> 102 103 </template> 103 104 <TaskTree 104 - v-for="task in running" 105 + v-for="task in throttledRunning" 105 106 :key="task.id" 106 107 :task="task" 107 108 :nested="nested"
+12
packages/ui/client/composables/client.ts
··· 1 1 import { createClient, getTasks } from '@vitest/ws-client' 2 2 import type { WebSocketStatus } from '@vueuse/core' 3 + import type { Ref } from 'vue' 3 4 import { reactive } from 'vue' 5 + import type { RunState } from '../../types' 4 6 import { activeFileId } from './params' 5 7 import type { File, ResolvedConfig } from '#types' 6 8 ··· 8 10 export const HOST = [location.hostname, PORT].filter(Boolean).join(':') 9 11 export const ENTRY_URL = `${location.protocol === 'https:' ? 'wss:' : 'ws:'}//${HOST}/__vitest_api__` 10 12 13 + export const testRunState: Ref<RunState> = ref('idle') 14 + 11 15 export const client = createClient(ENTRY_URL, { 12 16 reactive: reactive as any, 17 + handlers: { 18 + onTaskUpdate() { 19 + testRunState.value = 'running' 20 + }, 21 + onFinished() { 22 + testRunState.value = 'idle' 23 + }, 24 + }, 13 25 }) 14 26 15 27 export const config = shallowRef<ResolvedConfig>({} as any)
+2 -2
packages/ui/client/composables/summary.ts
··· 1 1 import { hasFailedSnapshot } from '@vitest/ws-client' 2 2 import type { Task, Test } from 'vitest/src' 3 - import { files } from '~/composables/client' 3 + import { files, testRunState } from '~/composables/client' 4 4 5 5 type Nullable<T> = T | null | undefined 6 6 type Arrayable<T> = T | Array<T> ··· 17 17 export const filesSkipped = computed(() => filesIgnore.value.filter(f => f.mode === 'skip')) 18 18 export const filesSnapshotFailed = computed(() => files.value.filter(hasFailedSnapshot)) 19 19 export const filesTodo = computed(() => filesIgnore.value.filter(f => f.mode === 'todo')) 20 - export const finished = computed(() => filesRunning.value.length === 0) 20 + export const finished = computed(() => testRunState.value === 'idle') 21 21 // tests 22 22 export const tests = computed(() => { 23 23 return getTests(files.value)
+8 -1
packages/vitest/src/api/setup.ts
··· 93 93 inlined: Array.from(inlined), 94 94 } 95 95 }, 96 - updateSnapshot(file: File) { 96 + updateSnapshot(file?: File) { 97 + if (!file) return ctx.updateSnapshot() 97 98 return ctx.updateSnapshot([file.filepath]) 98 99 }, 99 100 }, ··· 142 143 143 144 this.clients.forEach((client) => { 144 145 client.onTaskUpdate?.(packs) 146 + }) 147 + } 148 + 149 + onFinished(files?: File[] | undefined) { 150 + this.clients.forEach((client) => { 151 + client.onFinished?.(files) 145 152 }) 146 153 } 147 154
+2 -2
packages/vitest/src/api/types.ts
··· 13 13 readFile(id: string): Promise<string> 14 14 writeFile(id: string, content: string): Promise<void> 15 15 rerun(files: string[]): Promise<void> 16 - updateSnapshot(file: File): Promise<void> 16 + updateSnapshot(file?: File): Promise<void> 17 17 } 18 18 19 - export interface WebSocketEvents extends Pick<Reporter, 'onCollected' | 'onTaskUpdate' | 'onUserConsoleLog'> { 19 + export interface WebSocketEvents extends Pick<Reporter, 'onCollected' | 'onFinished' | 'onTaskUpdate' | 'onUserConsoleLog'> { 20 20 }
+3
packages/vitest/src/node/pool.ts
··· 138 138 ctx.state.updateUserLog(log) 139 139 ctx.report('onUserConsoleLog', log) 140 140 }, 141 + onFinished(files) { 142 + ctx.report('onFinished', files) 143 + }, 141 144 }, 142 145 { 143 146 post(v) {
+1 -1
packages/vitest/src/runtime/worker.ts
··· 67 67 rpc: createBirpc<WorkerRPC>( 68 68 {}, 69 69 { 70 - eventNames: ['onUserConsoleLog', 'onCollected', 'onWorkerExit'], 70 + eventNames: ['onUserConsoleLog', 'onFinished', 'onCollected', 'onWorkerExit'], 71 71 post(v) { port.postMessage(v) }, 72 72 on(fn) { port.addListener('message', fn) }, 73 73 },
+1
packages/vitest/src/types/worker.ts
··· 21 21 resolveId: ResolveIdFunction 22 22 getSourceMap: (id: string, force?: boolean) => Promise<RawSourceMap | undefined> 23 23 24 + onFinished: (files: File[]) => void 24 25 onWorkerExit: (code?: number) => void 25 26 onUserConsoleLog: (log: UserConsoleLog) => void 26 27 onCollected: (files: File[]) => void