Skip to content

Commit e5b9a0b

Browse files
authored
feat(browser): do not reload the page during watch mode (#5810)
1 parent 3796dd7 commit e5b9a0b

File tree

18 files changed

+87
-30
lines changed

18 files changed

+87
-30
lines changed

packages/browser/src/client/client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import { parse, stringify } from 'flatted'
55
import type { VitestBrowserClientMocker } from './mocker'
66
import { getBrowserState } from './utils'
77

8+
const PAGE_TYPE = getBrowserState().type
9+
810
export const PORT = import.meta.hot ? '51204' : location.port
911
export const HOST = [location.hostname, PORT].filter(Boolean).join(':')
1012
export const SESSION_ID = crypto.randomUUID()
1113
export const ENTRY_URL = `${
1214
location.protocol === 'https:' ? 'wss:' : 'ws:'
13-
}//${HOST}/__vitest_browser_api__?type=${getBrowserState().type}&sessionId=${SESSION_ID}`
15+
}//${HOST}/__vitest_browser_api__?type=${PAGE_TYPE}&sessionId=${SESSION_ID}`
1416

1517
let setCancel = (_: CancelReason) => {}
1618
export const onCancel = new Promise<CancelReason>((resolve) => {
@@ -51,6 +53,11 @@ function createClient() {
5153
const exports = await mocker.resolve(id)
5254
return Object.keys(exports)
5355
},
56+
async createTesters(files: string[]) {
57+
if (PAGE_TYPE !== 'orchestrator')
58+
return
59+
getBrowserState().createTesters?.(files)
60+
},
5461
}, {
5562
post: msg => ctx.ws.send(msg),
5663
on: fn => (onMessage = fn),

packages/browser/src/client/orchestrator.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ const ID_ALL = '__vitest_all__'
1212

1313
const iframes = new Map<string, HTMLIFrameElement>()
1414

15+
let promiseTesters: Promise<void> | undefined
16+
getBrowserState().createTesters = async (files) => {
17+
await promiseTesters
18+
promiseTesters = createTesters(files).finally(() => {
19+
promiseTesters = undefined
20+
})
21+
await promiseTesters
22+
}
23+
1524
function debug(...args: unknown[]) {
1625
const debug = getConfig().env.VITEST_BROWSER_DEBUG
1726
if (debug && debug !== 'false')
@@ -20,7 +29,7 @@ function debug(...args: unknown[]) {
2029

2130
function createIframe(container: HTMLDivElement, file: string) {
2231
if (iframes.has(file)) {
23-
container.removeChild(iframes.get(file)!)
32+
iframes.get(file)!.remove()
2433
iframes.delete(file)
2534
}
2635

@@ -75,7 +84,6 @@ async function getContainer(config: ResolvedConfig): Promise<HTMLDivElement> {
7584
}
7685

7786
client.ws.addEventListener('open', async () => {
78-
const config = getConfig()
7987
const testFiles = getBrowserState().files
8088

8189
debug('test files', testFiles.join(', '))
@@ -86,7 +94,6 @@ client.ws.addEventListener('open', async () => {
8694
return
8795
}
8896

89-
const container = await getContainer(config)
9097
const runningFiles = new Set<string>(testFiles)
9198

9299
channel.addEventListener('message', async (e: MessageEvent<IframeChannelEvent>): Promise<void> => {
@@ -137,6 +144,13 @@ client.ws.addEventListener('open', async () => {
137144
}
138145
})
139146

147+
await createTesters(testFiles)
148+
})
149+
150+
async function createTesters(testFiles: string[]) {
151+
const config = getConfig()
152+
const container = await getContainer(config)
153+
140154
if (config.browser.ui) {
141155
container.className = ''
142156
container.textContent = ''
@@ -174,7 +188,7 @@ client.ws.addEventListener('open', async () => {
174188
})
175189
}
176190
}
177-
})
191+
}
178192

179193
function generateFileId(file: string) {
180194
const config = getConfig()

packages/browser/src/client/tester.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ async function prepareTestEnvironment(files: string[]) {
7474
worker: './browser.js',
7575
workerId: 1,
7676
config,
77-
projectName: config.name,
77+
projectName: config.name || '',
7878
files,
7979
environment: {
8080
name: 'browser',

packages/browser/src/client/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ interface BrowserRunnerState {
1616
config: ResolvedConfig
1717
type: 'tester' | 'orchestrator'
1818
wrapModule: <T>(module: () => T) => T
19-
runTests: (tests: string[]) => Promise<void>
19+
runTests?: (tests: string[]) => Promise<void>
20+
createTesters?: (files: string[]) => Promise<void>
2021
}
2122

2223
export function getBrowserState(): BrowserRunnerState {

packages/runner/src/types/tasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export interface Suite extends TaskBase {
6060

6161
export interface File extends Suite {
6262
filepath: string
63-
projectName: string
63+
projectName: string | undefined
6464
collectDuration?: number
6565
setupDuration?: number
6666
}

packages/ui/client/components/FileDetails.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import type { ModuleGraphData } from 'vitest'
3-
import { client, current, currentLogs, isReport, browserState } from '~/composables/client'
3+
import { client, current, currentLogs, isReport, browserState, config } from '~/composables/client'
44
import type { Params } from '~/composables/params'
55
import { viewMode } from '~/composables/params'
66
import type { ModuleGraph } from '~/composables/module-graph'
@@ -43,6 +43,13 @@ const consoleCount = computed(() => {
4343
function onDraft(value: boolean) {
4444
draft.value = value
4545
}
46+
47+
function relativeToRoot(path?: string) {
48+
if (!path) return ''
49+
if (path.startsWith(config.root))
50+
return path.slice(config.root.length)
51+
return path
52+
}
4653
</script>
4754

4855
<template>
@@ -54,7 +61,7 @@ function onDraft(value: boolean) {
5461
[{{ current?.file.projectName || '' }}]
5562
</div>
5663
<div flex-1 font-light op-50 ws-nowrap truncate text-sm>
57-
{{ current?.filepath }}
64+
{{ relativeToRoot(current?.filepath) }}
5865
</div>
5966
<div class="flex text-lg">
6067
<IconButton

packages/ui/client/components/TasksList.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ const filteredTests: ComputedRef<File[]> = computed(() => isFiltered.value ? fil
3636
const failed = computed(() => filtered.value.filter(task => task.result?.state === 'fail'))
3737
const success = computed(() => filtered.value.filter(task => task.result?.state === 'pass'))
3838
const skipped = computed(() => filtered.value.filter(task => task.mode === 'skip' || task.mode === 'todo'))
39-
const running = computed(() => filtered.value.filter(task =>
40-
!failed.value.includes(task)
41-
&& !success.value.includes(task)
42-
&& !skipped.value.includes(task),
43-
))
39+
const running = computed(() => filtered.value.filter(task => !task.result || task.result.state === 'run'))
4440
4541
const disableClearSearch = computed(() => search.value === '')
4642

packages/ui/client/pages/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function resizeMain() {
5050
<transition v-else>
5151
<Splitpanes key="detail" @resized="onModuleResized">
5252
<Pane :size="detailSizes[0]">
53-
<BrowserIframe />
53+
<BrowserIframe v-once />
5454
</Pane>
5555
<Pane :size="detailSizes[1]">
5656
<Dashboard v-if="dashboardVisible" key="summary" />

packages/vitest/src/api/setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export function setup(ctx: Vitest, _server?: ViteDevServer) {
9191
async getTestFiles() {
9292
const spec = await ctx.globTestFiles()
9393
return spec.map(([project, file]) => [{
94-
name: project.getName(),
94+
name: project.config.name,
9595
root: project.config.root,
9696
}, file])
9797
},

packages/vitest/src/api/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface WebSocketEvents extends Pick<Reporter, 'onCollected' | 'onFinis
6262
export interface WebSocketBrowserEvents {
6363
onCancel: (reason: CancelReason) => void
6464
startMocking: (id: string) => Promise<string[]>
65+
createTesters: (files: string[]) => Promise<void>
6566
}
6667

6768
export type WebSocketRPC = BirpcReturn<WebSocketEvents, WebSocketHandlers>

0 commit comments

Comments
 (0)