vitest-plugin-vis 2.4.4 → 3.0.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 (264) hide show
  1. package/esm/client/actions/has_image_snapshot_action.d.ts +4 -0
  2. package/esm/client/actions/has_image_snapshot_action.d.ts.map +1 -0
  3. package/esm/client/actions/has_image_snapshot_action.js +6 -0
  4. package/esm/client/actions/load_image_snapshot_results_action.d.ts +3 -0
  5. package/esm/client/actions/load_image_snapshot_results_action.d.ts.map +1 -0
  6. package/esm/client/actions/load_image_snapshot_results_action.js +3 -0
  7. package/esm/client/actions/match_image_snapshot_action.d.ts +6 -0
  8. package/esm/client/actions/match_image_snapshot_action.d.ts.map +1 -0
  9. package/esm/client/actions/match_image_snapshot_action.js +20 -0
  10. package/esm/client/actions/match_page_image_snapshot_action.d.ts +6 -0
  11. package/esm/client/actions/match_page_image_snapshot_action.d.ts.map +1 -0
  12. package/esm/client/actions/match_page_image_snapshot_action.js +9 -0
  13. package/esm/client/auto_snapshot_options.d.ts +29 -0
  14. package/esm/client/auto_snapshot_options.d.ts.map +1 -0
  15. package/esm/client/auto_snapshot_options.js +49 -0
  16. package/esm/client/compare_image_snapshot.d.ts +6 -0
  17. package/esm/client/compare_image_snapshot.d.ts.map +1 -0
  18. package/esm/client/compare_image_snapshot.js +52 -0
  19. package/esm/client/{image_snapshot_matcher.logic.d.ts → compare_image_snapshot.logic.d.ts} +1 -1
  20. package/esm/client/compare_image_snapshot.logic.d.ts.map +1 -0
  21. package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -1
  22. package/esm/client/expect/to_match_image_snapshot.js +4 -3
  23. package/esm/client/image_resizer.d.ts.map +1 -1
  24. package/esm/client/image_snapshot_options.d.ts +2 -0
  25. package/esm/client/image_snapshot_options.d.ts.map +1 -0
  26. package/esm/client/image_snapshot_options.js +6 -0
  27. package/esm/client/page/augment.d.ts +2 -1
  28. package/esm/client/page/augment.d.ts.map +1 -1
  29. package/esm/client/page/extend.js +2 -1
  30. package/esm/client/page/has_image_snapshot.d.ts +6 -6
  31. package/esm/client/page/has_image_snapshot.d.ts.map +1 -1
  32. package/esm/client/page/has_image_snapshot.js +2 -11
  33. package/esm/client/page/to_match_image_snapshot.d.ts +8 -0
  34. package/esm/client/page/to_match_image_snapshot.d.ts.map +1 -0
  35. package/esm/client/page/to_match_image_snapshot.js +15 -0
  36. package/esm/client/setup/create_vis.d.ts +96 -0
  37. package/esm/client/setup/create_vis.d.ts.map +1 -0
  38. package/esm/{setup → client/setup}/create_vis.js +43 -31
  39. package/esm/client/setup/vis.ctx.d.ts +12 -0
  40. package/esm/client/setup/vis.ctx.d.ts.map +1 -0
  41. package/esm/client/setup/vis.ctx.js +32 -0
  42. package/esm/client/setup/vis.d.ts +5 -0
  43. package/esm/client/setup/vis.d.ts.map +1 -0
  44. package/esm/client/should_take_snapshot.d.ts +2 -9
  45. package/esm/client/should_take_snapshot.d.ts.map +1 -1
  46. package/esm/client/should_take_snapshot.js +1 -11
  47. package/esm/client/snapshot_meta.d.ts +6 -0
  48. package/esm/client/snapshot_meta.d.ts.map +1 -0
  49. package/esm/client/task_id.d.ts +0 -3
  50. package/esm/client/task_id.d.ts.map +1 -1
  51. package/esm/client/task_id.js +0 -3
  52. package/esm/client/vitest_suite_proxy.d.ts +2 -9
  53. package/esm/client/vitest_suite_proxy.d.ts.map +1 -1
  54. package/esm/client-api.d.ts +11 -0
  55. package/esm/client-api.d.ts.map +1 -0
  56. package/esm/client-api.js +8 -0
  57. package/esm/commands.d.ts +0 -1
  58. package/esm/commands.d.ts.map +1 -1
  59. package/esm/commands.js +0 -1
  60. package/esm/config/types.d.ts +22 -22
  61. package/esm/config/types.d.ts.map +1 -1
  62. package/esm/config/vis.d.ts +4 -3
  63. package/esm/config/vis.d.ts.map +1 -1
  64. package/esm/config/vis.js +3 -4
  65. package/esm/index.d.ts +1 -1
  66. package/esm/index.d.ts.map +1 -1
  67. package/esm/index.js +1 -1
  68. package/esm/presets/auto.d.ts +1 -2
  69. package/esm/presets/auto.d.ts.map +1 -1
  70. package/esm/presets/auto.js +8 -4
  71. package/esm/presets/enable.d.ts +1 -2
  72. package/esm/presets/enable.d.ts.map +1 -1
  73. package/esm/presets/enable.js +4 -4
  74. package/esm/presets/manual.d.ts +1 -2
  75. package/esm/presets/manual.d.ts.map +1 -1
  76. package/esm/presets/manual.js +3 -4
  77. package/esm/server/browser_provider/playwright.d.ts.map +1 -1
  78. package/esm/server/browser_provider/playwright.js +9 -3
  79. package/esm/server/browser_provider/types.d.ts +5 -1
  80. package/esm/server/browser_provider/types.d.ts.map +1 -1
  81. package/esm/server/browser_provider/webdriverio.d.ts.map +1 -1
  82. package/esm/server/browser_provider/webdriverio.js +7 -4
  83. package/esm/server/commands/augment.d.ts +11 -0
  84. package/esm/server/commands/augment.d.ts.map +1 -0
  85. package/esm/server/commands/augment.js +1 -0
  86. package/esm/server/commands/commands.d.ts +9 -0
  87. package/esm/server/commands/commands.d.ts.map +1 -0
  88. package/esm/server/commands/commands.js +14 -0
  89. package/esm/server/commands/has_image_snapshot.d.ts +2 -6
  90. package/esm/server/commands/has_image_snapshot.d.ts.map +1 -1
  91. package/esm/server/commands/has_image_snapshot.js +3 -3
  92. package/esm/server/commands/image_snapshot_next_index.d.ts +1 -1
  93. package/esm/server/commands/image_snapshot_next_index.d.ts.map +1 -1
  94. package/esm/server/commands/image_snapshot_next_index.js +2 -2
  95. package/esm/server/commands/load_image_snapshot_results.d.ts +21 -0
  96. package/esm/server/commands/load_image_snapshot_results.d.ts.map +1 -0
  97. package/esm/server/commands/load_image_snapshot_results.js +6 -0
  98. package/esm/server/commands/prepare_image_snapshot_comparison.d.ts +8 -10
  99. package/esm/server/commands/prepare_image_snapshot_comparison.d.ts.map +1 -1
  100. package/esm/server/commands/prepare_image_snapshot_comparison.js +11 -9
  101. package/esm/server/commands/prepare_page_image_snapshot_comparison.d.ts +35 -0
  102. package/esm/server/commands/prepare_page_image_snapshot_comparison.d.ts.map +1 -0
  103. package/esm/server/commands/prepare_page_image_snapshot_comparison.js +27 -0
  104. package/esm/server/commands/setup_vis_suite.d.ts +3 -3
  105. package/esm/server/commands/setup_vis_suite.d.ts.map +1 -1
  106. package/esm/server/commands/setup_vis_suite.js +2 -3
  107. package/esm/server/commands/types.d.ts +3 -0
  108. package/esm/server/commands/types.d.ts.map +1 -0
  109. package/esm/server/commands/types.js +1 -0
  110. package/esm/server/externals/file.d.ts +10 -0
  111. package/esm/server/externals/file.d.ts.map +1 -0
  112. package/esm/server/{file.js → externals/file.js} +12 -4
  113. package/esm/server/{commands/browser_command_context.d.ts → project.d.ts} +8 -3
  114. package/esm/server/project.d.ts.map +1 -0
  115. package/esm/server/{commands/browser_command_context.js → project.js} +2 -2
  116. package/esm/server/snapshot.d.ts +4 -5
  117. package/esm/server/snapshot.d.ts.map +1 -1
  118. package/esm/server/snapshot.js +15 -13
  119. package/esm/server/snapshot_path.d.ts +3 -3
  120. package/esm/server/snapshot_path.d.ts.map +1 -1
  121. package/esm/server/snapshot_path.js +12 -11
  122. package/esm/server/snapshot_writer.d.ts +13 -0
  123. package/esm/server/snapshot_writer.d.ts.map +1 -0
  124. package/esm/server/snapshot_writer.js +15 -0
  125. package/esm/server/suite.d.ts +53 -0
  126. package/esm/server/suite.d.ts.map +1 -0
  127. package/esm/server/suite.js +73 -0
  128. package/esm/server/vis_options.d.ts +18 -0
  129. package/esm/server/vis_options.d.ts.map +1 -0
  130. package/esm/server/vis_options.js +14 -0
  131. package/esm/server/vis_server_context.d.ts +50 -0
  132. package/esm/server/vis_server_context.d.ts.map +1 -0
  133. package/esm/server/{vis_context.ctx.d.ts → vis_server_context.deps.d.ts} +2 -2
  134. package/esm/server/vis_server_context.deps.d.ts.map +1 -0
  135. package/esm/server/{vis_context.ctx.js → vis_server_context.deps.js} +1 -1
  136. package/esm/server/vis_server_context.js +2 -0
  137. package/esm/server/{vis_context.logic.d.ts → vis_server_context.logic.d.ts} +12 -32
  138. package/esm/server/vis_server_context.logic.d.ts.map +1 -0
  139. package/esm/server/vis_server_context.logic.js +79 -0
  140. package/esm/server/{vis_context.types.d.ts → vis_server_context.types.d.ts} +6 -6
  141. package/esm/server/vis_server_context.types.d.ts.map +1 -0
  142. package/esm/server/vis_server_context.types.js +1 -0
  143. package/esm/server-utils.d.ts +3 -0
  144. package/esm/server-utils.d.ts.map +1 -0
  145. package/esm/server-utils.js +2 -0
  146. package/esm/setup.d.ts +2 -2
  147. package/esm/setup.d.ts.map +1 -1
  148. package/esm/setup.js +2 -2
  149. package/esm/shared/asserts.d.ts +2 -0
  150. package/esm/shared/asserts.d.ts.map +1 -0
  151. package/esm/shared/asserts.js +5 -0
  152. package/esm/shared/types.d.ts +22 -21
  153. package/esm/shared/types.d.ts.map +1 -1
  154. package/esm/testing/stubBrowserCommandContext.d.ts +1 -1
  155. package/esm/testing/stubBrowserCommandContext.d.ts.map +1 -1
  156. package/esm/testing/stubBrowserCommandContext.js +3 -13
  157. package/esm/testing/stubSuite.d.ts +10 -0
  158. package/esm/testing/stubSuite.d.ts.map +1 -0
  159. package/esm/testing/stubSuite.js +27 -0
  160. package/esm/testing/stubUserConfig.d.ts +7 -0
  161. package/esm/testing/stubUserConfig.d.ts.map +1 -0
  162. package/esm/testing/stubUserConfig.js +4 -0
  163. package/package.json +29 -28
  164. package/readme.md +409 -110
  165. package/src/client/actions/has_image_snapshot_action.ts +14 -0
  166. package/src/client/actions/load_image_snapshot_results_action.ts +5 -0
  167. package/src/client/actions/match_image_snapshot_action.ts +32 -0
  168. package/src/client/actions/match_page_image_snapshot_action.ts +20 -0
  169. package/src/client/auto_snapshot_options.ts +71 -0
  170. package/src/client/compare_image_snapshot.ts +84 -0
  171. package/src/client/expect/to_match_image_snapshot.ts +4 -3
  172. package/src/client/image_snapshot_options.ts +6 -0
  173. package/src/client/page/augment.ts +2 -1
  174. package/src/client/page/extend.ts +2 -1
  175. package/src/client/page/has_image_snapshot.ts +8 -21
  176. package/src/client/page/to_match_image_snapshot.ts +27 -0
  177. package/src/client/setup/create_vis.ts +227 -0
  178. package/src/client/setup/vis.ctx.ts +33 -0
  179. package/src/client/should_take_snapshot.ts +3 -13
  180. package/src/client/snapshot_meta.ts +7 -0
  181. package/src/client/task_id.ts +0 -3
  182. package/src/client/vitest_suite_proxy.ts +2 -5
  183. package/src/client-api.ts +11 -0
  184. package/src/commands.ts +0 -1
  185. package/src/config/types.ts +32 -27
  186. package/src/config/vis.ts +3 -5
  187. package/src/index.ts +1 -1
  188. package/src/presets/auto.ts +8 -4
  189. package/src/presets/enable.ts +4 -4
  190. package/src/presets/manual.ts +3 -4
  191. package/src/server/browser_provider/playwright.ts +9 -3
  192. package/src/server/browser_provider/types.ts +12 -1
  193. package/src/server/browser_provider/webdriverio.ts +7 -4
  194. package/src/server/commands/augment.ts +16 -0
  195. package/src/server/commands/commands.ts +15 -0
  196. package/src/server/commands/has_image_snapshot.ts +8 -6
  197. package/src/server/commands/image_snapshot_next_index.ts +5 -3
  198. package/src/server/commands/load_image_snapshot_results.ts +32 -0
  199. package/src/server/commands/prepare_image_snapshot_comparison.ts +20 -14
  200. package/src/server/commands/prepare_page_image_snapshot_comparison.ts +75 -0
  201. package/src/server/commands/setup_vis_suite.ts +17 -7
  202. package/src/server/commands/types.ts +9 -0
  203. package/src/server/externals/file.ts +21 -0
  204. package/src/server/{commands/browser_command_context.ts → project.ts} +2 -4
  205. package/src/server/snapshot.ts +23 -14
  206. package/src/server/snapshot_path.ts +15 -13
  207. package/src/server/snapshot_writer.ts +22 -0
  208. package/src/server/suite.ts +96 -0
  209. package/src/server/vis_options.ts +27 -0
  210. package/src/server/{vis_context.ctx.ts → vis_server_context.deps.ts} +1 -1
  211. package/src/server/vis_server_context.logic.ts +112 -0
  212. package/src/server/vis_server_context.ts +3 -0
  213. package/src/server/{vis_context.types.ts → vis_server_context.types.ts} +5 -5
  214. package/src/server-utils.ts +2 -0
  215. package/src/setup.ts +2 -2
  216. package/src/shared/asserts.ts +5 -0
  217. package/src/shared/types.ts +25 -23
  218. package/src/testing/stubBrowserCommandContext.ts +4 -14
  219. package/src/testing/stubSuite.ts +38 -0
  220. package/src/testing/stubUserConfig.ts +6 -0
  221. package/esm/client/image_snapshot_matcher.d.ts +0 -11
  222. package/esm/client/image_snapshot_matcher.d.ts.map +0 -1
  223. package/esm/client/image_snapshot_matcher.js +0 -80
  224. package/esm/client/image_snapshot_matcher.logic.d.ts.map +0 -1
  225. package/esm/client/snapshot_options.d.ts +0 -33
  226. package/esm/client/snapshot_options.d.ts.map +0 -1
  227. package/esm/client/snapshot_options.js +0 -37
  228. package/esm/client.d.ts +0 -8
  229. package/esm/client.d.ts.map +0 -1
  230. package/esm/client.js +0 -5
  231. package/esm/server/commands/browser_command_context.d.ts.map +0 -1
  232. package/esm/server/commands/extend.d.ts +0 -17
  233. package/esm/server/commands/extend.d.ts.map +0 -1
  234. package/esm/server/commands/extend.js +0 -12
  235. package/esm/server/commands/match_image_snapshot.d.ts +0 -18
  236. package/esm/server/commands/match_image_snapshot.d.ts.map +0 -1
  237. package/esm/server/commands/match_image_snapshot.js +0 -81
  238. package/esm/server/file.d.ts +0 -7
  239. package/esm/server/file.d.ts.map +0 -1
  240. package/esm/server/vis_context.ctx.d.ts.map +0 -1
  241. package/esm/server/vis_context.d.ts +0 -56
  242. package/esm/server/vis_context.d.ts.map +0 -1
  243. package/esm/server/vis_context.js +0 -2
  244. package/esm/server/vis_context.logic.d.ts.map +0 -1
  245. package/esm/server/vis_context.logic.js +0 -137
  246. package/esm/server/vis_context.types.d.ts.map +0 -1
  247. package/esm/setup/create_vis.d.ts +0 -53
  248. package/esm/setup/create_vis.d.ts.map +0 -1
  249. package/esm/setup/vis.d.ts +0 -5
  250. package/esm/setup/vis.d.ts.map +0 -1
  251. package/src/client/image_snapshot_matcher.ts +0 -121
  252. package/src/client/snapshot_options.ts +0 -82
  253. package/src/client.ts +0 -7
  254. package/src/server/commands/extend.ts +0 -25
  255. package/src/server/commands/match_image_snapshot.ts +0 -128
  256. package/src/server/file.ts +0 -13
  257. package/src/server/vis_context.logic.ts +0 -200
  258. package/src/server/vis_context.ts +0 -3
  259. package/src/setup/create_vis.ts +0 -154
  260. /package/esm/client/{image_snapshot_matcher.logic.js → compare_image_snapshot.logic.js} +0 -0
  261. /package/esm/{setup → client/setup}/vis.js +0 -0
  262. /package/esm/{server/vis_context.types.js → client/snapshot_meta.js} +0 -0
  263. /package/src/client/{image_snapshot_matcher.logic.ts → compare_image_snapshot.logic.ts} +0 -0
  264. /package/src/{setup → client/setup}/vis.ts +0 -0
