vitest-plugin-vis 4.2.2 → 5.1.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 (131) hide show
  1. package/dist/auto_snapshots/_extract_auto_snapshot_options.mjs +1 -1
  2. package/dist/auto_snapshots/_extract_auto_snapshot_options.mjs.map +1 -1
  3. package/dist/client/external/vitest/vitest_browser_context_proxy.mjs.map +1 -1
  4. package/dist/client/external/vitest/vitest_suite_proxy.d.mts +1 -3
  5. package/dist/client/external/vitest/vitest_suite_proxy.mjs +5 -5
  6. package/dist/client/external/vitest/vitest_suite_proxy.mjs.map +1 -1
  7. package/dist/client/page/_ctx.d.mts +1 -1
  8. package/dist/client/page/_ctx.mjs.map +1 -1
  9. package/dist/client/snapshot/compare_image_snapshot.logic.mjs +2 -1
  10. package/dist/client/snapshot/compare_image_snapshot.logic.mjs.map +1 -1
  11. package/dist/client/snapshot/compare_image_snapshot.mjs +1 -1
  12. package/dist/client/snapshot/compare_image_snapshot.mjs.map +1 -1
  13. package/dist/client/suite/auto_snapshot_matcher.d.mts +2 -2
  14. package/dist/client/suite/auto_snapshot_matcher.d.mts.map +1 -1
  15. package/dist/client/suite/auto_snapshot_matcher.mjs +4 -2
  16. package/dist/client/suite/auto_snapshot_matcher.mjs.map +1 -1
  17. package/dist/config/types.d.mts +15 -3
  18. package/dist/config/vis.mjs +1 -1
  19. package/dist/config/vis.mjs.map +1 -1
  20. package/dist/{client-api.d.mts → exports/client-api.d.mts} +12 -12
  21. package/dist/exports/client-api.mjs +11 -0
  22. package/dist/exports/config.d.mts +5 -0
  23. package/dist/exports/config.mjs +4 -0
  24. package/dist/exports/presets/auto.mjs +9 -0
  25. package/dist/exports/presets/auto.mjs.map +1 -0
  26. package/dist/exports/presets/manual.mjs +9 -0
  27. package/dist/exports/presets/manual.mjs.map +1 -0
  28. package/dist/exports/server-utils.d.mts +5 -0
  29. package/dist/exports/server-utils.mjs +6 -0
  30. package/dist/exports/setup-api.d.mts +4 -0
  31. package/dist/exports/setup-api.mjs +5 -0
  32. package/dist/exports/setup.d.mts +3 -0
  33. package/dist/exports/setup.mjs +4 -0
  34. package/dist/exports/testing/node.d.mts +4 -0
  35. package/dist/exports/testing/node.mjs +5 -0
  36. package/dist/exports/testing.d.mts +2 -0
  37. package/dist/exports/testing.mjs +3 -0
  38. package/dist/server/commands/prepare_image_snapshot_comparison.mjs.map +1 -1
  39. package/dist/server/commands/prepare_page_image_snapshot_comparison.mjs.map +1 -1
  40. package/dist/server/snapshot_path.d.mts +0 -1
  41. package/dist/server/snapshot_path.d.mts.map +1 -1
  42. package/dist/server/snapshot_path_limits.d.mts +28 -0
  43. package/dist/server/snapshot_path_limits.d.mts.map +1 -0
  44. package/dist/server/snapshot_path_limits.mjs +92 -0
  45. package/dist/server/snapshot_path_limits.mjs.map +1 -0
  46. package/dist/server/suite.mjs +8 -2
  47. package/dist/server/suite.mjs.map +1 -1
  48. package/dist/server/testing/stubBrowserCommandContext.mjs +9 -0
  49. package/dist/server/testing/stubBrowserCommandContext.mjs.map +1 -0
  50. package/dist/server/testing/stubSuite.d.mts +17 -0
  51. package/dist/server/testing/stubSuite.d.mts.map +1 -0
  52. package/dist/server/testing/stubSuite.mjs +23 -0
  53. package/dist/server/testing/stubSuite.mjs.map +1 -0
  54. package/dist/server/testing/stubUserConfig.mjs +8 -0
  55. package/dist/server/testing/stubUserConfig.mjs.map +1 -0
  56. package/dist/server/vis_options.d.mts +120 -0
  57. package/dist/server/vis_options.d.mts.map +1 -0
  58. package/dist/server/vis_options.mjs +7 -1
  59. package/dist/server/vis_options.mjs.map +1 -1
  60. package/dist/server/vis_server_context.logic.mjs +37 -10
  61. package/dist/server/vis_server_context.logic.mjs.map +1 -1
  62. package/dist/server/vis_server_context.types.d.mts +32 -2
  63. package/dist/server/vis_server_context.types.d.mts.map +1 -0
  64. package/dist/setup/create_vis.d.mts +1 -66
  65. package/dist/setup/create_vis.d.mts.map +1 -1
  66. package/dist/setup/create_vis.mjs +9 -45
  67. package/dist/setup/create_vis.mjs.map +1 -1
  68. package/dist/shared/types.d.mts +21 -1
  69. package/dist/shared/types.d.mts.map +1 -1
  70. package/package.json +22 -49
  71. package/readme.md +10 -4
  72. package/src/auto_snapshots/_extract_auto_snapshot_options.ts +1 -1
  73. package/src/client/expect/to_match_image_snapshot.mdx +24 -1
  74. package/src/client/external/vitest/vitest_browser_context_proxy.ts +2 -2
  75. package/src/client/external/vitest/vitest_suite_proxy.ts +6 -6
  76. package/src/client/page/_ctx.ts +2 -2
  77. package/src/client/page/to_match_image_snapshot.mdx +23 -1
  78. package/src/client/snapshot/compare_image_snapshot.logic.ts +1 -0
  79. package/src/client/snapshot/compare_image_snapshot.ts +2 -2
  80. package/src/client/suite/auto_snapshot_matcher.ts +9 -1
  81. package/src/config/types.ts +15 -3
  82. package/src/config/vis.ts +1 -1
  83. package/src/exports/client-api.ts +13 -0
  84. package/src/exports/config.ts +3 -0
  85. package/src/exports/presets/auto.ts +3 -0
  86. package/src/exports/presets/manual.ts +3 -0
  87. package/src/exports/server-utils.ts +7 -0
  88. package/src/exports/setup-api.ts +5 -0
  89. package/src/exports/setup.ts +3 -0
  90. package/src/exports/testing/node.ts +4 -0
  91. package/src/exports/testing.ts +1 -0
  92. package/src/server/commands/prepare_image_snapshot_comparison.ts +2 -2
  93. package/src/server/commands/prepare_page_image_snapshot_comparison.ts +2 -1
  94. package/src/server/snapshot_path_limits.ts +135 -0
  95. package/src/server/suite.ts +19 -4
  96. package/src/server/vis_options.ts +10 -1
  97. package/src/server/vis_server_context.logic.ts +47 -17
  98. package/src/setup/create_vis.mdx +2 -6
  99. package/src/setup/create_vis.ts +13 -123
  100. package/src/shared/types.ts +21 -1
  101. package/dist/client-api.mjs +0 -11
  102. package/dist/config.d.mts +0 -5
  103. package/dist/config.mjs +0 -4
  104. package/dist/presets/auto.mjs +0 -16
  105. package/dist/presets/auto.mjs.map +0 -1
  106. package/dist/presets/enable.d.mts +0 -1
  107. package/dist/presets/enable.mjs +0 -11
  108. package/dist/presets/enable.mjs.map +0 -1
  109. package/dist/presets/manual.mjs +0 -11
  110. package/dist/presets/manual.mjs.map +0 -1
  111. package/dist/server-utils.d.mts +0 -4
  112. package/dist/server-utils.mjs +0 -5
  113. package/dist/setup-api.d.mts +0 -4
  114. package/dist/setup-api.mjs +0 -5
  115. package/dist/setup.d.mts +0 -13
  116. package/dist/setup.d.mts.map +0 -1
  117. package/dist/setup.mjs +0 -13
  118. package/dist/setup.mjs.map +0 -1
  119. package/dist/testing.d.mts +0 -2
  120. package/dist/testing.mjs +0 -3
  121. package/src/client-api.ts +0 -13
  122. package/src/config.ts +0 -3
  123. package/src/presets/auto.ts +0 -9
  124. package/src/presets/enable.ts +0 -5
  125. package/src/presets/manual.ts +0 -5
  126. package/src/server-utils.ts +0 -3
  127. package/src/setup-api.ts +0 -5
  128. package/src/setup.ts +0 -10
  129. package/src/testing.ts +0 -1
  130. /package/dist/{presets → exports/presets}/auto.d.mts +0 -0
  131. /package/dist/{presets → exports/presets}/manual.d.mts +0 -0
