@vitest-agent/mcp 1.0.1 → 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 (229) hide show
  1. package/README.md +1 -2
  2. package/bin/vitest-agent-mcp.js +1 -17
  3. package/index.d.ts +324 -315
  4. package/index.js +2 -4
  5. package/middleware/idempotency.js +1 -1
  6. package/package.json +2 -2
  7. package/server.js +2 -4
  8. package/tools/acceptance-metrics.js +1 -1
  9. package/tools/cache-health.js +1 -1
  10. package/tools/commit-changes.js +1 -1
  11. package/tools/configure.js +1 -1
  12. package/tools/coverage.js +1 -1
  13. package/tools/errors.js +1 -1
  14. package/tools/failure-signature-get.js +1 -1
  15. package/tools/file-coverage.js +1 -1
  16. package/tools/history.js +1 -1
  17. package/tools/inventory.js +1 -1
  18. package/tools/overview.js +1 -1
  19. package/tools/run-tests.js +15 -3
  20. package/tools/settings-list.js +1 -1
  21. package/tools/status.js +1 -1
  22. package/tools/tdd-artifact.js +1 -1
  23. package/tools/tdd-task.js +1 -1
  24. package/tools/test.js +1 -1
  25. package/tools/trends.js +1 -1
  26. package/tools/turn-search.js +1 -1
  27. package/public/patterns/_meta.json +0 -67
  28. package/public/patterns/authoring-a-custom-vitest-agent-reporter.md +0 -82
  29. package/public/patterns/known-issues-and-caveats.md +0 -52
  30. package/public/patterns/operating-vitest-agent-as-an-agent.md +0 -53
  31. package/public/patterns/running-tests-via-mcp.md +0 -58
  32. package/public/patterns/silencing-leaking-output-in-tests.md +0 -91
  33. package/public/patterns/testing-effect-schema-definitions.md +0 -71
  34. package/public/patterns/testing-effect-services-with-mock-layers.md +0 -63
  35. package/public/vendor/vitest-docs/ATTRIBUTION.md +0 -5
  36. package/public/vendor/vitest-docs/api/advanced/artifacts.md +0 -189
  37. package/public/vendor/vitest-docs/api/advanced/metadata.md +0 -68
  38. package/public/vendor/vitest-docs/api/advanced/plugin.md +0 -168
  39. package/public/vendor/vitest-docs/api/advanced/reporters.md +0 -342
  40. package/public/vendor/vitest-docs/api/advanced/runner.md +0 -334
  41. package/public/vendor/vitest-docs/api/advanced/test-case.md +0 -302
  42. package/public/vendor/vitest-docs/api/advanced/test-collection.md +0 -89
  43. package/public/vendor/vitest-docs/api/advanced/test-module.md +0 -140
  44. package/public/vendor/vitest-docs/api/advanced/test-project.md +0 -321
  45. package/public/vendor/vitest-docs/api/advanced/test-specification.md +0 -96
  46. package/public/vendor/vitest-docs/api/advanced/test-suite.md +0 -230
  47. package/public/vendor/vitest-docs/api/advanced/vitest.md +0 -684
  48. package/public/vendor/vitest-docs/api/assert-type.md +0 -22
  49. package/public/vendor/vitest-docs/api/assert.md +0 -1960
  50. package/public/vendor/vitest-docs/api/browser/assertions.md +0 -1277
  51. package/public/vendor/vitest-docs/api/browser/commands.md +0 -154
  52. package/public/vendor/vitest-docs/api/browser/context.md +0 -338
  53. package/public/vendor/vitest-docs/api/browser/interactivity.md +0 -681
  54. package/public/vendor/vitest-docs/api/browser/locators.md +0 -1171
  55. package/public/vendor/vitest-docs/api/browser/react.md +0 -346
  56. package/public/vendor/vitest-docs/api/browser/svelte.md +0 -292
  57. package/public/vendor/vitest-docs/api/browser/vue.md +0 -222
  58. package/public/vendor/vitest-docs/api/describe.md +0 -374
  59. package/public/vendor/vitest-docs/api/expect-typeof.md +0 -571
  60. package/public/vendor/vitest-docs/api/expect.md +0 -2304
  61. package/public/vendor/vitest-docs/api/hooks.md +0 -463
  62. package/public/vendor/vitest-docs/api/mock.md +0 -701
  63. package/public/vendor/vitest-docs/api/test.md +0 -926
  64. package/public/vendor/vitest-docs/api/vi.md +0 -1372
  65. package/public/vendor/vitest-docs/config/alias.md +0 -13
  66. package/public/vendor/vitest-docs/config/allowonly.md +0 -32
  67. package/public/vendor/vitest-docs/config/api.md +0 -27
  68. package/public/vendor/vitest-docs/config/attachmentsdir.md +0 -6
  69. package/public/vendor/vitest-docs/config/bail.md +0 -9
  70. package/public/vendor/vitest-docs/config/benchmark.md +0 -65
  71. package/public/vendor/vitest-docs/config/browser/api.md +0 -23
  72. package/public/vendor/vitest-docs/config/browser/commands.md +0 -6
  73. package/public/vendor/vitest-docs/config/browser/connecttimeout.md +0 -10
  74. package/public/vendor/vitest-docs/config/browser/detailspanelposition.md +0 -38
  75. package/public/vendor/vitest-docs/config/browser/enabled.md +0 -40
  76. package/public/vendor/vitest-docs/config/browser/expect.md +0 -250
  77. package/public/vendor/vitest-docs/config/browser/headless.md +0 -7
  78. package/public/vendor/vitest-docs/config/browser/instances.md +0 -47
  79. package/public/vendor/vitest-docs/config/browser/isolate.md +0 -11
  80. package/public/vendor/vitest-docs/config/browser/locators.md +0 -24
  81. package/public/vendor/vitest-docs/config/browser/orchestratorscripts.md +0 -39
  82. package/public/vendor/vitest-docs/config/browser/playwright.md +0 -214
  83. package/public/vendor/vitest-docs/config/browser/preview.md +0 -32
  84. package/public/vendor/vitest-docs/config/browser/provider.md +0 -79
  85. package/public/vendor/vitest-docs/config/browser/screenshotdirectory.md +0 -6
  86. package/public/vendor/vitest-docs/config/browser/screenshotfailures.md +0 -6
  87. package/public/vendor/vitest-docs/config/browser/testerhtmlpath.md +0 -5
  88. package/public/vendor/vitest-docs/config/browser/trace.md +0 -43
  89. package/public/vendor/vitest-docs/config/browser/trackunhandlederrors.md +0 -10
  90. package/public/vendor/vitest-docs/config/browser/ui.md +0 -7
  91. package/public/vendor/vitest-docs/config/browser/viewport.md +0 -6
  92. package/public/vendor/vitest-docs/config/browser/webdriverio.md +0 -64
  93. package/public/vendor/vitest-docs/config/cache.md +0 -26
  94. package/public/vendor/vitest-docs/config/chaiconfig.md +0 -29
  95. package/public/vendor/vitest-docs/config/clearmocks.md +0 -22
  96. package/public/vendor/vitest-docs/config/coverage.md +0 -455
  97. package/public/vendor/vitest-docs/config/css.md +0 -47
  98. package/public/vendor/vitest-docs/config/dangerouslyignoreunhandlederrors.md +0 -23
  99. package/public/vendor/vitest-docs/config/deps.md +0 -127
  100. package/public/vendor/vitest-docs/config/detectasyncleaks.md +0 -39
  101. package/public/vendor/vitest-docs/config/diff.md +0 -96
  102. package/public/vendor/vitest-docs/config/dir.md +0 -7
  103. package/public/vendor/vitest-docs/config/disableconsoleintercept.md +0 -15
  104. package/public/vendor/vitest-docs/config/env.md +0 -5
  105. package/public/vendor/vitest-docs/config/environment.md +0 -96
  106. package/public/vendor/vitest-docs/config/environmentoptions.md +0 -30
  107. package/public/vendor/vitest-docs/config/exclude.md +0 -49
  108. package/public/vendor/vitest-docs/config/execargv.md +0 -10
  109. package/public/vendor/vitest-docs/config/expandsnapshotdiff.md +0 -7
  110. package/public/vendor/vitest-docs/config/expect.md +0 -38
  111. package/public/vendor/vitest-docs/config/experimental.md +0 -510
  112. package/public/vendor/vitest-docs/config/faketimers.md +0 -51
  113. package/public/vendor/vitest-docs/config/fileparallelism.md +0 -11
  114. package/public/vendor/vitest-docs/config/forcereruntriggers.md +0 -19
  115. package/public/vendor/vitest-docs/config/globals.md +0 -42
  116. package/public/vendor/vitest-docs/config/globalsetup.md +0 -72
  117. package/public/vendor/vitest-docs/config/hideskippedtests.md +0 -7
  118. package/public/vendor/vitest-docs/config/hooktimeout.md +0 -7
  119. package/public/vendor/vitest-docs/config/include-source.md +0 -115
  120. package/public/vendor/vitest-docs/config/include.md +0 -71
  121. package/public/vendor/vitest-docs/config/includetasklocation.md +0 -17
  122. package/public/vendor/vitest-docs/config/index.md +0 -85
  123. package/public/vendor/vitest-docs/config/isolate.md +0 -13
  124. package/public/vendor/vitest-docs/config/logheapusage.md +0 -7
  125. package/public/vendor/vitest-docs/config/maxconcurrency.md +0 -9
  126. package/public/vendor/vitest-docs/config/maxworkers.md +0 -49
  127. package/public/vendor/vitest-docs/config/mockreset.md +0 -22
  128. package/public/vendor/vitest-docs/config/mode.md +0 -7
  129. package/public/vendor/vitest-docs/config/name.md +0 -111
  130. package/public/vendor/vitest-docs/config/onconsolelog.md +0 -25
  131. package/public/vendor/vitest-docs/config/onstacktrace.md +0 -32
  132. package/public/vendor/vitest-docs/config/onunhandlederror.md +0 -35
  133. package/public/vendor/vitest-docs/config/open.md +0 -7
  134. package/public/vendor/vitest-docs/config/outputfile.md +0 -7
  135. package/public/vendor/vitest-docs/config/passwithnotests.md +0 -7
  136. package/public/vendor/vitest-docs/config/pool.md +0 -45
  137. package/public/vendor/vitest-docs/config/printconsoletrace.md +0 -6
  138. package/public/vendor/vitest-docs/config/projects.md +0 -6
  139. package/public/vendor/vitest-docs/config/provide.md +0 -45
  140. package/public/vendor/vitest-docs/config/reporters.md +0 -69
  141. package/public/vendor/vitest-docs/config/resolvesnapshotpath.md +0 -36
  142. package/public/vendor/vitest-docs/config/restoremocks.md +0 -22
  143. package/public/vendor/vitest-docs/config/retry.md +0 -140
  144. package/public/vendor/vitest-docs/config/root.md +0 -6
  145. package/public/vendor/vitest-docs/config/runner.md +0 -6
  146. package/public/vendor/vitest-docs/config/sequence.md +0 -158
  147. package/public/vendor/vitest-docs/config/server.md +0 -68
  148. package/public/vendor/vitest-docs/config/setupfiles.md +0 -40
  149. package/public/vendor/vitest-docs/config/silent.md +0 -9
  150. package/public/vendor/vitest-docs/config/slowtestthreshold.md +0 -7
  151. package/public/vendor/vitest-docs/config/snapshotenvironment.md +0 -27
  152. package/public/vendor/vitest-docs/config/snapshotformat.md +0 -28
  153. package/public/vendor/vitest-docs/config/snapshotserializers.md +0 -6
  154. package/public/vendor/vitest-docs/config/stricttags.md +0 -30
  155. package/public/vendor/vitest-docs/config/tags.md +0 -141
  156. package/public/vendor/vitest-docs/config/teardowntimeout.md +0 -7
  157. package/public/vendor/vitest-docs/config/testnamepattern.md +0 -21
  158. package/public/vendor/vitest-docs/config/testtimeout.md +0 -7
  159. package/public/vendor/vitest-docs/config/typecheck.md +0 -77
  160. package/public/vendor/vitest-docs/config/ui.md +0 -15
  161. package/public/vendor/vitest-docs/config/unstubenvs.md +0 -20
  162. package/public/vendor/vitest-docs/config/unstubglobals.md +0 -20
  163. package/public/vendor/vitest-docs/config/update.md +0 -16
  164. package/public/vendor/vitest-docs/config/vmmemorylimit.md +0 -30
  165. package/public/vendor/vitest-docs/config/watch.md +0 -11
  166. package/public/vendor/vitest-docs/config/watchtriggerpatterns.md +0 -29
  167. package/public/vendor/vitest-docs/guide/advanced/index.md +0 -147
  168. package/public/vendor/vitest-docs/guide/advanced/pool.md +0 -148
  169. package/public/vendor/vitest-docs/guide/advanced/reporters.md +0 -93
  170. package/public/vendor/vitest-docs/guide/advanced/tests.md +0 -125
  171. package/public/vendor/vitest-docs/guide/browser/aria-snapshots.md +0 -470
  172. package/public/vendor/vitest-docs/guide/browser/component-testing.md +0 -571
  173. package/public/vendor/vitest-docs/guide/browser/index.md +0 -630
  174. package/public/vendor/vitest-docs/guide/browser/multiple-setups.md +0 -121
  175. package/public/vendor/vitest-docs/guide/browser/trace-view.md +0 -126
  176. package/public/vendor/vitest-docs/guide/browser/visual-regression-testing.md +0 -734
  177. package/public/vendor/vitest-docs/guide/cli-generated.md +0 -972
  178. package/public/vendor/vitest-docs/guide/cli.md +0 -234
  179. package/public/vendor/vitest-docs/guide/common-errors.md +0 -163
  180. package/public/vendor/vitest-docs/guide/coverage.md +0 -515
  181. package/public/vendor/vitest-docs/guide/debugging.md +0 -127
  182. package/public/vendor/vitest-docs/guide/environment.md +0 -101
  183. package/public/vendor/vitest-docs/guide/extending-matchers.md +0 -160
  184. package/public/vendor/vitest-docs/guide/features.md +0 -310
  185. package/public/vendor/vitest-docs/guide/filtering.md +0 -175
  186. package/public/vendor/vitest-docs/guide/ide.md +0 -43
  187. package/public/vendor/vitest-docs/guide/improving-performance.md +0 -245
  188. package/public/vendor/vitest-docs/guide/in-source.md +0 -159
  189. package/public/vendor/vitest-docs/guide/index.md +0 -128
  190. package/public/vendor/vitest-docs/guide/learn/async.md +0 -147
  191. package/public/vendor/vitest-docs/guide/learn/debugging-tests.md +0 -210
  192. package/public/vendor/vitest-docs/guide/learn/matchers.md +0 -277
  193. package/public/vendor/vitest-docs/guide/learn/mock-functions.md +0 -277
  194. package/public/vendor/vitest-docs/guide/learn/setup-teardown.md +0 -240
  195. package/public/vendor/vitest-docs/guide/learn/snapshots.md +0 -166
  196. package/public/vendor/vitest-docs/guide/learn/testing-in-practice.md +0 -430
  197. package/public/vendor/vitest-docs/guide/learn/writing-tests-with-ai.md +0 -127
  198. package/public/vendor/vitest-docs/guide/learn/writing-tests.md +0 -231
  199. package/public/vendor/vitest-docs/guide/lifecycle.md +0 -379
  200. package/public/vendor/vitest-docs/guide/migration.md +0 -863
  201. package/public/vendor/vitest-docs/guide/mocking/classes.md +0 -158
  202. package/public/vendor/vitest-docs/guide/mocking/dates.md +0 -52
  203. package/public/vendor/vitest-docs/guide/mocking/file-system.md +0 -74
  204. package/public/vendor/vitest-docs/guide/mocking/functions.md +0 -61
  205. package/public/vendor/vitest-docs/guide/mocking/globals.md +0 -20
  206. package/public/vendor/vitest-docs/guide/mocking/modules.md +0 -414
  207. package/public/vendor/vitest-docs/guide/mocking/requests.md +0 -114
  208. package/public/vendor/vitest-docs/guide/mocking/timers.md +0 -48
  209. package/public/vendor/vitest-docs/guide/mocking.md +0 -239
  210. package/public/vendor/vitest-docs/guide/open-telemetry.md +0 -156
  211. package/public/vendor/vitest-docs/guide/parallelism.md +0 -82
  212. package/public/vendor/vitest-docs/guide/profiling-test-performance.md +0 -243
  213. package/public/vendor/vitest-docs/guide/projects.md +0 -291
  214. package/public/vendor/vitest-docs/guide/recipes.md +0 -59
  215. package/public/vendor/vitest-docs/guide/reporters.md +0 -723
  216. package/public/vendor/vitest-docs/guide/snapshot.md +0 -620
  217. package/public/vendor/vitest-docs/guide/test-annotations.md +0 -103
  218. package/public/vendor/vitest-docs/guide/test-context.md +0 -902
  219. package/public/vendor/vitest-docs/guide/test-tags.md +0 -314
  220. package/public/vendor/vitest-docs/guide/testing-types.md +0 -149
  221. package/public/vendor/vitest-docs/guide/ui.md +0 -160
  222. package/public/vendor/vitest-docs/guide/using-plugins.md +0 -5
  223. package/public/vendor/vitest-docs/manifest.json +0 -1691
  224. package/resources/index.js +0 -166
  225. package/resources/indexes.js +0 -77
  226. package/resources/manifest-schema.js +0 -46
  227. package/resources/paths.js +0 -20
  228. package/resources/patterns.js +0 -22
  229. package/resources/upstream-docs.js +0 -22
