@vitest-agent/mcp 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +1 -2
  2. package/index.d.ts +2 -2
  3. package/index.js +1 -1
  4. package/package.json +1 -1
  5. package/server.js +2 -4
  6. package/patterns/_meta.json +0 -67
  7. package/patterns/authoring-a-custom-vitest-agent-reporter.md +0 -82
  8. package/patterns/known-issues-and-caveats.md +0 -52
  9. package/patterns/operating-vitest-agent-as-an-agent.md +0 -62
  10. package/patterns/running-tests-via-mcp.md +0 -103
  11. package/patterns/silencing-leaking-output-in-tests.md +0 -91
  12. package/patterns/testing-effect-schema-definitions.md +0 -71
  13. package/patterns/testing-effect-services-with-mock-layers.md +0 -63
  14. package/resources/index.js +0 -166
  15. package/resources/indexes.js +0 -77
  16. package/resources/manifest-schema.js +0 -46
  17. package/resources/paths.js +0 -20
  18. package/resources/patterns.js +0 -22
  19. package/resources/upstream-docs.js +0 -22
  20. package/vendor/vitest-docs/ATTRIBUTION.md +0 -5
  21. package/vendor/vitest-docs/api/advanced/artifacts.md +0 -189
  22. package/vendor/vitest-docs/api/advanced/metadata.md +0 -68
  23. package/vendor/vitest-docs/api/advanced/plugin.md +0 -168
  24. package/vendor/vitest-docs/api/advanced/reporters.md +0 -342
  25. package/vendor/vitest-docs/api/advanced/runner.md +0 -334
  26. package/vendor/vitest-docs/api/advanced/test-case.md +0 -302
  27. package/vendor/vitest-docs/api/advanced/test-collection.md +0 -89
  28. package/vendor/vitest-docs/api/advanced/test-module.md +0 -140
  29. package/vendor/vitest-docs/api/advanced/test-project.md +0 -321
  30. package/vendor/vitest-docs/api/advanced/test-specification.md +0 -96
  31. package/vendor/vitest-docs/api/advanced/test-suite.md +0 -230
  32. package/vendor/vitest-docs/api/advanced/vitest.md +0 -684
  33. package/vendor/vitest-docs/api/assert-type.md +0 -22
  34. package/vendor/vitest-docs/api/assert.md +0 -1960
  35. package/vendor/vitest-docs/api/browser/assertions.md +0 -1277
  36. package/vendor/vitest-docs/api/browser/commands.md +0 -154
  37. package/vendor/vitest-docs/api/browser/context.md +0 -338
  38. package/vendor/vitest-docs/api/browser/interactivity.md +0 -681
  39. package/vendor/vitest-docs/api/browser/locators.md +0 -1171
  40. package/vendor/vitest-docs/api/browser/react.md +0 -346
  41. package/vendor/vitest-docs/api/browser/svelte.md +0 -292
  42. package/vendor/vitest-docs/api/browser/vue.md +0 -222
  43. package/vendor/vitest-docs/api/describe.md +0 -374
  44. package/vendor/vitest-docs/api/expect-typeof.md +0 -571
  45. package/vendor/vitest-docs/api/expect.md +0 -2304
  46. package/vendor/vitest-docs/api/hooks.md +0 -463
  47. package/vendor/vitest-docs/api/mock.md +0 -701
  48. package/vendor/vitest-docs/api/test.md +0 -926
  49. package/vendor/vitest-docs/api/vi.md +0 -1372
  50. package/vendor/vitest-docs/config/alias.md +0 -13
  51. package/vendor/vitest-docs/config/allowonly.md +0 -32
  52. package/vendor/vitest-docs/config/api.md +0 -27
  53. package/vendor/vitest-docs/config/attachmentsdir.md +0 -6
  54. package/vendor/vitest-docs/config/bail.md +0 -9
  55. package/vendor/vitest-docs/config/benchmark.md +0 -65
  56. package/vendor/vitest-docs/config/browser/api.md +0 -23
  57. package/vendor/vitest-docs/config/browser/commands.md +0 -6
  58. package/vendor/vitest-docs/config/browser/connecttimeout.md +0 -10
  59. package/vendor/vitest-docs/config/browser/detailspanelposition.md +0 -38
  60. package/vendor/vitest-docs/config/browser/enabled.md +0 -40
  61. package/vendor/vitest-docs/config/browser/expect.md +0 -250
  62. package/vendor/vitest-docs/config/browser/headless.md +0 -7
  63. package/vendor/vitest-docs/config/browser/instances.md +0 -47
  64. package/vendor/vitest-docs/config/browser/isolate.md +0 -11
  65. package/vendor/vitest-docs/config/browser/locators.md +0 -24
  66. package/vendor/vitest-docs/config/browser/orchestratorscripts.md +0 -39
  67. package/vendor/vitest-docs/config/browser/playwright.md +0 -214
  68. package/vendor/vitest-docs/config/browser/preview.md +0 -32
  69. package/vendor/vitest-docs/config/browser/provider.md +0 -79
  70. package/vendor/vitest-docs/config/browser/screenshotdirectory.md +0 -6
  71. package/vendor/vitest-docs/config/browser/screenshotfailures.md +0 -6
  72. package/vendor/vitest-docs/config/browser/testerhtmlpath.md +0 -5
  73. package/vendor/vitest-docs/config/browser/trace.md +0 -43
  74. package/vendor/vitest-docs/config/browser/trackunhandlederrors.md +0 -10
  75. package/vendor/vitest-docs/config/browser/ui.md +0 -7
  76. package/vendor/vitest-docs/config/browser/viewport.md +0 -6
  77. package/vendor/vitest-docs/config/browser/webdriverio.md +0 -64
  78. package/vendor/vitest-docs/config/cache.md +0 -26
  79. package/vendor/vitest-docs/config/chaiconfig.md +0 -29
  80. package/vendor/vitest-docs/config/clearmocks.md +0 -22
  81. package/vendor/vitest-docs/config/coverage.md +0 -455
  82. package/vendor/vitest-docs/config/css.md +0 -47
  83. package/vendor/vitest-docs/config/dangerouslyignoreunhandlederrors.md +0 -23
  84. package/vendor/vitest-docs/config/deps.md +0 -127
  85. package/vendor/vitest-docs/config/detectasyncleaks.md +0 -39
  86. package/vendor/vitest-docs/config/diff.md +0 -96
  87. package/vendor/vitest-docs/config/dir.md +0 -7
  88. package/vendor/vitest-docs/config/disableconsoleintercept.md +0 -15
  89. package/vendor/vitest-docs/config/env.md +0 -5
  90. package/vendor/vitest-docs/config/environment.md +0 -96
  91. package/vendor/vitest-docs/config/environmentoptions.md +0 -30
  92. package/vendor/vitest-docs/config/exclude.md +0 -49
  93. package/vendor/vitest-docs/config/execargv.md +0 -10
  94. package/vendor/vitest-docs/config/expandsnapshotdiff.md +0 -7
  95. package/vendor/vitest-docs/config/expect.md +0 -38
  96. package/vendor/vitest-docs/config/experimental.md +0 -510
  97. package/vendor/vitest-docs/config/faketimers.md +0 -51
  98. package/vendor/vitest-docs/config/fileparallelism.md +0 -11
  99. package/vendor/vitest-docs/config/forcereruntriggers.md +0 -19
  100. package/vendor/vitest-docs/config/globals.md +0 -42
  101. package/vendor/vitest-docs/config/globalsetup.md +0 -72
  102. package/vendor/vitest-docs/config/hideskippedtests.md +0 -7
  103. package/vendor/vitest-docs/config/hooktimeout.md +0 -7
  104. package/vendor/vitest-docs/config/include-source.md +0 -115
  105. package/vendor/vitest-docs/config/include.md +0 -71
  106. package/vendor/vitest-docs/config/includetasklocation.md +0 -17
  107. package/vendor/vitest-docs/config/index.md +0 -85
  108. package/vendor/vitest-docs/config/isolate.md +0 -13
  109. package/vendor/vitest-docs/config/logheapusage.md +0 -7
  110. package/vendor/vitest-docs/config/maxconcurrency.md +0 -9
  111. package/vendor/vitest-docs/config/maxworkers.md +0 -49
  112. package/vendor/vitest-docs/config/mockreset.md +0 -22
  113. package/vendor/vitest-docs/config/mode.md +0 -7
  114. package/vendor/vitest-docs/config/name.md +0 -111
  115. package/vendor/vitest-docs/config/onconsolelog.md +0 -25
  116. package/vendor/vitest-docs/config/onstacktrace.md +0 -32
  117. package/vendor/vitest-docs/config/onunhandlederror.md +0 -35
  118. package/vendor/vitest-docs/config/open.md +0 -7
  119. package/vendor/vitest-docs/config/outputfile.md +0 -7
  120. package/vendor/vitest-docs/config/passwithnotests.md +0 -7
  121. package/vendor/vitest-docs/config/pool.md +0 -45
  122. package/vendor/vitest-docs/config/printconsoletrace.md +0 -6
  123. package/vendor/vitest-docs/config/projects.md +0 -6
  124. package/vendor/vitest-docs/config/provide.md +0 -45
  125. package/vendor/vitest-docs/config/reporters.md +0 -69
  126. package/vendor/vitest-docs/config/resolvesnapshotpath.md +0 -36
  127. package/vendor/vitest-docs/config/restoremocks.md +0 -22
  128. package/vendor/vitest-docs/config/retry.md +0 -140
  129. package/vendor/vitest-docs/config/root.md +0 -6
  130. package/vendor/vitest-docs/config/runner.md +0 -6
  131. package/vendor/vitest-docs/config/sequence.md +0 -158
  132. package/vendor/vitest-docs/config/server.md +0 -68
  133. package/vendor/vitest-docs/config/setupfiles.md +0 -40
  134. package/vendor/vitest-docs/config/silent.md +0 -9
  135. package/vendor/vitest-docs/config/slowtestthreshold.md +0 -7
  136. package/vendor/vitest-docs/config/snapshotenvironment.md +0 -27
  137. package/vendor/vitest-docs/config/snapshotformat.md +0 -28
  138. package/vendor/vitest-docs/config/snapshotserializers.md +0 -6
  139. package/vendor/vitest-docs/config/stricttags.md +0 -30
  140. package/vendor/vitest-docs/config/tags.md +0 -141
  141. package/vendor/vitest-docs/config/teardowntimeout.md +0 -7
  142. package/vendor/vitest-docs/config/testnamepattern.md +0 -21
  143. package/vendor/vitest-docs/config/testtimeout.md +0 -7
  144. package/vendor/vitest-docs/config/typecheck.md +0 -77
  145. package/vendor/vitest-docs/config/ui.md +0 -15
  146. package/vendor/vitest-docs/config/unstubenvs.md +0 -20
  147. package/vendor/vitest-docs/config/unstubglobals.md +0 -20
  148. package/vendor/vitest-docs/config/update.md +0 -16
  149. package/vendor/vitest-docs/config/vmmemorylimit.md +0 -30
  150. package/vendor/vitest-docs/config/watch.md +0 -11
  151. package/vendor/vitest-docs/config/watchtriggerpatterns.md +0 -29
  152. package/vendor/vitest-docs/guide/advanced/index.md +0 -147
  153. package/vendor/vitest-docs/guide/advanced/pool.md +0 -148
  154. package/vendor/vitest-docs/guide/advanced/reporters.md +0 -93
  155. package/vendor/vitest-docs/guide/advanced/tests.md +0 -125
  156. package/vendor/vitest-docs/guide/browser/aria-snapshots.md +0 -470
  157. package/vendor/vitest-docs/guide/browser/component-testing.md +0 -571
  158. package/vendor/vitest-docs/guide/browser/index.md +0 -630
  159. package/vendor/vitest-docs/guide/browser/multiple-setups.md +0 -121
  160. package/vendor/vitest-docs/guide/browser/trace-view.md +0 -126
  161. package/vendor/vitest-docs/guide/browser/visual-regression-testing.md +0 -734
  162. package/vendor/vitest-docs/guide/cli-generated.md +0 -972
  163. package/vendor/vitest-docs/guide/cli.md +0 -234
  164. package/vendor/vitest-docs/guide/common-errors.md +0 -163
  165. package/vendor/vitest-docs/guide/coverage.md +0 -515
  166. package/vendor/vitest-docs/guide/debugging.md +0 -127
  167. package/vendor/vitest-docs/guide/environment.md +0 -101
  168. package/vendor/vitest-docs/guide/extending-matchers.md +0 -160
  169. package/vendor/vitest-docs/guide/features.md +0 -310
  170. package/vendor/vitest-docs/guide/filtering.md +0 -175
  171. package/vendor/vitest-docs/guide/ide.md +0 -43
  172. package/vendor/vitest-docs/guide/improving-performance.md +0 -245
  173. package/vendor/vitest-docs/guide/in-source.md +0 -159
  174. package/vendor/vitest-docs/guide/index.md +0 -128
  175. package/vendor/vitest-docs/guide/learn/async.md +0 -147
  176. package/vendor/vitest-docs/guide/learn/debugging-tests.md +0 -210
  177. package/vendor/vitest-docs/guide/learn/matchers.md +0 -277
  178. package/vendor/vitest-docs/guide/learn/mock-functions.md +0 -277
  179. package/vendor/vitest-docs/guide/learn/setup-teardown.md +0 -240
  180. package/vendor/vitest-docs/guide/learn/snapshots.md +0 -166
  181. package/vendor/vitest-docs/guide/learn/testing-in-practice.md +0 -430
  182. package/vendor/vitest-docs/guide/learn/writing-tests-with-ai.md +0 -127
  183. package/vendor/vitest-docs/guide/learn/writing-tests.md +0 -231
  184. package/vendor/vitest-docs/guide/lifecycle.md +0 -379
  185. package/vendor/vitest-docs/guide/migration.md +0 -863
  186. package/vendor/vitest-docs/guide/mocking/classes.md +0 -158
  187. package/vendor/vitest-docs/guide/mocking/dates.md +0 -52
  188. package/vendor/vitest-docs/guide/mocking/file-system.md +0 -74
  189. package/vendor/vitest-docs/guide/mocking/functions.md +0 -61
  190. package/vendor/vitest-docs/guide/mocking/globals.md +0 -20
  191. package/vendor/vitest-docs/guide/mocking/modules.md +0 -414
  192. package/vendor/vitest-docs/guide/mocking/requests.md +0 -114
  193. package/vendor/vitest-docs/guide/mocking/timers.md +0 -48
  194. package/vendor/vitest-docs/guide/mocking.md +0 -239
  195. package/vendor/vitest-docs/guide/open-telemetry.md +0 -156
  196. package/vendor/vitest-docs/guide/parallelism.md +0 -82
  197. package/vendor/vitest-docs/guide/profiling-test-performance.md +0 -243
  198. package/vendor/vitest-docs/guide/projects.md +0 -291
  199. package/vendor/vitest-docs/guide/recipes.md +0 -59
  200. package/vendor/vitest-docs/guide/reporters.md +0 -723
  201. package/vendor/vitest-docs/guide/snapshot.md +0 -620
  202. package/vendor/vitest-docs/guide/test-annotations.md +0 -103
  203. package/vendor/vitest-docs/guide/test-context.md +0 -902
  204. package/vendor/vitest-docs/guide/test-tags.md +0 -314
  205. package/vendor/vitest-docs/guide/testing-types.md +0 -149
  206. package/vendor/vitest-docs/guide/ui.md +0 -160
  207. package/vendor/vitest-docs/guide/using-plugins.md +0 -5
  208. package/vendor/vitest-docs/manifest.json +0 -1691