package/readme.md CHANGED
@@ -8,7 +8,7 @@ Vitest visual testing plugin allowing you to capture and compare image snapshots
8
8
  It requires [Vitest Browser Mode][vitest-browser-mode] to work.
9
9
 
10
10
  This plugin is inspired by [`jest-image-snapshot`][jest-image-snapshot],
11
- and extracted from [`storybook-addon-vis`][storybook-addon-vis] for better modularity.
11
+ and extracted from [`storybook-addon-vis`][storybook-addon-vis] to use directly in Vitest.
12
12
 
13
13
  ## Install
14
14
 
@@ -22,7 +22,7 @@ yarn add --save-dev vitest-plugin-vis
22
22
 
23
23
  ## Config
24
24
 
25
- The `vitest-plugin-vis` plugin can be used without customization.
25
+ The [`vitest-plugin-vis`][vitest-plugin-vis] plugin can be used without customization.
26
26
 
27
27
  ```ts
28
28
  // vitest.config.ts
@@ -56,54 +56,36 @@ This default configuration will:
56
56
  - Use `pixelmatch` as the image comparison method.
57
57
  - Set config to compare image snapshot with a failure threshold of `0 pixels`.
58
58
  - Timeout for image comparison is set to `30000 ms`.
59
- - Local (non-CI) image snapshots are saved in the `<root>/__vis__/local` directory.
60
- - CI image snapshots are saved in the `<root>/__vis__/<process.platform>` directory.
61
- - Image snapshots of the current test run are saved in the `<root>/__vis__/*/__results__` directory.
62
- - Diff images are saved in the `<root>/__vis__/*/__diffs__` directory.
63
- - Baseline images are saved in the `<root>/__vis__/*/__baselines__` directory.
59
+ - Save image snapshots using the default directory structure.
64
60
 
65
- You can customize the configuration:
61
+ ### `preset`
62
+
63
+ The `preset` option set up typical visual testing scenarios.
66
64
 
67
65
  ```ts
68
66
  // vitest.config.ts
69
67
  import { defineConfig } from 'vitest/config'
70
- import { vis, trimCommonFolder } from 'vitest-plugin-vis/config'
68
+ import { vis } from 'vitest-plugin-vis/config'
71
69
 
72
70
  export default defineConfig({
73
71
  plugins: [
74
72
  vis({
75
- preset: 'auto',
76
- snapshotRootDir: ({
77
- ci, // true if running on CI
78
- platform, // process.platform
79
- providerName, // 'playwright' or 'webdriverio'
80
- browserName,
81
- screenshotFailures, // from `browser` config
82
- screenshotDirectory, // from `browser` config
83
- }) => `__vis__/${ci ? platform : 'local'}`,
84
- platform: '...', // {process.platform} or `local` (deprecated use `snapshotRootDir` instead)
85
- customizeSnapshotSubpath: (subpath) => trimCommonFolder(subpath),
86
- // will change to "isAutoSnapshot ? `${id}-auto` : `${id}-${index}`" in the next major release.
87
- customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-${index}`,
88
- // set a default subject (e.g. 'subject') to capture image snapshot
89
- subjectDataTestId: undefined,
90
- comparisonMethod: 'pixel',
91
- // pixelmatch or ssim.js options, depending on `comparisonMethod`.
92
- diffOptions: undefined,
93
- timeout: 30000,
94
- failureThresholdType: 'pixel',
95
- failureThreshold: 0,
73
+ preset: 'auto' // or 'manual' or 'none'
96
74
  })
97
75
  ],
98
- test: {
99
- browser: {/* ... */}
100
- }
101
76
  })