@@ -79,6 +79,15 @@ type ToMatchImageSnapshotOptions<M extends ComparisonMethod = 'pixel'> = ImageSn
79
79
  * If it passes, it will throw an error with details.
80
80
  */
81
81
  expectToFail?: boolean | undefined;
82
+ /**
83
+ * Create a baseline image when none exists on disk.
84
+ *
85
+ * If `true`, the captured image is written to the baseline path and the assertion succeeds,
86
+ * without Vitest `-u` / `updateSnapshot: 'all'`.
87
+ *
88
+ * @default false
89
+ */
90
+ createMissingBaseline?: boolean | undefined;
82
91
  };
83
92
  interface PageImageSnapshotOptions {
84
93
  fullPage?: boolean | undefined;
@@ -120,9 +129,20 @@ type ImageSnapshotComparisonInfo = {
120
129
  */
121
130
  diff?: string | undefined;
122
131
  } & ImageSnapshotTimeoutOptions & FailureThresholdOptions & (SsimComparisonOptions | PixelComparisonOptions);
123
- type MatchImageSnapshotOptions = ImageSnapshotTimeoutOptions & ImageSnapshotCompareOptions<any> & ImageSnapshotKeyOptions;
132
+ type MatchImageSnapshotOptions = ImageSnapshotTimeoutOptions & ImageSnapshotCompareOptions<any> & ImageSnapshotKeyOptions & {
133
+ /**
134
+ * When `true`, write a missing baseline on first run (see {@link ToMatchImageSnapshotOptions} `createMissingBaseline`).
135
+ */
136
+ createMissingBaseline?: boolean | undefined;
137
+ };
124
138
  type SetupVisOptions<GM extends Record<string, any> | unknown = unknown> = {
125
139
  auto?: boolean | (<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void) | Record<string, boolean | (<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)>;
140
+ /**
141
+ * Default {@link ToMatchImageSnapshotOptions#createMissingBaseline} for auto snapshots.
142
+ *
143
+ * @default false
144
+ */
145
+ createMissingBaseline?: boolean | undefined;
126
146
  };
127
147
  //#endregion
128
148
  export { Awaitable, ComparisonMethod, FailureThresholdOptions, ImageSnapshotCompareOptions, ImageSnapshotComparisonInfo, ImageSnapshotKeyOptions, ImageSnapshotSubjectOptions, ImageSnapshotTimeoutOptions, MatchImageSnapshotOptions, PageImageSnapshotOptions, PixelComparisonOptions, PixelDiffOptions, SetupVisOptions, SnapshotTestMeta, SsimComparisonOptions, type SsimDiffOptions, ToMatchImageSnapshotOptions, ToMatchPageImageSnapshotOptions };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/shared/types.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,eAAe,IAAI,YAAY;UAE1B,2BAAA;EAFL;;;;;EAEK,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;AASjB;AAOY,UAPK,uBAAA,CAOW;EAEhB;AA6BZ;;EAKuB,WAAA,CAAA,EAAA,MAAA,GAAA,SAAA;;AAAD,KApCV,gBAAA,GAoCU,OAAA,GAAA,MAAA;AAKV,KAvCA,uBAAA,GAuCsB;EAQtB;AAEZ;;;;EACG,oBAAA,CAAA,EAAA,OAAA,GAAA,SAAA,GAAA,SAAA;EACuB;;;;AAG1B;AASA;;;;;;;AAUA;AAIA;;;;;;EAGY,gBAAA,CAAA,EAAgB,MAAA,GAAA,SAAA;CAEJ;AAAb,KArDC,qBAqDD,CAAA,IAAA,MAAA,CAAA,GAAA;EAAR,gBAAA,EApDgB,CAoDhB;EAAI;AAIP;;EA+BC,WAAA,CAAA,EAnFc,OAmFd,CAnFsB,eAmFtB,CAAA,GAAA,SAAA;CACC;AAA8C,KA/EpC,sBA+EoC,CAAA,IAAA,OAAA,CAAA,GAAA;EAEpC,gBAAA,CAAA,EAhFQ,CAgFR,GAAA,SAAyB;EAAG;;;EAEhB,WAAA,CAAA,EA9ET,gBA8ES,GAAA,SAAA;AAExB,CAAA;AAAuC,KA7E3B,gBAAA,GAAmB,UA6EQ,CAAA,OA7EU,UA6EV,CAAA,CAAA,CAAA,CAAA;AAGvB,KA9EJ,2BA8EI,CAAA,UA9EkC,gBA8ElC,GAAA,OAAA,CAAA,GAAA,CA9EiE,CA8EjE,SAAA,MAAA,GA7Eb,qBA6Ea,CA7ES,CA6ET,CAAA,GA5Eb,sBA4Ea,CA5EU,CA4EV,CAAA,CAAA,GA3Ef,uBA2Ee;AAA4B,KAzEhC,2BAAA,GAyEgC;EAClB;;;;;;EAKR,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;CAA4B;AAClB,KAvEhB,2BAuEgB,CAAA,UAvEsB,gBAuEtB,GAAA,OAAA,CAAA,GAvEoD,2BAuEpD,GAtE3B,uBAsE2B,GArE3B,2BAqE2B,CArEC,CAqED,CAAA,GAAA;EAAb;;;;EACe,YAAA,CAAA,EAAA,OAAA,GAAA,SAAA;CAL1B;AAAM,UAzDO,wBAAA,CAyDP;;;KArDE,0CAA0C,8BAA8B,4BAA4B,KAC/G;KAEW,gBAAA;;KAET,IAAA,IAAQ,aAAa;;;KAIZ,2BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BR,8BACH,2BACC,wBAAwB;KAEd,yBAAA,GAA4B,8BACvC,mCACA;KAEW,2BAA2B;+BAGvB,4BAA4B,kDAC/B,aAAa,KAAK,IAAI,OAC1B,mBAAmB,kCACxB,qCAGc,4BAA4B,kDAC/B,aAAa,KAAK,IAAI,OAC1B,mBAAmB"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/shared/types.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,eAAe,IAAI,YAAY;UAE1B,2BAAA;EAFL;;;;;EAEK,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;AASjB;AAOY,UAPK,uBAAA,CAOW;EAEhB;AA6BZ;;EAKuB,WAAA,CAAA,EAAA,MAAA,GAAA,SAAA;;AAAD,KApCV,gBAAA,GAoCU,OAAA,GAAA,MAAA;AAKV,KAvCA,uBAAA,GAuCsB;EAQtB;AAEZ;;;;EACG,oBAAA,CAAA,EAAA,OAAA,GAAA,SAAA,GAAA,SAAA;EACuB;;;;AAG1B;AASA;;;;;;;AAmBA;AAIA;;;;;;EAGY,gBAAA,CAAA,EAAgB,MAAA,GAAA,SAAA;CAEJ;AAAb,KA9DC,qBA8DD,CAAA,IAAA,MAAA,CAAA,GAAA;EAAR,gBAAA,EA7DgB,CA6DhB;EAAI;AAIP;;EA+BC,WAAA,CAAA,EA5Fc,OA4Fd,CA5FsB,eA4FtB,CAAA,GAAA,SAAA;CACC;AAA8C,KAxFpC,sBAwFoC,CAAA,IAAA,OAAA,CAAA,GAAA;EAEpC,gBAAA,CAAA,EAzFQ,CAyFR,GAAA,SAAyB;EAAG;;;EAEhB,WAAA,CAAA,EAvFT,gBAuFS,GAAA,SAAA;AAOxB,CAAA;AAAuC,KA3F3B,gBAAA,GAAmB,UA2FQ,CAAA,OA3FU,UA2FV,CAAA,CAAA,CAAA,CAAA;AAGvB,KA5FJ,2BA4FI,CAAA,UA5FkC,gBA4FlC,GAAA,OAAA,CAAA,GAAA,CA5FiE,CA4FjE,SAAA,MAAA,GA3Fb,qBA2Fa,CA3FS,CA2FT,CAAA,GA1Fb,sBA0Fa,CA1FU,CA0FV,CAAA,CAAA,GAzFf,uBAyFe;AAA4B,KAvFhC,2BAAA,GAuFgC;EAClB;;;;;;EAKR,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA;CAA4B;AAClB,KArFhB,2BAqFgB,CAAA,UArFsB,gBAqFtB,GAAA,OAAA,CAAA,GArFoD,2BAqFpD,GApF3B,uBAoF2B,GAnF3B,2BAmF2B,CAnFC,CAmFD,CAAA,GAAA;EAAb;;;;EACe,YAAA,CAAA,EAAA,OAAA,GAAA,SAAA;EAL1B;;;;;;;;;;UA9Da,wBAAA;;;KAIL,0CAA0C,8BAA8B,4BAA4B,KAC/G;KAEW,gBAAA;;KAET,IAAA,IAAQ,aAAa;;;KAIZ,2BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BR,8BACH,2BACC,wBAAwB;KAEd,yBAAA,GAA4B,8BACvC,mCACA;;;;;;KAOW,2BAA2B;+BAGvB,4BAA4B,kDAC/B,aAAa,KAAK,IAAI,OAC1B,mBAAmB,kCACxB,qCAGc,4BAA4B,kDAC/B,aAAa,KAAK,IAAI,OAC1B,mBAAmB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-plugin-vis",
3
- "version": "4.2.2",
3
+ "version": "5.1.0",
4
4
  "description": "Vitest visual testing plugin",
5
5
  "keywords": [
6
6
  "image-snapshot",
@@ -21,50 +21,23 @@
21
21
  "type": "module",
22
22
  "imports": {
23
23
  "#vitest-plugin-vis": "./src/index.ts",
24
- "#vitest-plugin-vis/client-api": "./src/client-api.ts",
25
- "#vitest-plugin-vis/config": "./src/config.ts",
26
- "#vitest-plugin-vis/setup": "./src/setup.ts"
24
+ "#vitest-plugin-vis/client-api": "./src/exports/client-api.ts",
25
+ "#vitest-plugin-vis/config": "./src/exports/config.ts",
26
+ "#vitest-plugin-vis/setup": "./src/exports/setup.ts",
27
+ "#vitest-plugin-vis/setup-api": "./src/exports/setup-api.ts",
28
+ "#vitest-plugin-vis/testing": "./src/exports/testing.ts",
29
+ "#vitest-plugin-vis/testing/node": "./src/exports/testing/node.ts"
27
30
  },
28
31
  "exports": {
29
32
  ".": {
33
+ "source": "./src/index.ts",
30
34
  "types": "./dist/index.d.mts",
31
35
  "default": "./dist/index.mjs"
32
36
  },
33
- "./config": {
34
- "types": "./dist/config.d.mts",
35
- "default": "./dist/config.mjs"
36
- },
37
- "./client-api": {
38
- "types": "./dist/client-api.d.mts",
39
- "default": "./dist/client-api.mjs"
40
- },
41
- "./presets/auto": {
42
- "types": "./dist/presets/auto.d.mts",
43
- "default": "./dist/presets/auto.mjs"
44
- },
45
- "./presets/enable": {
46
- "types": "./dist/presets/enable.d.mts",
47
- "default": "./dist/presets/enable.mjs"
48
- },
49
- "./presets/manual": {
50
- "types": "./dist/presets/manual.d.mts",
51
- "default": "./dist/presets/manual.mjs"
52
- },
53
- "./server-utils": {
54
- "types": "./dist/server-utils.d.mts",
55
- "default": "./dist/server-utils.mjs"
56
- },
57
- "./setup": {
58
- "types": "./dist/setup.d.mts",
59
- "default": "./dist/setup.mjs"
60
- },
61
- "./setup-api": {
62
- "types": "./dist/setup-api.d.mts",
63
- "default": "./dist/setup-api.mjs"
64
- },
65
- "./testing": {
66
- "types": "./dist/testing.d.mts",
67
- "default": "./dist/testing.mjs"
37
+ "./*": {
38
+ "source": "./src/exports/*.ts",
39
+ "types": "./dist/exports/*.d.mts",
40
+ "default": "./dist/exports/*.mjs"
68
41
  },
69
42
  "./package.json": "./package.json"
70
43
  },
@@ -97,13 +70,13 @@
97
70
  "@types/is-ci": "^3.0.4",
98
71
  "@types/pngjs": "^6.0.5",
99
72
  "@types/react": "^19.2.2",
100
- "@vitest/browser": "^4.0.16",
101
- "@vitest/browser-playwright": "^4.0.16",
102
- "@vitest/browser-webdriverio": "^4.0.16",
103
- "@vitest/coverage-istanbul": "^4.0.16",
104
- "@vitest/coverage-v8": "^4.0.16",
105
- "@vitest/expect": "^4.0.16",
106
- "@vitest/ui": "^4.0.16",
73
+ "@vitest/browser": "^4.1.4",
74
+ "@vitest/browser-playwright": "^4.1.4",
75
+ "@vitest/browser-webdriverio": "^4.1.4",
76
+ "@vitest/coverage-istanbul": "^4.1.4",
77
+ "@vitest/coverage-v8": "^4.1.4",
78
+ "@vitest/expect": "^4.1.4",
79
+ "@vitest/ui": "^4.1.4",
107
80
  "cross-env": "^10.0.0",
108
81
  "never-fail": "^1.1.4",
109
82
  "npm-run-all2": "^8.0.0",
@@ -113,9 +86,9 @@
113
86
  "storybook-addon-tag-badges": "^3.1.0",
114
87
  "tailwindcss": "^4.1.14",
115
88
  "tsdown": "^0.19.0",
116
- "typescript": "^5.9.3",
117
- "vite": "^7.3.0",
118
- "vitest": "^4.0.16",
89
+ "typescript": "^6.0.0",
90
+ "vite": "^8.0.0",
91
+ "vitest": "^4.1.4",
119
92
  "vitest-browser-react": "^2.0.2"
120
93
  },
121
94
  "peerDependencies": {
package/readme.md CHANGED
@@ -79,7 +79,7 @@ import { vis } from 'vitest-plugin-vis/config'
79
79
  export default defineConfig({
80
80
  plugins: [
81
81
  vis({
82
- preset: 'auto' // or 'manual' or 'none'
82
+ preset: 'auto' // or 'manual' or 'custom'
83
83
  })
84
84
  ],
85
85
  })
@@ -87,14 +87,14 @@ export default defineConfig({
87
87
 
88
88
  - `auto` (default): Automatically take a snapshot at the end of each rendering test.
89
89
  - `manual`: You control which test(s) should take a snapshot automatically with the `setAutoSnapshotOptions()` function.
90
- - `none`: Without preset. Set up your visual testing strategy in `vitest.setup.ts`.
90
+ - `custom`: No preset setup file from the plugin. Set up your visual testing strategy in `vitest.setup.ts`.
91
91
 
92
92
  When using the `auto` or `manual` preset,
93
93
  manual snapshots are enabled. You can take manual snapshot using the `expect().toMatchImageSnapshot()` matcher,
94
94
  or the `page.toMatchImageSnapshot()` for full page snapshot.
95
95
 
96
96
  If you want to customize the snapshot behavior,
97
- you can set the `preset` to `none` and configure your own snapshot strategy in `vitest.setup.ts`:
97
+ you can set the `preset` to `custom` and configure your own snapshot strategy in `vitest.setup.ts`:
98
98
 
99
99
  ```ts
100
100
  // vitest.config.ts
@@ -103,7 +103,7 @@ import { vis } from 'vitest-plugin-vis/config'
103
103
 
104
104
  export default defineConfig({
105
105
  plugins: [
106
- vis({ preset: 'none' })
106
+ vis({ preset: 'custom' })
107
107
  ],
108
108
  test: {
109
109
  browser: {/* ... */},
@@ -261,6 +261,10 @@ export default defineConfig({
261
261
  })
262
262
  ```
263
263
 
264
+ #### `shortenLongSnapshotPaths` (long absolute paths)
265
+
266
+ Defaults to `false`. When `true`, the plugin keeps legacy snapshot files as `taskId-key.png` and only adjusts the **`snapshotSubpath` segment** when needed: it builds **absolute** paths under `__baselines__` (after `snapshotRootDir` and your `snapshotSubpath`) plus representative snapshot filenames; if those would exceed typical Windows limits (length at least **250**, below classic `MAX_PATH` **260** with margin, or a path component longer than **255**), **directory segments stay as-is** and only the **final path component** (the file name derived from your test/story path) is shortened to `{firstToken}-{hash12}{ext}` — the first token is the substring before the first `.` in the basename (similar in spirit to [tersify](https://github.com/unional/tersify) terse labels). The same resolved subpath is used for **baselines**, **results**, and **diffs**. Your `snapshotRootDir` is not rewritten.
267
+
264
268
  #### Multiple browser instances
265
269
 
266
270
  When using multiple browser instances (e.g., different viewports or browsers),
@@ -451,6 +455,8 @@ setAutoSnapshotOptions({
451
455
  })
452
456
  ```
453
457
 
458
+ `createMissingBaseline` (on the matcher or on `vis.setup`) writes a missing baseline on the first run without `-u`. For auto snapshots, `vis.setup({ createMissingBaseline: true, auto: true })` applies a default; a test can override with `setAutoSnapshotOptions({ createMissingBaseline: false })` or equivalent meta.
459
+
454
460
  You can also enable/disable auto snapshot by passing boolean:
455
461
 
456
462
  ```ts
@@ -1,4 +1,4 @@
1
- import { NAME } from '../client-api.ts'
1
+ import { NAME } from '../exports/client-api.ts'
2
2
  import type { MetaTask } from './auto_snapshot_options.ts'
3
3
  import type { SnapshotMeta } from './snapshot_meta.ts'
4
4
 
@@ -72,6 +72,26 @@ it('should use custom snapshot key', async ({ expect }) => {
72
72
  })
73
73
  ```
74
74
 
75
+ #### `createMissingBaseline`
76
+
77
+ When `true`, if there is **no baseline image yet**,
78
+ the matcher writes the captured image to the baseline path and the assertion succeeds—without using Vitest's `-u` / `updateSnapshot` mode.
79
+ If a baseline already exists, `createMissingBaseline` does not change comparison behavior.
80
+
81
+ You can also set a default for **auto** snapshots with `vis.setup({ createMissingBaseline: true, auto: ... })`.
82
+ Per-test options from `setAutoSnapshotOptions` / test meta override that default when they set `createMissingBaseline` explicitly.
83
+
84
+ ```ts
85
+ it('creates baseline on first run with createMissingBaseline', async ({ expect }) => {
86
+ render(<MyComponent />)
87
+
88
+ await expect(document.body).toMatchImageSnapshot({
89
+ snapshotKey: 'first_run',
90
+ createMissingBaseline: true
91
+ })
92
+ })
93
+ ```
94
+
75
95
  ### Failure Threshold
76
96
 
77
97
  #### `failureThreshold` and `failureThresholdType`
@@ -258,7 +278,10 @@ it('should demonstrate all options', async ({ expect }) => {
258
278
  timeout: 45000,
259
279
 
260
280
  // Testing utility
261
- expectToFail: false
281
+ expectToFail: false,
282
+
283
+ // First-run baseline (optional)
284
+ createMissingBaseline: false
262
285
  })
263
286
  })
264
287
  ```
@@ -1,5 +1,5 @@
1
1
  import type { SerializedConfig } from 'vitest'
2
- import type { BrowserCommands, Platform } from 'vitest/browser'
2
+ import type { BrowserCommands } from 'vitest/browser'
3
3
 
4
4
  let ctx: Awaited<typeof import('vitest/browser')>
5
5
 
@@ -14,7 +14,7 @@ export const server = new Proxy<{
14
14
  * Platform the Vitest server is running on.
15
15
  * The same as calling `process.platform` on the server.
16
16
  */
17
- platform: Platform
17
+ platform: string
18
18
  /**
19
19
  * Runtime version of the Vitest server.
20
20
  * The same as calling `process.version` on the server.
@@ -1,14 +1,14 @@
1
1
  import type { SnapshotTestMeta } from '../../../shared/types.ts'
2
2
 
3
- let vitestSuite: Awaited<typeof import('vitest/suite')>
3
+ let vitest: Awaited<typeof import('vitest')>
4
4
 
5
5
  if ((globalThis as any).__vitest_browser__) {
6
- import('vitest/suite').then((m) => {
7
- vitestSuite = m
6
+ import('vitest').then((m) => {
7
+ vitest = m
8
8
  })
9
9
  }
10
10
 
11
- export type CurrentTest = ReturnType<typeof vitestSuite.getCurrentTest> & SnapshotTestMeta
11
+ export type CurrentTest = ReturnType<typeof vitest.TestRunner.getCurrentTest> & SnapshotTestMeta
12
12
 
13
- export const getCurrentTest = () => vitestSuite?.getCurrentTest() as CurrentTest
14
- export const getCurrentSuite = () => vitestSuite?.getCurrentSuite()
13
+ export const getCurrentTest = () => vitest?.TestRunner.getCurrentTest() as CurrentTest
14
+ export const getCurrentSuite = () => vitest?.TestRunner.getCurrentSuite()
@@ -1,10 +1,10 @@
1
- import { type BrowserPage, commands } from 'vitest/browser'
1
+ import { commands, type BrowserCommands, type BrowserPage } from 'vitest/browser'
2
2
  import { getCurrentTest } from '../external/vitest/vitest_suite_proxy.ts'
3
3
 
4
4
  export type { BrowserPage }
5
5
 
6
6
  export const ctx = {
7
- commands,
7
+ commands: commands as BrowserCommands,
8
8
  getCurrentTest,
9
9
  __test__reset() {
10
10
  ctx.getCurrentTest = getCurrentTest
@@ -68,6 +68,25 @@ it('should use custom snapshot key', async () => {
68
68
  })
69
69
  ```
70
70
 
71
+ #### `createMissingBaseline`
72
+
73
+ When `true`, if there is **no baseline image yet**,
74
+ the matcher writes the captured image to the baseline path and the assertion succeeds—without using Vitest's `-u` / `updateSnapshot` mode.
75
+ If a baseline already exists, `createMissingBaseline` does not change comparison behavior.
76
+
77
+ Defaults for **auto** snapshots can come from `vis.setup({ createMissingBaseline: true, auto: ... })`; per-test meta can override with an explicit `createMissingBaseline` value.
78
+
79
+ ```ts
80
+ it('creates page baseline on first run with createMissingBaseline', async () => {
81
+ render(<MyApp />)
82
+
83
+ await page.toMatchImageSnapshot({
84
+ snapshotKey: 'page_first_run',
85
+ createMissingBaseline: true
86
+ })
87
+ })
88
+ ```
89
+
71
90
  ### Failure Threshold
72
91
 
73
92
  #### `failureThreshold` and `failureThresholdType`
@@ -256,7 +275,10 @@ it('should demonstrate all page snapshot options', async () => {
256
275
  timeout: 45000,
257
276
 
258
277
  // Testing utility
259
- expectToFail: false
278
+ expectToFail: false,
279
+
280
+ // First-run baseline (optional)
281
+ createMissingBaseline: false
260
282
  })
261
283
  })
262
284
  ```
@@ -8,6 +8,7 @@ export function prettifyOptions(options: ToMatchImageSnapshotOptions<any> | unde
8
8
  options.timeout ? `timeout: ${options.timeout} ms` : '',
9
9
  `comparisonMethod: ${options.comparisonMethod ?? 'pixel'}`,
10
10
  options.diffOptions ? `diffOptions: ${JSON.stringify(options.diffOptions)}` : '',
11
+ options.createMissingBaseline ? 'createMissingBaseline: true' : '',
11
12
  ]
12
13
  .filter(Boolean)
13
14
  .join('\n ')
@@ -23,7 +23,7 @@ export async function compareImageSnapshot(
23
23
  const resultImage = await toImageData(info.result)
24
24
 
25
25
  if (!info.baseline) {
26
- if (server.config.snapshotOptions.updateSnapshot === 'all') {
26
+ if (server.config.snapshotOptions.updateSnapshot === 'all' || options?.createMissingBaseline === true) {
27
27
  await writeSnapshot(commands, resolve(info.projectRoot, info.baselinePath), resultImage)
28
28
  return
29
29
  }
@@ -45,7 +45,7 @@ export async function compareImageSnapshot(
45
45
  diffImage.data,
46
46
  width,
47
47
  height,
48
- options,
48
+ options as ToMatchImageSnapshotOptions<any>,
49
49
  )
50
50
  if (pass) {
51
51
  if (options?.expectToFail) {
@@ -2,7 +2,7 @@ import dedent from 'dedent'
2
2
  import { extractAutoSnapshotOptions } from '../../auto_snapshots/_extract_auto_snapshot_options.ts'
3
3
  import type { SnapshotMeta } from '../../auto_snapshots/snapshot_meta.ts'
4
4
  import type { SetupVisSuiteCommand } from '../../shared/commands.types.ts'
5
- import type { ComparisonMethod } from '../../shared/types.ts'
5
+ import type { ComparisonMethod, SetupVisOptions } from '../../shared/types.ts'
6
6
  import { shouldTakeSnapshot } from '../snapshot/should_take_snapshot.ts'
7
7
  import { toTaskId } from '../task/task_id.ts'
8
8
  import { ctx } from './_ctx.ts'
@@ -22,6 +22,7 @@ export function autoSnapshotMatcher<GM extends Record<string, any> | unknown = u
22
22
  string,
23
23
  boolean | ((options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)
24
24
  >,
25
+ suiteDefaults?: Pick<SetupVisOptions<GM>, 'createMissingBaseline'> | undefined,
25
26
  ) {
26
27
  return async function matchImageSnapshot() {
27
28
  const test = ctx.getCurrentTest()
@@ -35,9 +36,16 @@ export function autoSnapshotMatcher<GM extends Record<string, any> | unknown = u
35
36
  const theme = themes[themeId]
36
37
  const r = typeof theme === 'function' ? await theme(meta! as any) : theme
37
38
  if (r === false) continue
39
+ const effectiveCreateMissingBaseline =
40
+ meta != null && Object.hasOwn(meta as object, 'createMissingBaseline')
41
+ ? (meta as { createMissingBaseline?: boolean }).createMissingBaseline
42
+ : suiteDefaults?.createMissingBaseline
38
43
  await expect(getSubject(meta?.subject ?? subject)).toMatchImageSnapshot({
39
44
  ...meta,
40
45
  snapshotKey: meta?.snapshotKey ?? themeId,
46
+ ...(effectiveCreateMissingBaseline !== undefined
47
+ ? { createMissingBaseline: effectiveCreateMissingBaseline }
48
+ : {}),
41
49
  })
42
50
  } catch (error) {
43
51
  errors.push([themeId, error as Error])
@@ -35,10 +35,8 @@ export type VisOptions<M extends ComparisonMethod = 'pixel'> = (M extends 'ssim'
35
35
  * Loads the `test.setupFiles` of the specified preset.
36
36
  *
37
37
  * @default 'auto'
38
- * @deprecated 'enable' is deprecated. Use `manual` for the same effect.
39
- * @deprecated 'none' is deprecated. Use `custom` for the same effect.
40
38
  */
41
- preset?: 'enable' | 'manual' | 'auto' | 'custom' | 'none' | undefined
39
+ preset?: 'manual' | 'auto' | 'custom' | undefined
42
40
  /**
43
41
  * The snapshot folder relative to the root of the project.
44
42
  *
@@ -74,4 +72,18 @@ export type VisOptions<M extends ComparisonMethod = 'pixel'> = (M extends 'ssim'
74
72
  * @returns The customized snapshot subpath.
75
73
  */
76
74
  snapshotSubpath?: ((options: { subpath: string }) => string) | undefined
75
+ /**
76
+ * When `true`, shortenspaths that would exceed Windows-safe limits (full path length at
77
+ * least 250, below classic `MAX_PATH` 260, or a final path component longer than 255):
78
+ * - After `snapshotRootDir` and `snapshotSubpath`, if the path
79
+ * would exceed that budget, the **final** subpath segment is shortened to
80
+ * `{firstToken}-{hash12}{ext}` (tersify-style).
81
+ * - When writing a baseline, if the **actual** absolute path for the legacy `taskId-key.png` file would
82
+ * exceed the budget, only the final segment of that relative path is shortened the same way (nested
83
+ * `describe` directories from `taskId` stay as-is so `taskId-*.png` globs still work).
84
+ * `snapshotRootDir` itself is not rewritten.
85
+ *
86
+ * @default false
87
+ */
88
+ shortenLongSnapshotPaths?: boolean | undefined
77
89
  }
package/src/config/vis.ts CHANGED
@@ -23,7 +23,7 @@ export function vis<M extends ComparisonMethod = 'pixel'>(options: VisOptions<M>
23
23
  name: undefined,
24
24
  commands: commands as any,
25
25
  },
26
- setupFiles: preset && preset !== 'none' && preset !== 'custom' ? [`vitest-plugin-vis/presets/${preset}`] : [],
26
+ setupFiles: preset && preset !== 'custom' ? [`vitest-plugin-vis/presets/${preset}`] : [],
27
27
  },
28
28
  }
29
29
  },
@@ -0,0 +1,13 @@
1
+ import '../server/commands/augment.ts'
2
+
3
+ export * from '../auto_snapshots/auto_snapshot_options.ts'
4
+ export * from '../client/actions/has_image_snapshot_action.ts'
5
+ export * from '../client/actions/load_image_snapshot_results_action.ts'
6
+ export * from '../client/actions/match_image_snapshot_action.ts'
7
+ export * from '../client/actions/match_page_image_snapshot_action.ts'
8
+ export * from '../client/expect/expectation_result.ts'
9
+ export type * from '../client/expect/to_match_image_snapshot.types.ts'
10
+ export * from '../client/suite/auto_snapshot_matcher.ts'
11
+ export * from '../client/task/task_id.ts'
12
+ export * from '../shared/constants.ts'
13
+ export type * from '../shared/types.ts'
@@ -0,0 +1,3 @@
1
+ export type * from '../config/types.ts'
2
+ export * from '../config/vis.ts'
3
+ export * from '../shared/trim_common_folder.ts'
@@ -0,0 +1,3 @@
1
+ import { vis } from '../setup.ts'
2
+
3
+ vis.setup({ auto: true })
@@ -0,0 +1,3 @@
1
+ import { vis } from '../setup.ts'
2
+
3
+ vis.setup({ auto: false })
@@ -0,0 +1,7 @@
1
+ export { getSnapshotRootDir } from '../server/snapshot_path.ts'
2
+ export {
3
+ resolveLegacySnapshotFileRelativePath,
4
+ resolveSnapshotSubpathWithinLimits,
5
+ } from '../server/snapshot_path_limits.ts'
6
+ export { BASELINE_DIR, DIFF_DIR, SNAPSHOT_ROOT_DIR } from '../shared/constants.ts'
7
+ export { trimCommonFolder } from '../shared/trim_common_folder.ts'
@@ -0,0 +1,5 @@
1
+ // `vitest-plugin-vis/setup` provides code needed in `vitest.setup.ts`.
2
+ import '../client/expect/extend.ts'
3
+ import '../client/page/extend.ts'
4
+
5
+ export * from '../setup/create_vis.ts'
@@ -0,0 +1,3 @@
1
+ import './setup-api.ts'
2
+
3
+ export * from '../setup/vis.ts'
@@ -0,0 +1,4 @@
1
+ /** Node / Vitest project tests only — not safe for browser Vitest. */
2
+ export { stubSuite } from '../../server/testing/stubSuite.ts'
3
+ export { getVisOption } from '../../server/vis_options.ts'
4
+ export * from '../../testing/constants.ts'
@@ -0,0 +1 @@
1
+ export * from '../testing/constants.ts'
@@ -28,7 +28,7 @@ export const prepareImageSnapshotComparison: ExtendedBrowserCommand<
28
28
  ...info,
29
29
  projectRoot,
30
30
  result: subject,
31
- }
31
+ } as ImageSnapshotComparisonInfo
32
32
  }
33
33
 
34
34
  const resultBuffer = await takeSnapshot(context, projectRoot, info.resultPath, subject, options)
@@ -37,5 +37,5 @@ export const prepareImageSnapshotComparison: ExtendedBrowserCommand<
37
37
  projectRoot,
38
38
  baseline: baselineBuffer?.toString('base64'),
39
39
  result: resultBuffer.toString('base64'),
40
- }
40
+ } as ImageSnapshotComparisonInfo
41
41
  }
@@ -1,5 +1,6 @@
1
1
  import { resolve } from 'pathe'
2
2
  import type { PreparePageImageSnapshotComparisonCommand } from '../../shared/commands.types.ts'
3
+ import type { ImageSnapshotComparisonInfo } from '../../shared/types.ts'
3
4
  import { file } from '../externals/file.ts'
4
5
  import { getProjectRoot } from '../project.ts'
5
6
  import { takePageSnapshot } from '../snapshot.ts'
@@ -24,5 +25,5 @@ export const preparePageImageSnapshotComparison: ExtendedBrowserCommand<
24
25
  projectRoot,
25
26
  baseline: baselineBuffer?.toString('base64'),
26
27
  result: resultBuffer.toString('base64'),
27
- }
28
+ } as ImageSnapshotComparisonInfo
28
29
  }