@@ -1,902 +0,0 @@
1
- # Test Context
2
-
3
- Inspired by [Playwright Fixtures](https://playwright.dev/docs/test-fixtures), Vitest's test context allows you to define utils, states, and fixtures that can be used in your tests.
4
-
5
- ## Usage
6
-
7
- The first argument for each test callback is a test context.
8
-
9
- ```ts
10
- import { it } from 'vitest'
11
-
12
- it('should work', ({ task }) => {
13
- // prints name of the test
14
- console.log(task.name)
15
- })
16
- ```
17
-
18
- ## Built-in Test Context
19
-
20
- ### `task`
21
-
22
- A readonly object containing metadata about the test.
23
-
24
- ### `expect`
25
-
26
- The `expect` API bound to the current test:
27
-
28
- ```ts
29
- import { it } from 'vitest'
30
-
31
- it('math is easy', ({ expect }) => {
32
- expect(2 + 2).toBe(4)
33
- })
34
- ```
35
-
36
- This API is useful for running snapshot tests concurrently because global expect cannot track them:
37
-
38
- ```ts
39
- import { it } from 'vitest'
40
-
41
- it.concurrent('math is easy', ({ expect }) => {
42
- expect(2 + 2).toMatchInlineSnapshot()
43
- })
44
-
45
- it.concurrent('math is hard', ({ expect }) => {
46
- expect(2 * 2).toMatchInlineSnapshot()
47
- })
48
- ```
49
-
50
- ### `skip`
51
-
52
- ```ts
53
- function skip(note?: string): never
54
- function skip(condition: boolean, note?: string): void
55
- ```
56
-
57
- Skips subsequent test execution and marks test as skipped:
58
-
59
- ```ts
60
- import { expect, it } from 'vitest'
61
-
62
- it('math is hard', ({ skip }) => {
63
- skip()
64
- expect(2 + 2).toBe(5)
65
- })
66
- ```
67
-
68
- Since Vitest 3.1, it accepts a boolean parameter to skip the test conditionally:
69
-
70
- ```ts
71
- it('math is hard', ({ skip, mind }) => {
72
- skip(mind === 'foggy')
73
- expect(2 + 2).toBe(5)
74
- })
75
- ```
76
-
77
- ### `annotate` <Version>3.2.0</Version> {#annotate}
78
-
79
- ```ts
80
- function annotate(
81
- message: string,
82
- attachment?: TestAttachment,
83
- ): Promise<TestAnnotation>
84
-
85
- function annotate(
86
- message: string,
87
- type?: string,
88
- attachment?: TestAttachment,
89
- ): Promise<TestAnnotation>
90
- ```
91
-
92
- Add a [test annotation](/guide/test-annotations) that will be displayed by your [reporter](/config/reporters).
93
-
94
- ```ts
95
- test('annotations API', async ({ annotate }) => {
96
- await annotate('https://github.com/vitest-dev/vitest/pull/7953', 'issues')
97
- })
98
- ```
99
-
100
- ### `signal` <Version>3.2.0</Version> {#signal}
101
-
102
- An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that can be aborted by Vitest. The signal is aborted in these situations:
103
-
104
- - Test times out
105
- - User manually cancelled the test run with Ctrl+C
106
- - [`vitest.cancelCurrentRun`](/api/advanced/vitest#cancelcurrentrun) was called programmatically
107
- - Another test failed in parallel and the [`bail`](/config/bail) flag is set
108
-
109
- ```ts
110
- it('stop request when test times out', async ({ signal }) => {
111
- await fetch('/resource', { signal })
112
- }, 2000)
113
- ```
114
-
115
- ### `onTestFailed`
116
-
117
- The [`onTestFailed`](/api/hooks#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
118
-
119
- ### `onTestFinished`
120
-
121
- The [`onTestFinished`](/api/hooks#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
122
-
123
- ## Extend Test Context
124
-
125
- Vitest allows you to extend the test context with custom fixtures using `test.extend`.
126
-
127
- The `test.extend` method lets you create a custom test API with fixtures - reusable values that are automatically set up and torn down for your tests. Vitest supports two syntaxes: the builder pattern (recommended) and the object syntax (Playwright-compatible).
128
-
129
- ### Builder Pattern <Version>4.1.0</Version> {#builder-pattern}
130
-
131
- The builder pattern is the recommended way to define fixtures because it provides automatic type inference. TypeScript infers the type of each fixture from its return value, so you don't need to declare types manually.
132
-
133
- ```ts [my-test.ts]
134
- import { test as baseTest } from 'vitest'
135
-
136
- export const test = baseTest
137
- // Simple value - type is inferred as { port: number; host: string }
138
- .extend('config', { port: 3000, host: 'localhost' })
139
- // Function fixture - type is inferred from return value
140
- .extend('server', async ({ config }) => {
141
- // TypeScript knows config is { port: number; host: string }
142
- return `http://${config.host}:${config.port}`
143
- })
144
- ```
145
-
146
- Then use it in your tests:
147
-
148
- ```ts [my-test.test.ts]
149
- import { expect } from 'vitest'
150
- import { test } from './my-test.js'
151
-
152
- test('server uses correct port', ({ config, server }) => {
153
- // TypeScript knows the types:
154
- // - config is { port: number; host: string }
155
- // - server is string
156
- expect(server).toBe('http://localhost:3000')
157
- expect(config.port).toBe(3000)
158
- })
159
- ```
160
-
161
- #### Setup and Cleanup with `onCleanup`
162
-
163
- For fixtures that need setup or cleanup logic, use a function. The `onCleanup` callback registers teardown logic that runs after the fixture's scope ends:
164
-
165
- ```ts
166
- import { test as baseTest } from 'vitest'
167
-
168
- export const test = baseTest
169
- .extend('tempFile', async ({}, { onCleanup }) => {
170
- const filePath = `/tmp/test-${Date.now()}.txt`
171
- await fs.writeFile(filePath, 'test data')
172
-
173
- // Register cleanup - runs after test completes
174
- onCleanup(async () => {
175
- await fs.unlink(filePath)
176
- })
177
-
178
- return filePath
179
- })
180
- ```
181
-
182
- For more complex examples:
183
-
184
- ```ts
185
- const test = baseTest
186
- .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {
187
- const db = await createDatabase()
188
- await db.connect()
189
-
190
- onCleanup(async () => {
191
- await db.disconnect()
192
- })
193
-
194
- return db
195
- })
196
- .extend('user', async ({ database }, { onCleanup }) => {
197
- const user = await database.createTestUser()
198
-
199
- onCleanup(async () => {
200
- await database.deleteUser(user.id)
201
- })
202
-
203
- return user
204
- })
205
- ```
206
-
207
- ::: warning
208
- The `onCleanup` function can only be called **once per fixture**. If you need multiple cleanup operations, either combine them into a single cleanup function, or split your fixture into multiple smaller fixtures:
209
-
210
- ```ts
211
- // ❌ This will throw an error
212
- const test = baseTest
213
- .extend('resources', async ({}, { onCleanup }) => {
214
- const a = await acquireA()
215
- onCleanup(() => releaseA(a))
216
-
217
- const b = await acquireB()
218
- onCleanup(() => releaseB(b)) // Error: onCleanup can only be called once
219
-
220
- return { a, b }
221
- })
222
-
223
- // ✅ Split into separate fixtures (recommended)
224
- const test = baseTest
225
- .extend('resourceA', async ({}, { onCleanup }) => {
226
- const a = await acquireA()
227
- onCleanup(() => releaseA(a))
228
- return a
229
- })
230
- .extend('resourceB', async ({}, { onCleanup }) => {
231
- const b = await acquireB()
232
- onCleanup(() => releaseB(b))
233
- return b
234
- })
235
- ```
236
-
237
- Splitting into separate fixtures is the recommended approach as it provides better isolation and makes dependencies explicit.
238
- :::
239
-
240
- #### Fixture Options
241
-
242
- The second argument to `.extend()` accepts options:
243
-
244
- ```ts
245
- const test = baseTest
246
- // Automatic fixture - runs for every test even if not used
247
- .extend('metrics', { auto: true }, ({}, { onCleanup }) => {
248
- const metrics = new MetricsCollector()
249
- metrics.start()
250
- onCleanup(() => metrics.stop())
251
- return metrics
252
- })
253
- // Worker-scoped fixture - initialized once per worker
254
- .extend('config', { scope: 'worker' }, () => {
255
- return loadConfig()
256
- })
257
- // File-scoped fixture - initialized once per file
258
- .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {
259
- const db = await createDatabase(config)
260
- onCleanup(() => db.close())
261
- return db
262
- })
263
- // Injected fixture - can be overridden via config
264
- .extend('baseUrl', { injected: true }, () => {
265
- return 'http://localhost:3000'
266
- })
267
- ```
268
-
269
- For test-scoped fixtures (the default), you can omit the options:
270
-
271
- ```ts
272
- const test = baseTest
273
- .extend('simple', () => 'value')
274
- ```
275
-
276
- #### Accessing Other Fixtures
277
-
278
- Each fixture can access previously defined fixtures via its first parameter. This works for both function and non-function fixtures:
279
-
280
- ```ts
281
- const test = baseTest
282
- .extend('config', { apiUrl: 'https://api.example.com', port: 3000 })
283
- .extend('client', ({ config }) => {
284
- // TypeScript knows config is { apiUrl: string; port: number }
285
- return new ApiClient(config.apiUrl)
286
- })
287
- .extend('user', async ({ client }) => {
288
- // TypeScript knows client is ApiClient
289
- return await client.getCurrentUser()
290
- })
291
- ```
292
-
293
- #### Object Syntax (Playwright-Compatible)
294
-
295
- Vitest also supports a Playwright-compatible object syntax. This is useful if you're migrating from Playwright or prefer defining all fixtures at once:
296
-
297
- ```ts [my-test.ts]
298
- import { test as baseTest } from 'vitest'
299
-
300
- export const test = baseTest.extend({
301
- page: async ({}, use) => {
302
- // setup the fixture before each test function
303
- const page = await browser.newPage()
304
-
305
- // use the fixture value
306
- await use(page)
307
-
308
- // cleanup the fixture after each test function
309
- await page.close()
310
- },
311
- baseUrl: 'http://localhost:3000'
312
- })
313
- ```
314
-
315
- The key difference from the builder pattern is the `use()` callback pattern for cleanup:
316
-
317
- ```ts
318
- // Object syntax: cleanup code goes AFTER use()
319
- const test = baseTest.extend({
320
- database: async ({}, use) => {
321
- const db = await createDatabase()
322
- await db.connect()
323
-
324
- await use(db) // Test runs here
325
-
326
- // Cleanup after the test
327
- await db.disconnect()
328
- }
329
- })
330
-
331
- // Builder pattern: cleanup is registered with onCleanup()
332
- const test = baseTest
333
- .extend('database', async ({}, { onCleanup }) => {
334
- const db = await createDatabase()
335
- await db.connect()
336
-
337
- onCleanup(() => db.disconnect())
338
-
339
- return db // Test runs after this returns
340
- })
341
- ```
342
-
343
- ::: info
344
- With the object syntax, you need to provide types manually as a generic parameter since TypeScript cannot infer them from the `use()` callback:
345
-
346
- ```ts
347
- const test = baseTest.extend<{
348
- page: Page
349
- baseUrl: string
350
- }>({
351
- page: async ({}, use) => {
352
- const page = await browser.newPage()
353
- await use(page)
354
- await page.close()
355
- },
356
- baseUrl: 'http://localhost:3000'
357
- })
358
- ```
359
- :::
360
-
361
- #### Tuple Syntax for Options
362
-
363
- With the object syntax, use a tuple to specify fixture options:
364
-
365
- ```ts
366
- const test = baseTest.extend({
367
- // Auto fixture
368
- fixture: [
369
- async ({}, use) => {
370
- setup()
371
- await use()
372
- teardown()
373
- },
374
- { auto: true }
375
- ],
376
- // Scoped fixture
377
- database: [
378
- async ({}, use) => {
379
- const db = await createDatabase()
380
- await use(db)
381
- await db.close()
382
- },
383
- { scope: 'file' }
384
- ],
385
- // Injected fixture
386
- url: [
387
- '/default',
388
- { injected: true }
389
- ],
390
- })
391
- ```
392
-
393
- ### Fixture Initialization
394
-
395
- Vitest runner will smartly initialize your fixtures and inject them into the test context based on usage.
396
-
397
- ```ts
398
- import { test as baseTest } from 'vitest'
399
-
400
- const test = baseTest
401
- .extend('database', async () => {
402
- console.log('database initializing')
403
- return createDatabase()
404
- })
405
- .extend('cache', async () => {
406
- return createCache()
407
- })
408
-
409
- // database will not run
410
- test('no fixtures needed', () => {})
411
- test('only cache', ({ cache }) => {})
412
-
413
- // database will run
414
- test('needs database', ({ database }) => {})
415
- ```
416
-
417
- ::: warning
418
- When using `test.extend()` with fixtures, you should always use the object destructuring pattern `{ database }` to access context both in fixture function and test function.
419
-
420
- ```ts
421
- test('context must be destructured', (context) => { // [!code --]
422
- expect(context.database).toBeDefined()
423
- })
424
-
425
- test('context must be destructured', ({ database }) => { // [!code ++]
426
- expect(database).toBeDefined()
427
- })
428
- ```
429
- :::
430
-
431
- ### Extending Extended Tests
432
-
433
- You can extend an already extended test to add more fixtures:
434
-
435
- ```ts
436
- import { test as dbTest } from './my-test.js'
437
-
438
- export const test = dbTest
439
- .extend('user', ({ database }) => {
440
- return database.createUser()
441
- })
442
- ```
443
-
444
- With the object syntax:
445
-
446
- ```ts
447
- import { test as dbTest } from './my-test.js'
448
-
449
- export const test = dbTest.extend({
450
- admin: async ({ database }, use) => {
451
- const admin = await database.createAdmin()
452
- await use(admin)
453
- await database.deleteUser(admin.id)
454
- }
455
- })
456
- ```
457
-
458
- ### Mixing Both Syntaxes
459
-
460
- You can combine both approaches. The builder pattern can be chained after object-based extensions:
461
-
462
- ```ts
463
- const test = baseTest
464
- // Object syntax for simple fixtures
465
- .extend<{ apiKey: string }>({
466
- apiKey: 'test-key-123',
467
- })
468
- // Builder pattern for complex fixtures with inference
469
- .extend('client', ({ apiKey }) => {
470
- // TypeScript knows apiKey is string
471
- return new ApiClient(apiKey)
472
- })
473
- ```
474
-
475
- ### Fixture Scopes <Version>3.2.0</Version> {#fixture-scopes}
476
-
477
- By default, fixtures are initialized for each test. You can change this with the `scope` option to share fixtures across tests.
478
-
479
- ::: warning
480
- By default any fixture without a scope is treated as a `test` fixture. This means that you cannot use it inside `worker` and `file` scopes. If you wish to access it there, consider specifying a scope manually:
481
-
482
- ```ts
483
- test
484
- .extend('port', { scope: 'worker' }, 5000)
485
- .extend('db', { scope: 'worker' }, async ({ port }) => {
486
- return createDb(port)
487
- })
488
- ```
489
-
490
- Note that you cannot override non-test fixtures inside `describe` blocks:
491
-
492
- ```ts
493
- test.describe('a nested suite', () => {
494
- test.override('port', { scope: 'worker' }, 3000) // throws an error
495
- })
496
- ```
497
-
498
- Consider overriding it on the top level of the module, or by using [`injected`](#default-fixture-injected) option and providing the value in the project config.
499
-
500
- Also note that in [non-isolate](/config/isolate) mode overriding a `worker` fixture will affect the fixture value in all test files running after it was overridden.
501
- :::
502
-
503
- #### Test Scope (Default)
504
-
505
- Test-scoped fixtures are created fresh for each test:
506
-
507
- ```ts
508
- const test = baseTest
509
- .extend('counter', () => {
510
- return { value: 0 }
511
- })
512
-
513
- test('first test', ({ counter }) => {
514
- counter.value++
515
- expect(counter.value).toBe(1)
516
- })
517
-
518
- test('second test', ({ counter }) => {
519
- // Fresh instance, value is 0 again
520
- expect(counter.value).toBe(0)
521
- })
522
- ```
523
-
524
- Test-scoped fixtures have access to the [built-in test context](#built-in-test-context) (`task`, `expect`, `skip`, etc.):
525
-
526
- ```ts
527
- const test = baseTest
528
- .extend('testInfo', ({ task }) => {
529
- return { name: task.name }
530
- })
531
- ```
532
-
533
- #### File Scope
534
-
535
- File-scoped fixtures are initialized once per test file:
536
-
537
- ```ts
538
- const test = baseTest
539
- .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {
540
- const db = await createDatabase()
541
- onCleanup(() => db.close())
542
- return db
543
- })
544
-
545
- test('first test', ({ database }) => {
546
- // Uses the same database instance
547
- })
548
-
549
- test('second test', ({ database }) => {
550
- // Same database instance as first test
551
- })
552
- ```
553
-
554
- #### Worker Scope
555
-
556
- Worker-scoped fixtures are initialized once per worker process:
557
-
558
- ```ts
559
- const test = baseTest
560
- .extend('config', { scope: 'worker' }, () => {
561
- return await loadExpensiveConfig()
562
- })
563
- ```
564
-
565
- ::: info
566
- By default, every file runs in a separate worker, so `file` and `worker` scopes work the same way. However, if you disable [isolation](/config/isolate), then the number of workers is limited by [`maxWorkers`](/config/maxworkers), and worker-scoped fixtures will be shared across files running in the same worker.
567
-
568
- When running tests in `vmThreads` or `vmForks`, `scope: 'worker'` works the same way as `scope: 'file'` because each file has its own VM context.
569
- :::
570
-
571
- #### Scope Hierarchy
572
-
573
- Fixtures can only access other fixtures from the same or higher (longer-lived) scopes:
574
-
575
- | Fixture Scope | Can Access |
576
- |---------------|------------|
577
- | `worker` | Only other worker fixtures |
578
- | `file` | Worker + file fixtures |
579
- | `test` | Worker + file + test fixtures + [test context](#built-in-test-context) |
580
-
581
- ```ts
582
- const test = baseTest
583
- .extend('config', { scope: 'worker' }, () => {
584
- return { apiUrl: 'https://api.example.com' }
585
- })
586
- .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {
587
- // ✅ File fixture can access worker fixture
588
- const db = await createDatabase(config.apiUrl)
589
- onCleanup(() => db.close())
590
- return db
591
- })
592
- .extend('user', async ({ database, task }) => {
593
- // ✅ Test fixture can access file fixture AND test context
594
- return await database.createUser(task.name)
595
- })
596
- ```
597
-
598
- ::: tip
599
- Only test-scoped fixtures have access to the [built-in test context](#built-in-test-context) (`task`, `expect`, `skip`, etc.). Worker and file fixtures run outside of any specific test, so test-specific properties are not available to them.
600
-
601
- If you need the file path in a file-scoped fixture, use `expect.getState().testPath` instead.
602
- :::
603
-
604
- #### Type-Safe Scope Access <Version>3.2.0</Version> {#type-safe-scope-access}
605
-
606
- With the builder pattern, TypeScript automatically enforces scope-based access rules. If you try to access a test-scoped fixture from a file-scoped fixture, you'll get a compile-time error.
607
-
608
- If you're using the object syntax and want the same type safety, you can use the `$worker`, `$file`, and `$test` keys to explicitly declare which fixtures belong to which scope:
609
-
610
- ```ts
611
- const test = baseTest.extend<{
612
- $worker: { config: Config }
613
- $file: { database: Database }
614
- $test: { user: User }
615
- }>({
616
- config: [async ({}, use) => {
617
- await use(loadConfig())
618
- }, { scope: 'worker' }],
619
-
620
- database: [async ({ config }, use) => {
621
- const db = await createDatabase(config)
622
- await use(db)
623
- await db.close()
624
- }, { scope: 'file' }],
625
-
626
- user: async ({ database }, use) => {
627
- const user = await database.createUser()
628
- await use(user)
629
- await database.deleteUser(user.id)
630
- },
631
- })
632
- ```
633
-
634
- This provides the same compile-time safety as the builder pattern, catching scope violations at build time rather than runtime.
635
-
636
- ### Default Fixture (Injected)
637
-
638
- Since Vitest 3, you can provide different values in different [projects](/guide/projects). To enable this, pass `{ injected: true }` in the options. If the key is not specified in the [project configuration](/config/provide), the default value will be used.
639
-
640
- :::code-group
641
- ```ts [fixtures.test.ts]
642
- import { test as baseTest } from 'vitest'
643
-
644
- const test = baseTest
645
- .extend('url', { injected: true }, '/default')
646
-
647
- test('works correctly', ({ url }) => {
648
- // url is "/default" in "project-new"
649
- // url is "/full" in "project-full"
650
- // url is "/empty" in "project-empty"
651
- })
652
- ```
653
- ```ts [vitest.config.ts]
654
- import { defineConfig } from 'vitest/config'
655
-
656
- export default defineConfig({
657
- test: {
658
- projects: [
659
- {
660
- test: {
661
- name: 'project-new',
662
- },
663
- },
664
- {
665
- test: {
666
- name: 'project-full',
667
- provide: {
668
- url: '/full',
669
- },
670
- },
671
- },
672
- {
673
- test: {
674
- name: 'project-empty',
675
- provide: {
676
- url: '/empty',
677
- },
678
- },
679
- },
680
- ],
681
- },
682
- })
683
- ```
684
- :::
685
-
686
- ### Overriding Fixture Values <Version>4.1.0</Version> {#overriding-fixture-values}
687
-
688
- You can override fixture values for a specific suite and its children using `test.override`. This is useful when you need different fixture values for different test scenarios.
689
-
690
- ::: tip
691
- Vitest will automatically inherit the options, if they are not provided when overriding. Note that you cannot override fixture's `scope` or `auto` options.
692
- :::
693
-
694
- #### Builder Pattern (Recommended)
695
-
696
- ```ts
697
- import { test as baseTest, describe, expect } from 'vitest'
698
-
699
- const test = baseTest
700
- .extend('config', { port: 3000, host: 'localhost' })
701
- .extend('server', ({ config }) => `http://${config.host}:${config.port}`)
702
-
703
- describe('production environment', () => {
704
- // Override with a new static value (chainable)
705
- test
706
- .override('config', { port: 8080, host: 'api.example.com' })
707
-
708
- test('uses production config', ({ server }) => {
709
- expect(server).toBe('http://api.example.com:8080')
710
- })
711
- })
712
-
713
- describe('with custom server', () => {
714
- // Override with a function that can access other fixtures
715
- test.override('server', ({ config }) => {
716
- return `https://${config.host}:${config.port}/v2`
717
- })
718
-
719
- test('uses custom server', ({ server }) => {
720
- expect(server).toBe('https://localhost:3000/v2')
721
- })
722
- })
723
-
724
- test('uses default values', ({ server }) => {
725
- expect(server).toBe('http://localhost:3000')
726
- })
727
- ```
728
-
729
- #### Chaining Multiple Overrides
730
-
731
- `test.override` returns the test API, so you can chain multiple calls:
732
-
733
- ```ts
734
- describe('production environment', () => {
735
- test
736
- .override('environment', 'production')
737
- .override('port', 8080)
738
- .override('debug', false)
739
-
740
- test('uses production settings', ({ environment, port, debug }) => {
741
- expect(environment).toBe('production')
742
- expect(port).toBe(8080)
743
- expect(debug).toBe(false)
744
- })
745
- })
746
- ```
747
-
748
- #### Object Syntax
749
-
750
- You can also use object syntax to override multiple fixtures at once:
751
-
752
- ```ts
753
- describe('different configuration', () => {
754
- test.override({
755
- config: { port: 4000, host: 'test.local' },
756
- })
757
-
758
- test('uses overwritten config', ({ config }) => {
759
- expect(config.port).toBe(4000)
760
- })
761
- })
762
- ```
763
-
764
- #### With Cleanup
765
-
766
- When overwriting with a function, you can use `onCleanup` just like in `test.extend`:
767
-
768
- ```ts
769
- describe('with custom database', () => {
770
- test.override('database', async ({ config }, { onCleanup }) => {
771
- const db = await createTestDatabase(config)
772
- onCleanup(() => db.drop())
773
- return db
774
- })
775
-
776
- test('uses custom database', ({ database }) => {
777
- // Uses the overwritten database
778
- })
779
- })
780
- ```
781
-
782
- #### Nested Scopes
783
-
784
- Overrides are inherited by nested suites and can be overwritten again:
785
-
786
- ```ts
787
- describe('level 1', () => {
788
- test.override('value', 'one')
789
-
790
- test('uses level 1 value', ({ value }) => {
791
- expect(value).toBe('one')
792
- })
793
-
794
- describe('level 2', () => {
795
- test.override('value', 'two')
796
-
797
- test('uses level 2 value', ({ value }) => {
798
- expect(value).toBe('two')
799
- })
800
- })
801
-
802
- test('still uses level 1 value', ({ value }) => {
803
- expect(value).toBe('one')
804
- })
805
- })
806
- ```
807
-
808
- ::: warning
809
- Note that you cannot introduce new fixtures inside `test.override`. Extend the test context with `test.extend` instead.
810
- :::
811
-
812
- ::: info
813
- `test.scoped` is deprecated in favor of `test.override`. The `test.scoped` API still works but will be removed in a future version.
814
- :::
815
-
816
- ### Type-Safe Hooks
817
-
818
- When using `test.extend`, the extended `test` object provides type-safe hooks that are aware of the extended context:
819
-
820
- ```ts
821
- const test = baseTest
822
- .extend('counter', { value: 0, increment() { this.value++ } })
823
-
824
- // Unlike global hooks, these hooks are aware of the extended context
825
- test.beforeEach(({ counter }) => {
826
- counter.increment()
827
- })
828
-
829
- test.afterEach(({ counter }) => {
830
- console.log('Final count:', counter.value)
831
- })
832
- ```
833
-
834
- #### Suite-Level Hooks with Fixtures <Version>4.1.0</Version> {#suite-level-hooks}
835
-
836
- The extended `test` object also provides [`beforeAll`](/api/hooks#beforeall), [`afterAll`](/api/hooks#afterall), and [`aroundAll`](/api/hooks#aroundall) hooks that can access file-scoped and worker-scoped fixtures:
837
-
838
- ```ts
839
- const test = baseTest
840
- .extend('config', { scope: 'file' }, () => loadConfig())
841
- .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {
842
- const db = await createDatabase(config)
843
- onCleanup(() => db.close())
844
- return db
845
- })
846
-
847
- // Access file-scoped fixtures in suite-level hooks
848
- test.aroundAll(async (runSuite, { database }) => {
849
- await database.transaction(runSuite)
850
- })
851
-
852
- test.beforeAll(async ({ database }) => {
853
- await database.createUsers()
854
- })
855
-
856
- test.afterAll(async ({ database }) => {
857
- await database.removeUsers()
858
- })
859
- ```
860
-
861
- ::: warning IMPORTANT
862
- Suite-level hooks (`beforeAll`, `afterAll`, `aroundAll`) **must be called on the `test` object returned from `test.extend()`** to have access to the extended fixtures. Using the global `beforeAll`/`afterAll`/`aroundAll` functions will not have access to your custom fixtures:
863
-
864
- ```ts
865
- import { test as baseTest, beforeAll } from 'vitest'
866
-
867
- const test = baseTest
868
- .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {
869
- const db = await createDatabase()
870
- onCleanup(() => db.close())
871
- return db
872
- })
873
-
874
- // ❌ WRONG: Global beforeAll doesn't have access to 'database'
875
- beforeAll(({ database }) => {
876
- // Error: 'database' is undefined
877
- })
878
-
879
- // ✅ CORRECT: Use test.beforeAll to access fixtures
880
- test.beforeAll(({ database }) => {
881
- // 'database' is available
882
- })
883
- ```
884
-
885
- This applies to all suite-level hooks: `beforeAll`, `afterAll`, and `aroundAll`.
886
- :::
887
-
888
- ::: tip
889
- Suite-level hooks can only access [**file-scoped** and **worker-scoped** fixtures](#fixture-scopes), including `auto` fixtures. Test-scoped fixtures are not available in these hooks because they run outside the context of individual tests. If you try to access a test-scoped fixture in a suite-level hook, Vitest will throw an error.
890
-
891
- ```ts
892
- const test = baseTest
893
- .extend('testFixture', () => 'test-scoped')
894
- .extend('fileFixture', { scope: 'file' }, () => 'file-scoped')
895
-
896
- // ❌ Error: test-scoped fixtures not available in beforeAll
897
- test.beforeAll(({ testFixture }) => {})
898
-
899
- // ✅ Works: file-scoped fixtures are available
900
- test.beforeAll(({ fileFixture }) => {})
901
- ```
902
- :::