diff --git a/docs/config/index.md b/docs/config/index.md
index f8c9624455b8..4bc5ed6ab986 100644
--- a/docs/config/index.md
+++ b/docs/config/index.md
@@ -1065,17 +1065,30 @@ Beware that the global setup is running in a different global scope, so your tes
:::code-group
```js [globalSetup.js]
-export default function setup({ provide }) {
- provide('wsPort', 3000)
+export default function setup(project) {
+ project.provide('wsPort', 3000)
}
```
-```ts [globalSetup.ts]
+```ts [globalSetup.ts 2.0.0]
import type { GlobalSetupContext } from 'vitest/node'
export default function setup({ provide }: GlobalSetupContext) {
provide('wsPort', 3000)
}
+declare module 'vitest' {
+ export interface ProvidedContext {
+ wsPort: number
+ }
+}
+```
+```ts [globalSetup.ts 2.2.0]
+import type { TestProject } from 'vitest/node'
+
+export default function setup(project: TestProject) {
+ project.provide('wsPort', 3000)
+}
+
declare module 'vitest' {
export interface ProvidedContext {
wsPort: number
@@ -1089,13 +1102,13 @@ inject('wsPort') === 3000
```
:::
-Since Vitest 2.2.0, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing the tests.
+Since Vitest 2.2.0, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing tests. Note that you cannot destruct the `project` like `{ onTestsRerun }` because it relies on the context.
```ts
-import type { GlobalSetupContext } from 'vitest/node'
+import type { TestProject } from 'vitest/node'
-export default function setup({ onTestsRerun }: GlobalSetupContext) {
- onTestsRerun(async () => {
+export default function setup(project: TestProject) {
+ project.onTestsRerun(async () => {
await restartDb()
})
}
diff --git a/packages/vitest/src/node/globalSetup.ts b/packages/vitest/src/node/globalSetup.ts
index 295b8a862035..435dbbe19e55 100644
--- a/packages/vitest/src/node/globalSetup.ts
+++ b/packages/vitest/src/node/globalSetup.ts
@@ -1,29 +1,13 @@
import type { ViteNodeRunner } from 'vite-node/client'
-import type { OnTestsRerunHandler, ProvidedContext } from '../types/general'
-import type { ResolvedConfig } from './types/config'
+import type { TestProject } from './project'
import { toArray } from '@vitest/utils'
-export interface GlobalSetupContext {
- /**
- * Config of the current project.
- */
- config: ResolvedConfig
- /**
- * Provide a value to the test context. This value will be available to all tests via `inject`.
- */
- provide: (
- key: T,
- value: ProvidedContext[T]
- ) => void
- /**
- * Register a function that will be called before tests run again in watch mode.
- */
- onTestsRerun: (cb: OnTestsRerunHandler) => void
-}
+/** @deprecated use `TestProject` instead */
+export type GlobalSetupContext = TestProject
export interface GlobalSetupFile {
file: string
- setup?: (context: GlobalSetupContext) => Promise | void
+ setup?: (context: TestProject) => Promise | void
teardown?: Function
}
diff --git a/packages/vitest/src/node/project.ts b/packages/vitest/src/node/project.ts
index 23bf9566b6e5..e25c03992735 100644
--- a/packages/vitest/src/node/project.ts
+++ b/packages/vitest/src/node/project.ts
@@ -5,9 +5,10 @@ import type {
InlineConfig as ViteInlineConfig,
} from 'vite'
import type { Typechecker } from '../typecheck/typechecker'
-import type { ProvidedContext } from '../types/general'
+import type { OnTestsRerunHandler, ProvidedContext } from '../types/general'
import type { Vitest } from './core'
import type { GlobalSetupFile } from './globalSetup'
+import type { Logger } from './logger'
import type { BrowserServer } from './types/browser'
import type {
ResolvedConfig,
@@ -87,13 +88,15 @@ export class TestProject {
this.globalConfig = vitest.config
}
+ // "provide" is a property, not a method to keep the context when destructed in the global setup,
+ // making it a method would be a breaking change, and can be done in Vitest 3 at minimum
/**
* Provide a value to the test context. This value will be available to all tests with `inject`.
*/
- provide(
+ provide = (
key: T,
value: ProvidedContext[T],
- ): void {
+ ): void => {
try {
structuredClone(value)
}
@@ -217,11 +220,7 @@ export class TestProject {
)
for (const globalSetupFile of this._globalSetups) {
- const teardown = await globalSetupFile.setup?.({
- provide: (key, value) => this.provide(key, value),
- config: this.config,
- onTestsRerun: cb => this.vitest.onTestsRerun(cb),
- })
+ const teardown = await globalSetupFile.setup?.(this)
if (teardown == null || !!globalSetupFile.teardown) {
continue
}
@@ -234,13 +233,17 @@ export class TestProject {
}
}
+ onTestsRerun(cb: OnTestsRerunHandler): void {
+ this.vitest.onTestsRerun(cb)
+ }
+
/** @deprecated */
- teardownGlobalSetup() {
+ teardownGlobalSetup(): Promise {
return this._teardownGlobalSetup()
}
/** @internal */
- async _teardownGlobalSetup() {
+ async _teardownGlobalSetup(): Promise {
if (!this._globalSetups) {
return
}
@@ -250,7 +253,7 @@ export class TestProject {
}
/** @deprecated use `vitest.logger` instead */
- get logger() {
+ get logger(): Logger {
return this.vitest.logger
}
diff --git a/test/watch/fixtures/global-setup.ts b/test/watch/fixtures/global-setup.ts
index b86537e952dc..4d9c33792e65 100644
--- a/test/watch/fixtures/global-setup.ts
+++ b/test/watch/fixtures/global-setup.ts
@@ -1,12 +1,12 @@
-import { GlobalSetupContext } from 'vitest/node';
+import { TestProject } from 'vitest/node';
const calls: string[] = [];
(globalThis as any).__CALLS = calls
-export default ({ onTestsRerun }: GlobalSetupContext) => {
+export default (project: TestProject) => {
calls.push('start')
- onTestsRerun(() => {
+ project.onTestsRerun(() => {
calls.push('rerun')
})
return () => {