102
77
  ```
103
78
 
104
- If you want to do a custom snapshot at the end of each test,
105
- such as taking a snapshot for each theme,
106
- you can set it up using a custom setup file:
79
+ - `auto` (default): Automatically take a snapshot at the end of each rendering test.
80
+ - `manual`: You control which test(s) should take a snapshot automatically with the `setAutoSnapshotOptions()` function.
81
+ - `none`: Without preset. Set up your visual testing strategy in `vitest.setup.ts`.
82
+
83
+ When using the `auto` or `manual` preset,
84
+ manual snapshots are enabled. You can take manual snapshot using the `expect().toMatchImageSnapshot()` matcher,
85
+ or the `page.toMatchImageSnapshot()` for full page snapshot.
86
+
87
+ If you want to customize the snapshot behavior,
88
+ you can set the `preset` to `none` and configure your own snapshot strategy in `vitest.setup.ts`:
107
89
 
108
90
  ```ts
109
91
  // vitest.config.ts
@@ -123,31 +105,171 @@ export default defineConfig({
123
105
  // vitest.setup.ts
124
106
  import { vis } from 'vitest-plugin-vis/setup'
125
107
 
126
- // if you set `preset: none` in `vitest.config.ts`,
127
- // you can use a preset manually here.
128
-
129
- // Take snapshot at the end of each rendering test.
130
- vis.presets.auto()
131
- // Enable snapshot testing for manual snapshot only.
132
- vis.presets.manual()
133
- // Enable snapshot testing, allow auto snapshot with `setAutoSnapshotOptions()`
134
- vis.presets.enable()
135
-
136
- // Take image snapshot for each rendering test,
137
- // one snapshot per theme (light and dark in this example).
138
- //
139
- // Note that this changes the theme in the `afterEach` hook.
140
- // If you want to capture manual snapshots in different themes,
141
- // configure Vitest to run the tests in different themes.
142
- vis.presets.theme({
143
- async light() { document.body.classList.remove('dark') },
144
- async dark() { document.body.classList.add('dark') },
108
+ vis.setup({
109
+ auto: true,
110
+ auto: async ({ meta }) => meta['darkOnly'],
111
+ auto: {
112
+ async light() { document.body.classList.remove('dark') },
113
+ async dark() { document.body.classList.add('dark') },
114
+ }
115
+ })
116
+ ```
117
+
118
+ As seen in the example above,
119
+ you can configure the `auto` preset to:
120
+
121
+ - Enable/disable auto snapshot for all tests with `auto: true/false`,
122
+ - Perform some actions before the snapshot is taken,
123
+ - Skip certain snapshots for specific tests by returning `false` in the function,
124
+ - Take snapshots for different themes by providing an object.
125
+
126
+ ### Customizing snapshot path
127
+
128
+ Let's say you have this test:
129
+
130
+ ```ts
131
+ // src/components/MyComponent.spec.tsx
132
+
133
+ describe('MyComponent', () => {
134
+ describe('className', () => {
135
+ it('can customize className', () => {
136
+ // ...
137
+ })
138
+ })
139
+ })
140
+ ```
141
+
142
+ By default, when you run the test locally, the image snapshot will be saved in the following path:
143
+
144
+ ```sh
145
+ __vis__/local/__baselines__/components/MyComponent.spec.tsx/MyComponent/className/can-customize-className-auto.png
146
+ ```
147
+
148
+ This path can be broken down into a few parts:
149
+
150
+ > `__vis__/local`: `snapshotRootDir`
151
+
152
+ This is the `snapshotRootDir` where the image snapshots folders are placed.
153
+ When running on CI, the `snapshotRootDir` is default to `__vis__/<process.platform>`.
154
+
155
+ > `__baselines__`: baseline folder
156
+
157
+ This is the folder where the baseline images are saved and used for comparison.
158
+ There is also a `__results__` folder where the current test run images are saved,
159
+ and a `__diffs__` folder where the diff images are saved if the comparison fails.
160
+
161
+ > `components/MyComponent.spec.tsx`: `snapshotSubpath`
162
+
163
+ This is part of the path based on the path of the test file relative to the project root.
164
+ By default, the plugin will trim the common folder such as `src` or `test` from the path to reduce the path length.
165
+
166
+ If you place your test files in multiple folders,
167
+ such as in both `tests` and `src` folders,
168
+ and they might have files with the same name and create conflicting snapshots,
169
+ you can customize it.
170
+
171
+ > `MyComponent/className/can-customize-className`: `snapshotId`
172
+
173
+ This is the ID of the snapshot based on the test name and scope.
174
+ This is not customizable.
175
+
176
+ > `auto`: `snapshotKey`
177
+
178
+ This is the key of the snapshot.
179
+ In this case, it is `auto` because the snapshot is taken automatically at the end of the test.
180
+ If you take a manual snapshot, the key will be `0`, `1`, etc.
181
+ If you customize it when taking the snapshot,
182
+ the global customization will not be used.
183
+
184
+ You can customize the `snapshotRootDir`, `snapshotSubpath`, and `snapshotKey` with corresponding options:
185
+
186
+ ```ts
187
+ // vitest.config.ts
188
+ import { defineConfig } from 'vitest/config'
189
+ import { vis, trimCommonFolder } from 'vitest-plugin-vis/config'
190
+
191
+ export default defineConfig({
192
+ plugins: [
193
+ vis({
194
+ snapshotRootDir: ({
195
+ ci, // true if running on CI
196
+ platform, // process.platform
197
+ providerName, // 'playwright' or 'webdriverio'
198
+ browserName, // 'chromium', 'firefox', etc.
199
+ screenshotFailures, // from `browser` config
200
+ screenshotDirectory, // from `browser` config
201
+ }) => `__vis__/${ci ? platform : 'local'}`,
202
+ snapshotSubpath: ({ subpath }) => trimCommonFolder(subpath),
203
+ // Alphanumeric characters, and underscore are allowed. Dash is not allowed.
204
+ snapshotKey: 'auto',
205
+ })
206
+ ]
207
+ })
208
+ ```
209
+
210
+ ### Customizing auto snapshot subject
211
+
212
+ By default, auto snapshots are taken from the `document.body` element.
213
+
214
+ You can customize this globally by specifying your selector in the `subject` option:
215
+
216
+ ```ts
217
+ // vitest.config.ts
218
+ import { defineConfig } from 'vitest/config'
219
+ import { vis } from 'vitest-plugin-vis/config'
220
+
221
+ export default defineConfig({
222
+ plugins: [
223
+ vis({
224
+ subject: '[data-testid="subject"]'
225
+ })
226
+ ]
227
+ })
228
+ ```
229
+
230
+ You can also customize the subject per test using the `setAutoSnapshotOptions` function:
231
+
232
+ ```ts
233
+ // some.test.ts
234
+ import { page } from '@vitest/browser/context'
235
+ import { expect, it } from 'vitest'
236
+ import { render } from 'vitest-browser-react'
237
+ import { setAutoSnapshotOptions } from 'vitest-plugin-vis'
238
+
239
+ it('set your own subject', async () => {
240
+ setAutoSnapshotOptions({ subject: '[data-testid="subject"]' })
241
+ render(<div data-testid="subject">hello world</div>)
242
+ })
243
+ ```
244
+
245
+ ### Customizing snapshot comparison options
246
+
247
+ You can customize the snapshot comparison options globally in the config:
248
+
249
+ ```ts
250
+ // vitest.config.ts
251
+ import { defineConfig } from 'vitest/config'
252
+ import { vis } from 'vitest-plugin-vis/config'
253
+
254
+ export default defineConfig({
255
+ plugins: [
256
+ vis({
257
+ // set a default subject selector (e.g. `[data-testid="subject"]`) to capture image snapshot
258
+ subject: undefined,
259
+ comparisonMethod: 'pixel', // or 'ssim'
260
+ // pixelmatch or ssim.js options, depending on `comparisonMethod`.
261
+ diffOptions: undefined,
262
+ timeout: 30000,
263
+ failureThresholdType: 'pixel',
264
+ failureThreshold: 0,
265
+ })
266
+ ]
145
267
  })
146
268
  ```
147
269
 
148
270
  ### TypeScript Configuration
149
271
 
150
- The main usage of this addon is to use the `toMatchImageSnapshot` matcher.
272
+ The main usage of this add-on is to use the `toMatchImageSnapshot` matcher.
151
273
 
152
274
  Since it is exposed under the `expect` object of `vitest`,
153
275
  you typically do not need to import `vitest-plugin-vis` directly.
@@ -163,9 +285,27 @@ To address this, you can add the following to your `tsconfig.json`:
163
285
  }
164
286
  ```
165
287
 
288
+ Or use the triple-slash reference.
289
+
290
+ To do that, create a typing file, e.g. `types/vitest-plugin-vis.d.ts`:
291
+
292
+ ```ts
293
+ /// <reference types="vitest-plugin-vis" />
294
+ ```
295
+
296
+ Make sure to include this file in your `tsconfig.json`:
297
+
298
+ ```json
299
+ {
300
+ "files": ["types/vitest-plugin-vis.d.ts"],
301
+ // or
302
+ "include": ["src", "types"]
303
+ }
304
+ ```
305
+
166
306
  ## Usage
167
307
 
168
- ### Auto Preset
308
+ ### Automatic snapshots
169
309
 
170
310
  By default, the plugin will use the `auto` preset,
171
311
  which will take a snapshot at the end of each rendering test.
@@ -176,50 +316,37 @@ You can control how the auto snapshot is taken using the `setAutoSnapshotOptions
176
316
  import { setAutoSnapshotOptions } from 'vitest-plugin-vis'
177
317
  import { beforeEach, it } from 'vitest'
178
318
 
179
- beforeAll((suite) => {
319
+ beforeAll(() => {
180
320
  // Apply options to all tests in the current suite (file)
181
- setAutoSnapshotOptions(suite, /* options */)
182
- // or
183
321
  setAutoSnapshotOptions(/* options */)
184
322
  })
185
323
 
186
- beforeEach(({ task }) => {
324
+ beforeEach(() => {
187
325
  // Apply options to all tests in the current scope
188
- setAutoSnapshotOptions(task, /* options */)
189
- // or
190
326
  setAutoSnapshotOptions(/* options */)
191
327
  })
192
328
 
193
329
 
194
- it('disable snapshot per test', async ({ task }) => {
330
+ it('disable snapshot per test', async () => {
195
331
  // Apply options to this test only
196
- setAutoSnapshotOptions(task, /* options */)
197
- // or
198
332
  setAutoSnapshotOptions(/* options */)
199
333
  })
200
334
 
201
335
  describe('nested scope', () => {
202
- beforeEach(({ task }) => {
336
+ beforeEach(() => {
203
337
  // Apply options to all tests in the current scope
204
- setAutoSnapshotOptions(task, /* options */)
205
- // or
206
338
  setAutoSnapshotOptions(/* options */)
207
339
  })
208
340
  })
209
341
  ```
210
342
 
211
- The options are similar to `expect(...).toMatchImageSnapshot(options)`:
343
+ It supports options of `expect(...).toMatchImageSnapshot(options)`:
212
344
 
213
345
  ```ts
214
- // enable/disable auto snapshot
215
- setAutoSnapshotOptions(true /* or false */)
216
-
217
- // detailed options
218
346
  setAutoSnapshotOptions({
219
347
  enable: true,
220
348
  comparisonMethod: 'pixel',
221
- customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-custom-${index}`,
222
- // pixelmatch or ssim.js options, depending on `comparisonMethod`.
349
+ snapshotKey: 'auto',
223
350
  diffOptions: { threshold: 0.01 },
224
351
  failureThreshold: 0.01,
225
352
  failureThresholdType: 'percent',
@@ -227,6 +354,13 @@ setAutoSnapshotOptions({
227
354
  })
228
355
  ```
229
356
 
357
+ You can also enable/disable auto snapshot by passing boolean:
358
+
359
+ ```ts
360
+ // enable/disable auto snapshot
361
+ setAutoSnapshotOptions(true /* or false */)
362
+ ```
363
+
230
364
  You can also provide additional options, which you can use during theme to enable/disable snapshot for each theme:
231
365
 
232
366
  ```ts
@@ -235,38 +369,28 @@ setAutoSnapshotOptions({
235
369
  })
236
370
 
237
371
  // in vitest.setup.ts
238
- vis.presets.theme({
239
- async dark(options) {
240
- if (options.skipDark) return false
241
- document.body.classList.add('dark')
242
- },
372
+ vis.setup({
373
+ auto: {
374
+ async dark(options) {
375
+ if (options.skipDark) return false
376
+ document.body.classList.add('dark')
377
+ },
378
+ }
243
379
  })
244
380
  ```
245
381
 
246
- ### Manual Preset
382
+ ### Manual Snapshots
247
383
 
248
- You can also set the preset to `manual` and compare snapshots manually:
384
+ You can take snapshots manually:
249
385
 
250
386
  ```ts
251
- // vitest.config.ts
252
- import { defineConfig } from 'vitest/config'
253
-
254
- export default defineConfig({
255
- plugins: [
256
- vis({ preset: 'manual' })
257
- ],
258
- test:{
259
- browser: {/* ... */}
260
- }
261
- })
262
-
263
387
  // some.test.ts
264
- import 'vitest-browser-react' // do this in your setup file to get `page.render`
388
+ import { render } from 'vitest-browser-react'
265
389
  import { page } from '@vitest/browser/context'
266
390
  import { it } from 'vitest'
267
391
 
268
392
  it('manual snapshot', async ({ expect }) => {
269
- page.render(<div data-testid="subject">hello world</div>)
393
+ render(<div data-testid="subject">hello world</div>)
270
394
  await expect(document.body).toMatchImageSnapshot(/* options */)
271
395
  // or
272
396
  const subject = page.getByTestId('subject')
@@ -278,15 +402,15 @@ You can customize the snapshot comparison options per assertion:
278
402
 
279
403
  ```ts
280
404
  // some.test.ts
281
- import 'vitest-browser-react' // do this in your setup file to get `page.render`
405
+ import { render } from 'vitest-browser-react'
282
406
  import { page } from '@vitest/browser/context'
283
407
  import { it } from 'vitest'
284
408
 
285
409
  it('manual snapshot with options', async ({ expect }) => {
286
- page.render(<div data-testid="subject">hello world</div>)
410
+ render(<div data-testid="subject">hello world</div>)
287
411
  const subject = page.getByTestId('subject')
288
412
  await expect(subject).toMatchImageSnapshot({
289
- customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-custom-${index}`,
413
+ snapshotKey: 'custom',
290
414
  failureThreshold: 0.01,
291
415
  failureThresholdType: 'percent',
292
416
  diffOptions: {
@@ -297,20 +421,16 @@ it('manual snapshot with options', async ({ expect }) => {
297
421
  })
298
422
  ```
299
423
 
300
- ### Enable Preset
424
+ ### Full Page Snapshot
301
425
 
302
- The `enable` preset allows you to take manual snapshot,
303
- as well as auto snapshot at the end on a rendering test using the `setAutoSnapshotOptions` function:
426
+ You can also take a full page snapshot:
304
427
 
305
428
  ```ts
306
- import { setAutoSnapshotOptions } from 'vitest-plugin-vis'
307
- import { beforeEach, it } from 'vitest'
308
-
309
-
310
- it('take snapshot', async () => {
311
- setAutoSnapshotOptions(/* options */) // e.g. `true`
429
+ import { page } from '@vitest/browser/context'
430
+ import { it } from 'vitest'
312
431
 
313
- // ...your test...
432
+ it('full page snapshot', async () => {
433
+ await page.toMatchImageSnapshot({ fullPage: true })
314
434
  })
315
435
  ```
316
436
 
@@ -335,6 +455,47 @@ it('Has Snapshot', async ({ expect }) => {
335
455
 
336
456
  This is useful when you are performing negative test.
337
457
 
458
+ ### `webdriverio` Support
459
+
460
+ While Vitest Browser Mode supports both `playwright` and `webdriverio`,
461
+ `webdriverio` currently does not work well with visual testing.
462
+
463
+ There are two issues we are aware of:
464
+
465
+ > `element click intercepted: WebDriverError: element click intercepted: Element is not clickable at point`
466
+
467
+ This occurs in CI when `--window-size` is not set.
468
+ To work around this issue, you can set the `--window-size` flag in your config:
469
+
470
+ ```ts
471
+ // vitest.config.ts
472
+
473
+ export default {
474
+ test: {
475
+ browser: {
476
+ instances: [
477
+ {
478
+ browser: 'chrome',
479
+ capabilities: {
480
+ 'goog:chromeOptions': {
481
+ args: ['--window-size=1280,720']
482
+ }
483
+ }
484
+ }
485
+ ]
486
+ }
487
+ }
488
+ }
489
+ ```
490
+
491
+ > `fullPage` is not working
492
+
493
+ This occurs when the browser is in `headless` mode.
494
+ But even when it is not in `headless` mode,
495
+ the resulting snapshot is still not capturing the full page.
496
+
497
+ For the time being, we recommend using `playwright` for visual testing.
498
+
338
499
  ## Git Ignore
339
500
 
340
501
  The local snapshots, current run results, and diffs should be ignored by git.
@@ -362,6 +523,144 @@ When running on CI, the plugin will save the image snapshots in the `<root>/__vi
362
523
  The image snapshots are taken on the server side using `playwright` or `webdriverio` depending on your browser provider.
363
524
  It is recommended to run your tests serially to avoid flakiness.
364
525
 
526
+ ## Migrating from v2
527
+
528
+ [`vitest-plugin-vis`][vitest-plugin-vis] v3 is a number of breaking changes from v2.
529
+
530
+ If you are using `vitest-plugin-vis` v2,
531
+ you can follow the migration guide here to use v3.
532
+
533
+ > Preset changes
534
+
535
+ The `enable` and `manual` options are combined as `manual`.
536
+ The only difference between `enable` and `manual` was that `manual` was not capable to take automatic snapshot even when you use `setAutoSnapshotOptions` in your test.
537
+
538
+ > `platform` option is removed
539
+
540
+ The `platform` option is removed.
541
+ It is replaced with `snapshotRootDir` which takes a function to determine the snapshot root directory.
542
+
543
+ > `customizeSnapshotSubpath` is replaced with `snapshotSubpath`
544
+
545
+ The main difference is that `customizeSnapshotSubpath` receives the `subpath` as a string,
546
+ while `snapshotSubpath` receives `{ subpath: string }`.
547
+
548
+ This change allows us to expand it by adding more properties such as `viewport` in the future.
549
+
550
+ > `customizeSnapshotId` is replaced with `snapshotKey`
551
+
552
+ In v3, we need a stable snapshot ID to be able to identify snapshots originated from the same test.
553
+ We couldn't to that with `customizeSnapshotId`.
554
+
555
+ The `snapshotKey` has a reduced responsibility of only customizing the snapshot key,
556
+ which is added to the end of the snapshot filename.
557
+
558
+ Let's say you have a test file `src/components/x/x.test.ts`.
559
+ Within that file, you have a test:
560
+
561
+ ```ts
562
+ // src/components/x/x.test.ts
563
+
564
+ describe('some scope', () => {
565
+ it('should do something', () => {
566
+ // ...
567
+ })
568
+ })
569
+ ```
570
+
571
+ By default, the snapshot will be saved in the following path:
572
+
573
+ ```sh
574
+ // auto snapshot
575
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-auto.png
576
+
577
+ // manual snapshot
578
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-1.png
579
+
580
+ // auto snapshot map: `{ light() {...}, dark() {...} }`
581
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-light.png
582
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-dark.png
583
+ ```
584
+
585
+ The `snapshotKey` defined in your config or is `setAutoSnapshotOptions()` will affect the auto snapshot
586
+
587
+ ```ts
588
+ // vitest.config.ts
589
+ import { defineConfig } from 'vitest/config'
590
+
591
+ export default defineConfig({
592
+ plugins: [
593
+ vis({
594
+ snapshotKey: 'custom'
595
+ })
596
+ ]
597
+ })
598
+
599
+ // or
600
+ // src/components/x/x.test.ts
601
+
602
+ describe('some scope', () => {
603
+ it('should do something', () => {
604
+ setAutoSnapshotOptions({
605
+ snapshotKey: 'custom'
606
+ })
607
+ // ...
608
+ })
609
+ })
610
+ ```
611
+
612
+ ```sh
613
+ // auto snapshot
614
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-auto.png
615
+ // becomes
616
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-custom.png
617
+ ```
618
+
619
+ If you define a `snapshotKey` in your manual snapshot,
620
+ expectedly it will be used for that snapshot only.
621
+
622
+ ```ts
623
+ // src/components/x/x.test.ts
624
+
625
+ describe('some scope', () => {
626
+ it('should do something', () => {
627
+ expect(document.body).toMatchImageSnapshot({
628
+ snapshotKey: 'custom'
629
+ })
630
+ page.toMatchImageSnapshot({
631
+ snapshotKey: 'custom'
632
+ })
633
+ })
634
+ })
635
+ ```
636
+
637
+ ```sh
638
+ // manual snapshot
639
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-1.png
640
+ // becomes
641
+ __vis__/local/__baselines__/components/x/x.test.ts/some-scope/should-do-something-custom.png
642
+ ```
643
+
644
+ > `subjectDataTestId` is replaced with `subject`
645
+
646
+ If you are using `subjectDataTestId` in your config,
647
+ you can replace it with `subject` in your config.
648
+
649
+ ```ts
650
+ // vitest.config.ts
651
+ import { defineConfig } from 'vitest/config'
652
+ import { vis } from 'vitest-plugin-vis/config'
653
+
654
+ export default defineConfig({
655
+ plugins: [
656
+ vis({
657
+ // subjectDataTestId: 'subject'
658
+ subject: '[data-testid="subject"]'
659
+ })
660
+ ]
661
+ })
662
+ ```
663
+
365
664
  ## FAQ
366
665
 
367
666
  > feature X in [`jest-image-snapshot`][jest-image-snapshot] is missing
@@ -0,0 +1,14 @@
1
+ import type { HasImageSnapshotCommand, ImageSnapshotNextIndexCommand } from '../../commands.ts'
2
+ import type { ImageSnapshotKeyOptions } from '../../shared/types.ts'
3
+
4
+ export function hasImageSnapshotAction(
5
+ commands: ImageSnapshotNextIndexCommand & HasImageSnapshotCommand,
6
+ taskId: string,
7
+ options?: ImageSnapshotKeyOptions | undefined,
8
+ ) {
9
+ if (options?.snapshotKey?.includes('-')) {
10
+ throw new Error('Snapshot key cannot contain dash')
11
+ }
12
+
13
+ return commands.hasImageSnapshot(taskId, options?.snapshotKey)
14
+ }
@@ -0,0 +1,5 @@
1
+ import type { LoadImageSnapshotResultsCommand } from '../../server/commands/load_image_snapshot_results.ts'
2
+
3
+ export function loadImageSnapshotResultsAction(commands: LoadImageSnapshotResultsCommand, taskId: string) {
4
+ return commands.loadImageSnapshotResults(taskId)
5
+ }