@@ -1,620 +0,0 @@
1
- # Snapshot
2
-
3
- ::: tip
4
- For a beginner-friendly introduction to snapshot testing, see the [Snapshot Testing](/guide/learn/snapshots) tutorial.
5
- :::
6
-
7
- <CourseLink href="https://vueschool.io/lessons/snapshots-in-vitest?friend=vueuse">Learn Snapshot by video from Vue School</CourseLink>
8
-
9
- Snapshot tests are a very useful tool whenever you want to make sure the output of your functions does not change unexpectedly.
10
-
11
- When using snapshot, Vitest will take a snapshot of the given value, then compare it to a reference snapshot file stored alongside the test. The test will fail if the two snapshots do not match: either the change is unexpected, or the reference snapshot needs to be updated to the new version of the result.
12
-
13
- ## Use Snapshots
14
-
15
- To snapshot a value, you can use the [`toMatchSnapshot()`](/api/expect#tomatchsnapshot) from `expect()` API:
16
-
17
- ```ts
18
- import { expect, it } from 'vitest'
19
-
20
- it('toUpperCase', () => {
21
- const result = toUpperCase('foobar')
22
- expect(result).toMatchSnapshot()
23
- })
24
- ```
25
-
26
- The first time this test is run, Vitest creates a snapshot file that looks like this:
27
-
28
- ```js
29
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
30
-
31
- exports['toUpperCase 1'] = '"FOOBAR"'
32
- ```
33
-
34
- The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. On subsequent test runs, Vitest will compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated.
35
-
36
- Vitest stores a serialized representation of the received value. Snapshot rendering is powered by [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format). [`snapshotFormat`](/config/snapshotformat) allows configuring general snapshot formatting behavior in Vitest. For further customization, you can implement your own [custom serializers](#custom-serializer) or [custom snapshot matchers](#custom-snapshot-matchers).
37
-
38
- ::: warning
39
- When using Snapshots with async concurrent tests, `expect` from the local [Test Context](/guide/test-context) must be used to ensure the right test is detected.
40
- :::
41
-
42
- ## Inline Snapshots
43
-
44
- Similarly, you can use the [`toMatchInlineSnapshot()`](/api/expect#tomatchinlinesnapshot) to store the snapshot inline within the test file.
45
-
46
- ```ts
47
- import { expect, it } from 'vitest'
48
-
49
- it('toUpperCase', () => {
50
- const result = toUpperCase('foobar')
51
- expect(result).toMatchInlineSnapshot()
52
- })
53
- ```
54
-
55
- Instead of creating a snapshot file, Vitest will modify the test file directly to update the snapshot as a string:
56
-
57
- ```ts
58
- import { expect, it } from 'vitest'
59
-
60
- it('toUpperCase', () => {
61
- const result = toUpperCase('foobar')
62
- expect(result).toMatchInlineSnapshot('"FOOBAR"')
63
- })
64
- ```
65
-
66
- This allows you to see the expected output directly without jumping across different files.
67
-
68
- ::: warning
69
- When using Snapshots with async concurrent tests, `expect` from the local [Test Context](/guide/test-context) must be used to ensure the right test is detected.
70
- :::
71
-
72
- ## Updating Snapshots
73
-
74
- When the received value doesn't match the snapshot, the test fails and shows you the difference between them. When the snapshot change is expected, you may want to update the snapshot from the current state.
75
-
76
- In watch mode, you can press the `u` key in the terminal to update the failed snapshot directly.
77
-
78
- Or you can use the `--update` or `-u` flag in the CLI to make Vitest update snapshots.
79
-
80
- ```bash
81
- vitest -u
82
- ```
83
-
84
- ### CI behavior
85
-
86
- By default, Vitest does not write snapshots in CI (`process.env.CI` is truthy) and any snapshot mismatches, missing snapshots, and obsolete snapshots fail the run. See [`update`](/config/update) for the details.
87
-
88
- An **obsolete snapshot** is a snapshot entry (or snapshot file) that no longer matches any collected test. This usually happens after removing or renaming tests.
89
-
90
- ## File Snapshots
91
-
92
- When calling `toMatchSnapshot()`, we store all snapshots in a formatted snap file. That means we need to escape some characters (namely the double-quote `"` and backtick `` ` ``) in the snapshot string. Meanwhile, you might lose the syntax highlighting for the snapshot content (if they are in some language).
93
-
94
- In light of this, we introduced [`toMatchFileSnapshot()`](/api/expect#tomatchfilesnapshot) to explicitly match against a file. This allows you to assign any file extension to the snapshot file, and makes them more readable.
95
-
96
- ```ts
97
- import { expect, it } from 'vitest'
98
-
99
- it('render basic', async () => {
100
- const result = renderHTML(h('div', { class: 'foo' }))
101
- await expect(result).toMatchFileSnapshot('./test/basic.output.html')
102
- })
103
- ```
104
-
105
- It will compare with the content of `./test/basic.output.html`. And can be written back with the `--update` flag.
106
-
107
- ## Visual Snapshots
108
-
109
- For visual regression testing of UI components and pages, Vitest provides built-in support through [browser mode](/guide/browser/) with the [`toMatchScreenshot()`](/api/browser/assertions#tomatchscreenshot) assertion:
110
-
111
- ```ts
112
- import { expect, test } from 'vitest'
113
- import { page } from 'vitest/browser'
114
-
115
- test('button looks correct', async () => {
116
- const button = page.getByRole('button')
117
- await expect(button).toMatchScreenshot('primary-button')
118
- })
119
- ```
120
-
121
- This captures screenshots and compares them against reference images to detect unintended visual changes. Learn more in the [Visual Regression Testing guide](/guide/browser/visual-regression-testing).
122
-
123
- ## ARIA Snapshots <Badge type="warning">experimental</Badge> <Version>4.1.4</Version>
124
-
125
- ARIA snapshots capture the accessibility tree of a DOM element and compare it against a stored template. Based on [Playwright's ARIA snapshots](https://playwright.dev/docs/aria-snapshots), they provide a semantic alternative to visual regression testing — asserting structure and meaning rather than pixels.
126
-
127
- For example, given this HTML:
128
-
129
- ```html
130
- <nav aria-label="Main">
131
- <a href="/">Home</a>
132
- <a href="/about">About</a>
133
- </nav>
134
- ```
135
-
136
- You can assert its accessibility tree:
137
-
138
- ```ts
139
- import { expect, test } from 'vitest'
140
- import { page } from 'vitest/browser'
141
-
142
- test('navigation structure', async () => {
143
- await expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(`
144
- - navigation "Main":
145
- - link "Home":
146
- - /url: /
147
- - link "About":
148
- - /url: /about
149
- `)
150
- })
151
- ```
152
-
153
- See the dedicated [ARIA Snapshots guide](/guide/browser/aria-snapshots) for syntax details, retry behavior in Browser Mode, and file vs. inline snapshot examples. See [`toMatchAriaSnapshot`](/api/expect#tomatcharisnapshot) and [`toMatchAriaInlineSnapshot`](/api/expect#tomatchariainlinesnapshot) for the full API reference.
154
-
155
- ## Custom Serializer
156
-
157
- You can add your own logic to alter how your snapshots are serialized. Like Jest, Vitest has default serializers for built-in JavaScript types, HTML elements, ImmutableJS and for React elements.
158
-
159
- You can explicitly add custom serializer by using [`expect.addSnapshotSerializer`](/api/expect#expect-addsnapshotserializer) API.
160
-
161
- ```ts
162
- expect.addSnapshotSerializer({
163
- serialize(val, config, indentation, depth, refs, printer) {
164
- // `printer` is a function that serializes a value using existing plugins.
165
- return `Pretty foo: ${printer(
166
- val.foo,
167
- config,
168
- indentation,
169
- depth,
170
- refs,
171
- )}`
172
- },
173
- test(val) {
174
- return val && Object.prototype.hasOwnProperty.call(val, 'foo')
175
- },
176
- })
177
- ```
178
-
179
- We also support [snapshotSerializers](/config/snapshotserializers) option to implicitly add custom serializers.
180
-
181
- ```ts [path/to/custom-serializer.ts]
182
- import { SnapshotSerializer } from 'vitest'
183
-
184
- export default {
185
- serialize(val, config, indentation, depth, refs, printer) {
186
- // `printer` is a function that serializes a value using existing plugins.
187
- return `Pretty foo: ${printer(
188
- val.foo,
189
- config,
190
- indentation,
191
- depth,
192
- refs,
193
- )}`
194
- },
195
- test(val) {
196
- return val && Object.prototype.hasOwnProperty.call(val, 'foo')
197
- },
198
- } satisfies SnapshotSerializer
199
- ```
200
-
201
- ```ts [vitest.config.ts]
202
- import { defineConfig } from 'vitest/config'
203
-
204
- export default defineConfig({
205
- test: {
206
- snapshotSerializers: ['path/to/custom-serializer.ts'],
207
- },
208
- })
209
- ```
210
-
211
- After adding a test like this:
212
-
213
- ```ts
214
- test('foo snapshot test', () => {
215
- const bar = {
216
- foo: {
217
- x: 1,
218
- y: 2,
219
- },
220
- }
221
-
222
- expect(bar).toMatchSnapshot()
223
- })
224
- ```
225
-
226
- You will get the following snapshot:
227
-
228
- ```
229
- Pretty foo: Object {
230
- "x": 1,
231
- "y": 2,
232
- }
233
- ```
234
-
235
- ## Custom Snapshot Matchers <Badge type="warning">experimental</Badge> <Version>4.1.3</Version> {#custom-snapshot-matchers}
236
-
237
- You can build custom snapshot matchers using the composable functions exposed on `Snapshots` from `vitest`. These let you transform values before snapshotting while preserving full snapshot lifecycle support (creation, update, inline rewriting).
238
-
239
- ```ts
240
- import { expect, test, Snapshots } from 'vitest'
241
-
242
- const { toMatchFileSnapshot, toMatchInlineSnapshot, toMatchSnapshot } = Snapshots
243
-
244
- expect.extend({
245
- toMatchTrimmedSnapshot(received: string) {
246
- return toMatchSnapshot.call(this, received.slice(0, 10))
247
- },
248
- toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {
249
- return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)
250
- },
251
- async toMatchTrimmedFileSnapshot(received: string, file: string) {
252
- return toMatchFileSnapshot.call(this, received.slice(0, 10), file)
253
- },
254
- })
255
-
256
- test('file snapshot', () => {
257
- // create __snapshots__/demo.test.ts with
258
- // > exports[`file snapshot 1`] = `"extra long"`
259
- expect('extra long string oh my gerd').toMatchTrimmedSnapshot(10)
260
- })
261
-
262
- test('inline snapshot', () => {
263
- expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot(`"super long"`)
264
- })
265
-
266
- test('raw file snapshot', async () => {
267
- // create raw-file.txt with:
268
- // > crazy long
269
- await expect('crazy long string oh my gerd').toMatchTrimmedFileSnapshot('./raw-file.txt')
270
- })
271
- ```
272
-
273
- The composables return `{ pass, message }` so you can further customize the error:
274
-
275
- ```ts
276
- import { Snapshots } from 'vitest'
277
-
278
- const { toMatchSnapshot } = Snapshots
279
-
280
- expect.extend({
281
- toMatchTrimmedSnapshot(received: string, length: number) {
282
- const result = toMatchSnapshot.call(this, received.slice(0, length))
283
- return { ...result, message: () => `Trimmed snapshot failed: ${result.message()}` }
284
- },
285
- })
286
- ```
287
-
288
- ::: warning
289
- For inline snapshot matchers, the snapshot argument must be the last parameter (or second-to-last when using property matchers). Vitest rewrites the last string argument in the source code, so custom arguments before the snapshot work, but custom arguments after it are not supported.
290
- :::
291
-
292
- ::: tip
293
- File snapshot matchers must be `async` — `toMatchFileSnapshot` returns a `Promise`. Remember to `await` the result in the matcher and in your test.
294
- :::
295
-
296
- ::: warning
297
- When custom inline snapshot matcher is aynchronous, Vitest cannot automatically infer the call location for inline snapshot rewriting. You must capture the call site by setting the `'error'` flag on the chai assertion object:
298
-
299
- ```ts
300
- import { expect, chai, Snapshots } from 'vitest'
301
-
302
- const { toMatchInlineSnapshot } = Snapshots
303
-
304
- expect.extend({
305
- async toMatchTransformedInlineSnapshot(received: string, inlineSnapshot?: string) {
306
- // capture call site synchronously at the top of matcher implementation
307
- chai.util.flag(this.assertion, 'error', new Error())
308
- const transformed = await transform(received)
309
- return toMatchInlineSnapshot.call(this, transformed, inlineSnapshot)
310
- },
311
- })
312
- ```
313
-
314
- :::
315
-
316
- For TypeScript, extend the `Assertion` interface:
317
-
318
- ```ts
319
- import 'vitest'
320
-
321
- declare module 'vitest' {
322
- interface Assertion<T = any> {
323
- toMatchTrimmedSnapshot: (length: number) => T
324
- toMatchTrimmedInlineSnapshot: (inlineSnapshot?: string) => T
325
- toMatchTrimmedFileSnapshot: (file: string) => Promise<T>
326
- }
327
- }
328
- ```
329
-
330
- ::: tip
331
- See [Extending Matchers](/guide/extending-matchers) for more on `expect.extend` and custom matcher conventions.
332
- :::
333
-
334
- ## Custom Snapshot Domain <Badge type="warning">experimental</Badge> <Version>4.1.4</Version> {#custom-snapshot-domain}
335
-
336
- Custom serializers control how values are _rendered_ into snapshot strings, but comparison is still string equality. A **domain snapshot adapter** goes further: it owns the entire comparison pipeline for a custom matcher, including how to capture a value, render it, parse a stored snapshot, and match them semantically.
337
-
338
- ### The adapter interface
339
-
340
- A domain adapter implements four methods and is generic over two types — `Captured` (what the value actually is) and `Expected` (what the stored snapshot parses into):
341
-
342
- ```ts
343
- import type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot'
344
-
345
- const myAdapter: DomainSnapshotAdapter<Captured, Expected> = {
346
- name: 'my-domain',
347
-
348
- // Extract structured data from the received value
349
- capture(received: unknown): Captured { /* ... */ },
350
-
351
- // Render captured data as the snapshot string (what gets stored)
352
- render(captured: Captured): string { /* ... */ },
353
-
354
- // Parse a stored snapshot string into a structured expected value
355
- parseExpected(input: string): Expected { /* ... */ },
356
-
357
- // Compare captured vs expected, return pass/fail and resolved output
358
- match(captured: Captured, expected: Expected): DomainMatchResult { /* ... */ },
359
- }
360
- ```
361
-
362
- #### `DomainMatchResult`
363
-
364
- The `match` method returns a `DomainMatchResult` with two optional string fields beyond `pass`:
365
-
366
- - **`resolved`** — the captured value viewed through the template's lens. Where the template uses patterns (e.g. regexes) or omits details, the resolved string adopts those patterns. Where the template doesn't match, it uses literal captured values. This serves as both the actual side of diffs and the value written on `--update`. When omitted, falls back to `render(capture(received))`.
367
-
368
- - **`expected`** — the stored template re-rendered as a string. Used as the expected side of diffs. When omitted, falls back to the raw snapshot string from the snap file or inline snapshot.
369
-
370
- :::details Why are `Captured` and `Expected` separate types?
371
-
372
- When a snapshot is first generated, `render(captured)` produces a plain string that gets stored. But once stored, the user can **hand-edit** it — replacing literals with regex patterns, relaxing assertions, or adding domain-specific query syntax. After editing, `parseExpected(input)` parses this modified string into a type that is _richer_ than what `capture` produces.
373
-
374
- For example, in the [key-value adapter](#example-key-value-adapter) below, `Captured` values are always `string`, but `Expected` values can be `string | RegExp`:
375
-
376
- ```ts
377
- type KVCaptured = Record<string, string>
378
- type KVExpected = Record<string, string | RegExp>
379
- ```
380
-
381
- This asymmetry is what makes `--update` work correctly: `match` returns a `resolved` string that updates changed literal parts while **preserving** the user's hand-edited patterns. If both sides were the same type, there would be no way to distinguish "what the value actually is" from "what the user chose to assert" — and every update would overwrite the user's patterns.
382
-
383
- :::
384
-
385
- ### Build a matcher from the adapter
386
-
387
- Register a custom matcher with `expect.extend(...)` and call the snapshot composables from `vitest`:
388
-
389
- ```ts [setup.ts]
390
- import { expect, Snaphsots } from 'vitest'
391
-
392
- expect.extend({
393
- toMatchMyDomainSnapshot(received: unknown) {
394
- return Snaphsots.toMatchDomainSnapshot.call(this, myAdapter, received)
395
- },
396
- toMatchMyDomainInlineSnapshot(received: unknown, inlineSnapshot?: string) {
397
- return Snaphsots.toMatchDomainInlineSnapshot.call(
398
- this,
399
- myAdapter,
400
- received,
401
- inlineSnapshot,
402
- )
403
- },
404
- })
405
- ```
406
-
407
- Then use your matcher in tests:
408
-
409
- ```ts
410
- expect(value).toMatchMyDomainSnapshot()
411
- expect(value).toMatchMyDomainInlineSnapshot(`key=value`)
412
- ```
413
-
414
- ### Example: key-value adapter
415
-
416
- A minimal adapter that stores objects as `key=value` lines, with regex pattern and subset key match support ([full source](https://github.com/vitest-dev/vitest/blob/main/test/snapshots/test/fixtures/domain/basic.ts)):
417
-
418
- ```ts [kv-adapter.ts]
419
- import type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot'
420
-
421
- type KVCaptured = Record<string, string>
422
- type KVExpected = Record<string, string | RegExp>
423
-
424
- function renderKV(obj: Record<string, unknown>) {
425
- return `\n${Object.entries(obj).map(([k, v]) => `${k}=${v}`).join('\n')}\n`
426
- }
427
-
428
- export const kvAdapter: DomainSnapshotAdapter<KVCaptured, KVExpected> = {
429
- name: 'kv',
430
-
431
- capture(received: unknown): KVCaptured {
432
- if (received && typeof received === 'object') {
433
- return Object.fromEntries(
434
- Object.entries(received).map(([k, v]) => [k, String(v)]),
435
- )
436
- }
437
- throw new TypeError('kv adapter expects a plain object')
438
- },
439
-
440
- render(captured: KVCaptured): string {
441
- return renderKV(captured)
442
- },
443
-
444
- parseExpected(input: string): KVExpected {
445
- const entries = input.trim().split('\n').map((line) => {
446
- const eq = line.indexOf('=')
447
- const key = line.slice(0, eq)
448
- const raw = line.slice(eq + 1)
449
- const value = (raw.startsWith('/') && raw.endsWith('/') && raw.length > 1)
450
- ? new RegExp(raw.slice(1, -1))
451
- : raw
452
- return [key, value]
453
- })
454
- return Object.fromEntries(entries)
455
- },
456
-
457
- match(captured: KVCaptured, expected: KVExpected): DomainMatchResult {
458
- const resolvedLines: string[] = []
459
- let pass = true
460
-
461
- for (const [key, actualValue] of Object.entries(captured)) {
462
- const expectedValue = expected[key]
463
-
464
- // non-asserted keys are skipped (works as subset match)
465
- if (typeof expectedValue === 'undefined') {
466
- continue
467
- }
468
-
469
- // preserve matched pattern for normalized diff and partial update
470
- if (expectedValue instanceof RegExp && expectedValue.test(actualValue)) {
471
- resolvedLines.push(`${key}=/${expectedValue.source}/`)
472
- continue
473
- }
474
-
475
- resolvedLines.push(`${key}=${actualValue}`)
476
- pass &&= actualValue === expectedValue
477
- }
478
-
479
- return {
480
- pass,
481
- message: pass ? undefined : 'KV entries do not match',
482
- resolved: `\n${resolvedLines.join('\n')}\n`,
483
- expected: `\n${renderKV(expected)}\n`,
484
- }
485
- },
486
- }
487
- ```
488
-
489
- ```ts [setup.ts]
490
- import { expect, Snapshots } from 'vitest'
491
- import { kvAdapter } from './kv-adapter'
492
-
493
- expect.extend({
494
- toMatchKvSnapshot(received: unknown) {
495
- return Snapshots.toMatchDomainSnapshot.call(this, kvAdapter, received)
496
- },
497
- toMatchKvInlineSnapshot(received: unknown, inlineSnapshot?: string) {
498
- return Snapshots.toMatchDomainInlineSnapshot.call(this, kvAdapter, received, inlineSnapshot)
499
- },
500
- })
501
- ```
502
-
503
- ```ts [example.test.ts]
504
- import { expect, test } from 'vitest'
505
-
506
- test('user data', () => {
507
- const user = { name: 'Alice', score: '42' }
508
- expect(user).toMatchKvSnapshot()
509
- })
510
-
511
- test('user data inline', () => {
512
- const user = { name: 'Alice', age: 100, score: '42' }
513
- expect(user).toMatchKvInlineSnapshot(`
514
- name=Alice
515
- score=/\\d+/
516
- `)
517
- })
518
- ```
519
-
520
- ## Difference from Jest
521
-
522
- Vitest provides an almost compatible Snapshot feature with [Jest's](https://jestjs.io/docs/snapshot-testing) with a few exceptions:
523
-
524
- #### 1. Comment header in the snapshot file is different
525
-
526
- ```diff
527
- - // Jest Snapshot v1, https://goo.gl/fbAQLP
528
- + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
529
- ```
530
-
531
- This does not really affect the functionality but might affect your commit diff when migrating from Jest.
532
-
533
- #### 2. `printBasicPrototype` is default to `false`
534
-
535
- Both Jest and Vitest snapshots are powered by `pretty-format`, but Vitest applies its own snapshot defaults on top of [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format). In particular, Vitest sets `printBasicPrototype` to `false` to provide a cleaner snapshot output, while in Jest <29.0.0 it is `true` by default.
536
-
537
- ```ts
538
- import { expect, test } from 'vitest'
539
-
540
- test('snapshot', () => {
541
- const bar = [
542
- {
543
- foo: 'bar',
544
- },
545
- ]
546
-
547
- // in Jest
548
- expect(bar).toMatchInlineSnapshot(`
549
- Array [
550
- Object {
551
- "foo": "bar",
552
- },
553
- ]
554
- `)
555
-
556
- // in Vitest
557
- expect(bar).toMatchInlineSnapshot(`
558
- [
559
- {
560
- "foo": "bar",
561
- },
562
- ]
563
- `)
564
- })
565
- ```
566
-
567
- We believe this is a more reasonable default for readability and overall DX. If you still prefer Jest's behavior, you can change your config:
568
-
569
- ```ts [vitest.config.ts]
570
- import { defineConfig } from 'vitest/config'
571
-
572
- export default defineConfig({
573
- test: {
574
- snapshotFormat: {
575
- printBasicPrototype: true,
576
- },
577
- },
578
- })
579
- ```
580
-
581
- #### 3. Chevron `>` is used as a separator instead of colon `:` for custom messages
582
-
583
- Vitest uses chevron `>` as a separator instead of colon `:` for readability, when a custom message is passed during creation of a snapshot file.
584
-
585
- For the following example test code:
586
- ```js
587
- test('toThrowErrorMatchingSnapshot', () => {
588
- expect(() => {
589
- throw new Error('error')
590
- }).toThrowErrorMatchingSnapshot('hint')
591
- })
592
- ```
593
-
594
- In Jest, the snapshot will be:
595
- ```console
596
- exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;
597
- ```
598
-
599
- In Vitest, the equivalent snapshot will be:
600
- ```console
601
- exports[`toThrowErrorMatchingSnapshot > hint 1`] = `[Error: error]`;
602
- ```
603
-
604
- #### 4. default `Error` snapshot is different for `toThrowErrorMatchingSnapshot` and `toThrowErrorMatchingInlineSnapshot`
605
-
606
- ```js
607
- import { expect, test } from 'vitest'
608
-
609
- test('snapshot', () => {
610
- // in Jest and Vitest
611
- expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`)
612
-
613
- // Jest snapshots `Error.message` for `Error` instance
614
- // Vitest prints the same value as toMatchInlineSnapshot
615
- expect(() => {
616
- throw new Error('error')
617
- }).toThrowErrorMatchingInlineSnapshot(`"error"`) // [!code --]
618
- }).toThrowErrorMatchingInlineSnapshot(`[Error: error]`) // [!code ++]
619
- })
620
- ```