Skip to content

Commit 417bdb4

Browse files
authored
fix(browser): init browsers eagerly when tests are running (#6876)
1 parent 32be0af commit 417bdb4

File tree

13 files changed

+83
-65
lines changed

13 files changed

+83
-65
lines changed

docs/guide/browser/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ export default defineConfig({
107107

108108
::: info
109109
Vitest assigns port `63315` to avoid conflicts with the development server, allowing you to run both in parallel. You can change that with the [`browser.api`](/config/#browser-api) option.
110+
111+
Since Vitest 2.1.5, CLI no longer prints the Vite URL automcatically. You can press "b" to print the URL when running in watch mode.
110112
:::
111113

112114
If you have not used Vite before, make sure you have your framework's plugin installed and specified in the config. Some frameworks might require extra configuration to work - check their Vite related documentation to be sure.

packages/browser/src/node/pool.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export function createBrowserPool(ctx: Vitest): ProcessPool {
131131
if (isCancelled) {
132132
break
133133
}
134+
await project.initBrowserProvider()
134135

135136
await executeTests(method, project, files)
136137
}

packages/browser/src/node/providers/preview.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { BrowserProvider, WorkspaceProject } from 'vitest/node'
33
export class PreviewBrowserProvider implements BrowserProvider {
44
public name = 'preview' as const
55
public supportsParallelism: boolean = false
6-
private ctx!: WorkspaceProject
6+
private project!: WorkspaceProject
77
private open = false
88

99
getSupportedBrowsers() {
@@ -19,25 +19,26 @@ export class PreviewBrowserProvider implements BrowserProvider {
1919
return {}
2020
}
2121

22-
async initialize(ctx: WorkspaceProject) {
23-
this.ctx = ctx
22+
async initialize(project: WorkspaceProject) {
23+
this.project = project
2424
this.open = false
25-
if (ctx.config.browser.headless) {
25+
if (project.config.browser.headless) {
2626
throw new Error(
2727
'You\'ve enabled headless mode for "preview" provider but it doesn\'t support it. Use "playwright" or "webdriverio" instead: https://vitest.dev/guide/browser/#configuration',
2828
)
2929
}
30+
project.ctx.logger.printBrowserBanner(project)
3031
}
3132

3233
async openPage(_contextId: string, url: string) {
3334
this.open = true
34-
if (!this.ctx.browser) {
35+
if (!this.project.browser) {
3536
throw new Error('Browser is not initialized')
3637
}
37-
const options = this.ctx.browser.vite.config.server
38+
const options = this.project.browser.vite.config.server
3839
const _open = options.open
3940
options.open = url
40-
this.ctx.browser.vite.openBrowser()
41+
this.project.browser.vite.openBrowser()
4142
options.open = _open
4243
}
4344

packages/vitest/src/node/core.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,6 @@ export class Vitest {
303303
return this.coverageProvider
304304
}
305305

306-
private async initBrowserProviders() {
307-
return Promise.all(this.projects.map(w => w.initBrowserProvider()))
308-
}
309-
310306
async mergeReports() {
311307
if (this.reporters.some(r => r instanceof BlobReporter)) {
312308
throw new Error('Cannot merge reports when `--reporter=blob` is used. Remove blob reporter from the config first.')
@@ -369,8 +365,6 @@ export class Vitest {
369365
async collect(filters?: string[]) {
370366
this._onClose = []
371367

372-
await this.initBrowserProviders()
373-
374368
const files = await this.filterTestsBySource(
375369
await this.globTestFiles(filters),
376370
)
@@ -402,7 +396,6 @@ export class Vitest {
402396
try {
403397
await this.initCoverageProvider()
404398
await this.coverageProvider?.clean(this.config.coverage.clean)
405-
await this.initBrowserProviders()
406399
}
407400
finally {
408401
await this.report('onInit', this)
@@ -445,7 +438,6 @@ export class Vitest {
445438
try {
446439
await this.initCoverageProvider()
447440
await this.coverageProvider?.clean(this.config.coverage.clean)
448-
await this.initBrowserProviders()
449441
}
450442
finally {
451443
await this.report('onInit', this)
@@ -693,6 +685,10 @@ export class Vitest {
693685
await Promise.all(this._onCancelListeners.splice(0).map(listener => listener(reason)))
694686
}
695687

688+
async initBrowserServers() {
689+
await Promise.all(this.projects.map(p => p.initBrowserServer()))
690+
}
691+
696692
async rerunFiles(files: string[] = this.state.getFilepaths(), trigger?: string, allTestsRun = true) {
697693
if (this.filenamePattern) {
698694
const filteredFiles = await this.globTestFiles([this.filenamePattern])

packages/vitest/src/node/logger.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { createLogUpdate } from 'log-update'
1212
import c from 'tinyrainbow'
1313
import { highlightCode } from '../utils/colors'
1414
import { printError } from './error'
15-
import { divider, withLabel } from './reporters/renderers/utils'
15+
import { divider, formatProjectName, withLabel } from './reporters/renderers/utils'
1616
import { RandomSequencer } from './sequencers/RandomSequencer'
1717

1818
export interface ErrorOptions {
@@ -217,21 +217,6 @@ export class Logger {
217217
this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`))
218218
}
219219

220-
this.ctx.projects.forEach((project) => {
221-
if (!project.browser) {
222-
return
223-
}
224-
const name = project.getName()
225-
const output = project.isCore() ? '' : ` [${name}]`
226-
227-
const resolvedUrls = project.browser.vite.resolvedUrls
228-
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0]
229-
const provider = project.browser.provider.name
230-
const providerString = provider === 'preview' ? '' : ` by ${provider}`
231-
232-
this.log(PAD + c.dim(c.green(`${output} Browser runner started${providerString} at ${new URL('/', origin)}`)))
233-
})
234-
235220
if (this.ctx.config.ui) {
236221
const host = this.ctx.config.api?.host || 'localhost'
237222
const port = this.ctx.server.config.server.port
@@ -260,6 +245,30 @@ export class Logger {
260245
}
261246
}
262247

248+
printBrowserBanner(project: WorkspaceProject) {
249+
if (!project.browser) {
250+
return
251+
}
252+
253+
const resolvedUrls = project.browser.vite.resolvedUrls
254+
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0]
255+
if (!origin) {
256+
return
257+
}
258+
259+
const name = project.getName()
260+
const output = project.isCore()
261+
? ''
262+
: formatProjectName(name)
263+
const provider = project.browser.provider.name
264+
const providerString = provider === 'preview' ? '' : ` by ${c.reset(c.bold(provider))}`
265+
this.log(
266+
c.dim(
267+
`${output}Browser runner started${providerString} ${c.dim('at')} ${c.blue(new URL('/', origin))}\n`,
268+
),
269+
)
270+
}
271+
263272
printUnhandledErrors(errors: unknown[]) {
264273
const errorMessage = c.red(
265274
c.bold(

packages/vitest/src/node/stdin.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const keys = [
1818
['p', 'filter by a filename'],
1919
['t', 'filter by a test name regex pattern'],
2020
['w', 'filter by a project name'],
21+
['b', 'start the browser server if not started yet'],
2122
['q', 'quit'],
2223
]
2324
const cancelKeys = ['space', 'c', 'h', ...keys.map(key => key[0]).flat()]
@@ -120,6 +121,14 @@ export function registerConsoleShortcuts(
120121
if (name === 'p') {
121122
return inputFilePattern()
122123
}
124+
if (name === 'b') {
125+
await ctx.initBrowserServers()
126+
ctx.projects.forEach((project) => {
127+
ctx.logger.log()
128+
ctx.logger.printBrowserBanner(project)
129+
})
130+
return null
131+
}
123132
}
124133

125134
async function keypressHandler(str: string, key: any) {

packages/vitest/src/node/workspace.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -358,16 +358,15 @@ export class WorkspaceProject {
358358
return testFiles
359359
}
360360

361-
async initBrowserServer(configFile: string | undefined) {
362-
if (!this.isBrowserEnabled()) {
361+
async initBrowserServer() {
362+
if (!this.isBrowserEnabled() || this.browser) {
363363
return
364364
}
365365
await this.ctx.packageInstaller.ensureInstalled('@vitest/browser', this.config.root, this.ctx.version)
366366
const { createBrowserServer, distRoot } = await import('@vitest/browser')
367-
await this.browser?.close()
368367
const browser = await createBrowserServer(
369368
this,
370-
configFile,
369+
this.server.config.configFile,
371370
[
372371
...MocksPlugins({
373372
filter(id) {
@@ -408,9 +407,7 @@ export class WorkspaceProject {
408407
}
409408

410409
static async createCoreProject(ctx: Vitest) {
411-
const project = WorkspaceProject.createBasicProject(ctx)
412-
await project.initBrowserServer(ctx.server.config.configFile)
413-
return project
410+
return WorkspaceProject.createBasicProject(ctx)
414411
}
415412

416413
async setServer(options: UserConfig, server: ViteDevServer) {
@@ -449,8 +446,6 @@ export class WorkspaceProject {
449446
return node.resolveId(id, importer)
450447
},
451448
})
452-
453-
await this.initBrowserServer(this.server.config.configFile)
454449
}
455450

456451
isBrowserEnabled(): boolean {
@@ -495,9 +490,12 @@ export class WorkspaceProject {
495490
}
496491

497492
async initBrowserProvider() {
498-
if (!this.isBrowserEnabled()) {
493+
if (!this.isBrowserEnabled() || this.browser?.provider) {
499494
return
500495
}
496+
if (!this.browser) {
497+
await this.initBrowserServer()
498+
}
501499
await this.browser?.initBrowserProvider()
502500
}
503501
}

test/browser/specs/runner.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { readFile } from 'node:fs/promises'
22
import { beforeAll, describe, expect, onTestFailed, test } from 'vitest'
3-
import { defaultBrowserPort } from 'vitest/config'
4-
import { browser, provider, runBrowserTests } from './utils'
3+
import { browser, runBrowserTests } from './utils'
54

65
describe('running browser tests', async () => {
76
let stderr: string
@@ -29,8 +28,6 @@ describe('running browser tests', async () => {
2928
console.error(stderr)
3029
})
3130

32-
expect(stdout).toContain(`Browser runner started by ${provider} at http://localhost:${defaultBrowserPort}/`)
33-
3431
expect(browserResultJson.testResults).toHaveLength(19)
3532
expect(passedTests).toHaveLength(17)
3633
expect(failedTests).toHaveLength(2)

test/browser/specs/server-url.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
import { afterEach, expect, test } from 'vitest'
2-
import { provider, runBrowserTests } from './utils'
2+
import { runBrowserTests } from './utils'
33

44
afterEach(() => {
55
delete process.env.TEST_HTTPS
66
})
77

88
test('server-url http', async () => {
9-
const { stdout, stderr } = await runBrowserTests({
9+
const { stderr, ctx } = await runBrowserTests({
1010
root: './fixtures/server-url',
11+
watch: true, // otherwise the browser is closed before we can get the url
1112
})
13+
const url = ctx?.projects[0].browser?.vite.resolvedUrls?.local[0]
1214
expect(stderr).toBe('')
13-
expect(stdout).toContain(`Browser runner started by ${provider} at http://localhost:51133/`)
15+
expect(url).toBe('http://localhost:51133/')
1416
})
1517

1618
test('server-url https', async () => {
1719
process.env.TEST_HTTPS = '1'
18-
const { stdout, stderr } = await runBrowserTests({
20+
const { stdout, stderr, ctx } = await runBrowserTests({
1921
root: './fixtures/server-url',
22+
watch: true, // otherwise the browser is closed before we can get the url
2023
})
2124
expect(stderr).toBe('')
22-
expect(stdout).toContain(`Browser runner started by ${provider} at https://localhost:51122/`)
25+
const url = ctx?.projects[0].browser?.vite.resolvedUrls?.local[0]
26+
expect(url).toBe('https://localhost:51122/')
2327
expect(stdout).toContain('Test Files 1 passed')
2428
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { test } from 'vitest';
2+
3+
test('passes')

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy