vitest-plugin-vis 1.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 (204) hide show
  1. package/esm/client/ctx.d.ts +6 -0
  2. package/esm/client/ctx.d.ts.map +1 -0
  3. package/esm/client/ctx.js +7 -0
  4. package/esm/client/expect/expectation_result.d.ts +3 -0
  5. package/esm/client/expect/expectation_result.d.ts.map +1 -0
  6. package/esm/client/expect/expectation_result.js +5 -0
  7. package/esm/client/expect/extend.d.ts +8 -0
  8. package/esm/client/expect/extend.d.ts.map +1 -0
  9. package/esm/client/expect/extend.js +3 -0
  10. package/esm/client/expect/to_match_image_snapshot.d.ts +9 -0
  11. package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -0
  12. package/esm/client/expect/to_match_image_snapshot.js +32 -0
  13. package/esm/client/expect/to_match_image_snapshot.logic.d.ts +2 -0
  14. package/esm/client/expect/to_match_image_snapshot.logic.d.ts.map +1 -0
  15. package/esm/client/expect/to_match_image_snapshot.logic.js +11 -0
  16. package/esm/client/expect/to_match_image_snapshot.types.d.ts +7 -0
  17. package/esm/client/expect/to_match_image_snapshot.types.d.ts.map +1 -0
  18. package/esm/client/expect/to_match_image_snapshot.types.js +1 -0
  19. package/esm/client/page/extend.d.ts +6 -0
  20. package/esm/client/page/extend.d.ts.map +1 -0
  21. package/esm/client/page/extend.js +3 -0
  22. package/esm/client/page/has_image_snapshot.d.ts +10 -0
  23. package/esm/client/page/has_image_snapshot.d.ts.map +1 -0
  24. package/esm/client/page/has_image_snapshot.js +23 -0
  25. package/esm/client/selector.d.ts +9 -0
  26. package/esm/client/selector.d.ts.map +1 -0
  27. package/esm/client/selector.js +104 -0
  28. package/esm/client/should_take_snapshot.d.ts +10 -0
  29. package/esm/client/should_take_snapshot.d.ts.map +1 -0
  30. package/esm/client/should_take_snapshot.js +13 -0
  31. package/esm/client/snapshot_options.d.ts +34 -0
  32. package/esm/client/snapshot_options.d.ts.map +1 -0
  33. package/esm/client/snapshot_options.internal.d.ts +3 -0
  34. package/esm/client/snapshot_options.internal.d.ts.map +1 -0
  35. package/esm/client/snapshot_options.internal.js +20 -0
  36. package/esm/client/snapshot_options.js +16 -0
  37. package/esm/client/task_id.d.ts +7 -0
  38. package/esm/client/task_id.d.ts.map +1 -0
  39. package/esm/client/task_id.js +10 -0
  40. package/esm/client.d.ts +8 -0
  41. package/esm/client.d.ts.map +1 -0
  42. package/esm/client.js +5 -0
  43. package/esm/commands.d.ts +5 -0
  44. package/esm/commands.d.ts.map +1 -0
  45. package/esm/commands.js +4 -0
  46. package/esm/config/types.d.ts +35 -0
  47. package/esm/config/types.d.ts.map +1 -0
  48. package/esm/config/types.js +1 -0
  49. package/esm/config/vis.d.ts +25 -0
  50. package/esm/config/vis.d.ts.map +1 -0
  51. package/esm/config/vis.js +27 -0
  52. package/esm/config.d.ts +4 -0
  53. package/esm/config.d.ts.map +1 -0
  54. package/esm/config.js +2 -0
  55. package/esm/index.d.ts +2 -0
  56. package/esm/index.d.ts.map +1 -0
  57. package/esm/index.js +2 -0
  58. package/esm/presets/auto.d.ts +2 -0
  59. package/esm/presets/auto.d.ts.map +1 -0
  60. package/esm/presets/auto.js +3 -0
  61. package/esm/presets/manual.d.ts +2 -0
  62. package/esm/presets/manual.d.ts.map +1 -0
  63. package/esm/presets/manual.js +3 -0
  64. package/esm/server/browser_provider/browser_api.d.ts +3 -0
  65. package/esm/server/browser_provider/browser_api.d.ts.map +1 -0
  66. package/esm/server/browser_provider/browser_api.js +11 -0
  67. package/esm/server/browser_provider/playwright.d.ts +4 -0
  68. package/esm/server/browser_provider/playwright.d.ts.map +1 -0
  69. package/esm/server/browser_provider/playwright.js +13 -0
  70. package/esm/server/browser_provider/types.d.ts +6 -0
  71. package/esm/server/browser_provider/types.d.ts.map +1 -0
  72. package/esm/server/browser_provider/types.js +1 -0
  73. package/esm/server/browser_provider/webdriverio.d.ts +4 -0
  74. package/esm/server/browser_provider/webdriverio.d.ts.map +1 -0
  75. package/esm/server/browser_provider/webdriverio.js +10 -0
  76. package/esm/server/commands/extend.d.ts +15 -0
  77. package/esm/server/commands/extend.d.ts.map +1 -0
  78. package/esm/server/commands/extend.js +10 -0
  79. package/esm/server/commands/has_image_snapshot.d.ts +6 -0
  80. package/esm/server/commands/has_image_snapshot.d.ts.map +1 -0
  81. package/esm/server/commands/has_image_snapshot.js +7 -0
  82. package/esm/server/commands/image_snapshot_next_index.d.ts +9 -0
  83. package/esm/server/commands/image_snapshot_next_index.d.ts.map +1 -0
  84. package/esm/server/commands/image_snapshot_next_index.js +7 -0
  85. package/esm/server/commands/is_ci.d.ts +2 -0
  86. package/esm/server/commands/is_ci.d.ts.map +1 -0
  87. package/esm/server/commands/is_ci.js +6 -0
  88. package/esm/server/commands/match_image_snapshot.d.ts +17 -0
  89. package/esm/server/commands/match_image_snapshot.d.ts.map +1 -0
  90. package/esm/server/commands/match_image_snapshot.js +88 -0
  91. package/esm/server/commands/setup_vis_suite.d.ts +13 -0
  92. package/esm/server/commands/setup_vis_suite.d.ts.map +1 -0
  93. package/esm/server/commands/setup_vis_suite.js +4 -0
  94. package/esm/server/compare_image.d.ts +8 -0
  95. package/esm/server/compare_image.d.ts.map +1 -0
  96. package/esm/server/compare_image.js +16 -0
  97. package/esm/server/file.d.ts +6 -0
  98. package/esm/server/file.d.ts.map +1 -0
  99. package/esm/server/file.js +14 -0
  100. package/esm/server/snapshot_path.d.ts +4 -0
  101. package/esm/server/snapshot_path.d.ts.map +1 -0
  102. package/esm/server/snapshot_path.js +9 -0
  103. package/esm/server/vis_context.ctx.d.ts +29 -0
  104. package/esm/server/vis_context.ctx.d.ts.map +1 -0
  105. package/esm/server/vis_context.ctx.js +11 -0
  106. package/esm/server/vis_context.d.ts +33 -0
  107. package/esm/server/vis_context.d.ts.map +1 -0
  108. package/esm/server/vis_context.js +2 -0
  109. package/esm/server/vis_context.logic.d.ts +63 -0
  110. package/esm/server/vis_context.logic.d.ts.map +1 -0
  111. package/esm/server/vis_context.logic.js +116 -0
  112. package/esm/server/vis_context.types.d.ts +20 -0
  113. package/esm/server/vis_context.types.d.ts.map +1 -0
  114. package/esm/server/vis_context.types.js +1 -0
  115. package/esm/setup/create_vis.d.ts +39 -0
  116. package/esm/setup/create_vis.d.ts.map +1 -0
  117. package/esm/setup/create_vis.js +96 -0
  118. package/esm/setup/vis.d.ts +18 -0
  119. package/esm/setup/vis.d.ts.map +1 -0
  120. package/esm/setup/vis.js +6 -0
  121. package/esm/setup.d.ts +5 -0
  122. package/esm/setup.d.ts.map +1 -0
  123. package/esm/setup.js +7 -0
  124. package/esm/shared/base64.d.ts +2 -0
  125. package/esm/shared/base64.d.ts.map +1 -0
  126. package/esm/shared/base64.js +3 -0
  127. package/esm/shared/constants.d.ts +5 -0
  128. package/esm/shared/constants.d.ts.map +1 -0
  129. package/esm/shared/constants.js +4 -0
  130. package/esm/shared/convert_threshold_unit.d.ts +6 -0
  131. package/esm/shared/convert_threshold_unit.d.ts.map +1 -0
  132. package/esm/shared/convert_threshold_unit.js +10 -0
  133. package/esm/shared/get_max_size.d.ts +11 -0
  134. package/esm/shared/get_max_size.d.ts.map +1 -0
  135. package/esm/shared/get_max_size.js +5 -0
  136. package/esm/shared/is_same_size.d.ts +8 -0
  137. package/esm/shared/is_same_size.d.ts.map +1 -0
  138. package/esm/shared/is_same_size.js +3 -0
  139. package/esm/shared/trim_common_folder.d.ts +6 -0
  140. package/esm/shared/trim_common_folder.d.ts.map +1 -0
  141. package/esm/shared/trim_common_folder.js +10 -0
  142. package/esm/shared/types.d.ts +37 -0
  143. package/esm/shared/types.d.ts.map +1 -0
  144. package/esm/shared/types.js +1 -0
  145. package/esm/testing/constants.d.ts +9 -0
  146. package/esm/testing/constants.d.ts.map +1 -0
  147. package/esm/testing/constants.js +1933 -0
  148. package/esm/testing.d.ts +2 -0
  149. package/esm/testing.d.ts.map +1 -0
  150. package/esm/testing.js +1 -0
  151. package/package.json +115 -0
  152. package/readme.md +264 -0
  153. package/src/client/ctx.ts +8 -0
  154. package/src/client/expect/expectation_result.ts +7 -0
  155. package/src/client/expect/extend.ts +12 -0
  156. package/src/client/expect/to_match_image_snapshot.logic.ts +11 -0
  157. package/src/client/expect/to_match_image_snapshot.ts +43 -0
  158. package/src/client/expect/to_match_image_snapshot.types.ts +14 -0
  159. package/src/client/page/extend.ts +8 -0
  160. package/src/client/page/has_image_snapshot.ts +33 -0
  161. package/src/client/selector.ts +118 -0
  162. package/src/client/should_take_snapshot.ts +15 -0
  163. package/src/client/snapshot_options.internal.ts +22 -0
  164. package/src/client/snapshot_options.ts +53 -0
  165. package/src/client/task_id.ts +16 -0
  166. package/src/client.ts +7 -0
  167. package/src/commands.ts +4 -0
  168. package/src/config/readme.md +4 -0
  169. package/src/config/types.ts +35 -0
  170. package/src/config/vis.ts +30 -0
  171. package/src/config.ts +3 -0
  172. package/src/index.ts +2 -0
  173. package/src/presets/auto.ts +4 -0
  174. package/src/presets/manual.ts +4 -0
  175. package/src/server/browser_provider/browser_api.ts +13 -0
  176. package/src/server/browser_provider/playwright.ts +16 -0
  177. package/src/server/browser_provider/types.ts +11 -0
  178. package/src/server/browser_provider/webdriverio.ts +13 -0
  179. package/src/server/commands/extend.ts +19 -0
  180. package/src/server/commands/has_image_snapshot.ts +18 -0
  181. package/src/server/commands/image_snapshot_next_index.ts +17 -0
  182. package/src/server/commands/is_ci.ts +7 -0
  183. package/src/server/commands/match_image_snapshot.ts +139 -0
  184. package/src/server/commands/setup_vis_suite.ts +17 -0
  185. package/src/server/compare_image.ts +34 -0
  186. package/src/server/file.ts +15 -0
  187. package/src/server/readme.md +5 -0
  188. package/src/server/snapshot_path.ts +12 -0
  189. package/src/server/vis_context.ctx.ts +12 -0
  190. package/src/server/vis_context.logic.ts +141 -0
  191. package/src/server/vis_context.ts +3 -0
  192. package/src/server/vis_context.types.ts +25 -0
  193. package/src/setup/create_vis.ts +98 -0
  194. package/src/setup/vis.ts +7 -0
  195. package/src/setup.ts +9 -0
  196. package/src/shared/base64.ts +3 -0
  197. package/src/shared/constants.ts +4 -0
  198. package/src/shared/convert_threshold_unit.ts +13 -0
  199. package/src/shared/get_max_size.ts +5 -0
  200. package/src/shared/is_same_size.ts +3 -0
  201. package/src/shared/trim_common_folder.ts +10 -0
  202. package/src/shared/types.ts +39 -0
  203. package/src/testing/constants.ts +1936 -0
  204. package/src/testing.ts +1 -0
@@ -0,0 +1,6 @@
1
+ import { getCurrentTest } from 'vitest/suite';
2
+ export declare const ctx: {
3
+ getCurrentTest: typeof getCurrentTest;
4
+ __test__reset(): void;
5
+ };
6
+ //# sourceMappingURL=ctx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctx.d.ts","sourceRoot":"","sources":["../../src/client/ctx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,eAAO,MAAM,GAAG;;;CAKf,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { getCurrentTest } from 'vitest/suite';
2
+ export const ctx = {
3
+ getCurrentTest,
4
+ __test__reset() {
5
+ ctx.getCurrentTest = getCurrentTest;
6
+ },
7
+ };
@@ -0,0 +1,3 @@
1
+ import type { SyncExpectationResult } from '@vitest/expect';
2
+ export declare const success: SyncExpectationResult;
3
+ //# sourceMappingURL=expectation_result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expectation_result.d.ts","sourceRoot":"","sources":["../../../src/client/expect/expectation_result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,eAAO,MAAM,OAAO,EAAE,qBAIrB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export const success = {
2
+ pass: true,
3
+ /* v8 ignore next */
4
+ message: () => '',
5
+ };
@@ -0,0 +1,8 @@
1
+ import type { ImageSnapshotMatcher } from './to_match_image_snapshot.types.ts';
2
+ declare global {
3
+ namespace jest {
4
+ interface Matchers<R, T> extends ImageSnapshotMatcher {
5
+ }
6
+ }
7
+ }
8
+ //# sourceMappingURL=extend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/client/expect/extend.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAE9E,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,IAAI,CAAC;QAEd,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,oBAAoB;SAAG;KACxD;CACD"}
@@ -0,0 +1,3 @@
1
+ import { expect } from 'vitest';
2
+ import { toMatchImageSnapshot } from "./to_match_image_snapshot.js";
3
+ expect.extend({ toMatchImageSnapshot });
@@ -0,0 +1,9 @@
1
+ import type { AsyncExpectationResult } from '@vitest/expect';
2
+ import type { ToMatchImageSnapshotOptions } from './to_match_image_snapshot.types.ts';
3
+ export declare function toMatchImageSnapshot(
4
+ /**
5
+ * The element or locator to take the snapshot of,
6
+ * or the base64 value of the image to compare against.
7
+ */
8
+ subject: any, options?: ToMatchImageSnapshotOptions | undefined): AsyncExpectationResult;
9
+ //# sourceMappingURL=to_match_image_snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to_match_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/client/expect/to_match_image_snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAK5D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAA;AAErF,wBAAgB,oBAAoB;AACnC;;;GAGG;AACH,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,2BAA2B,GAAG,SAAS,GAC/C,sBAAsB,CAgBxB"}
@@ -0,0 +1,32 @@
1
+ import { commands } from '@vitest/browser/context';
2
+ import { ctx } from "../ctx.js";
3
+ import { toTaskId } from "../task_id.js";
4
+ import { success } from "./expectation_result.js";
5
+ import { parseImageSnapshotSubject } from "./to_match_image_snapshot.logic.js";
6
+ export function toMatchImageSnapshot(
7
+ /**
8
+ * The element or locator to take the snapshot of,
9
+ * or the base64 value of the image to compare against.
10
+ */
11
+ subject, options) {
12
+ const test = ctx.getCurrentTest();
13
+ if (!test) {
14
+ throw new Error('`toMatchImageSnapshot()` must be called in a test.');
15
+ }
16
+ if (test.concurrent) {
17
+ throw new Error('`toMatchImageSnapshot()` cannot be called in a concurrent test because ' +
18
+ "concurrent tests run at the same time in the same iframe and affect each other's environment. ");
19
+ }
20
+ const s = parseImageSnapshotSubject(subject);
21
+ const taskId = toTaskId(test);
22
+ return toMatchImageSnapshotAsync(taskId, s, options).then(() => success);
23
+ }
24
+ async function toMatchImageSnapshotAsync(taskId, subject, options) {
25
+ if (options?.customizeSnapshotId) {
26
+ const index = await commands.imageSnapshotNextIndex(taskId);
27
+ const { customizeSnapshotId, ...rest } = options;
28
+ const snapshotFileId = customizeSnapshotId(taskId, index);
29
+ return commands.matchImageSnapshot(taskId, subject, { ...rest, snapshotFileId });
30
+ }
31
+ return commands.matchImageSnapshot(taskId, subject, options);
32
+ }
@@ -0,0 +1,2 @@
1
+ export declare function parseImageSnapshotSubject(subject: any): any;
2
+ //# sourceMappingURL=to_match_image_snapshot.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to_match_image_snapshot.logic.d.ts","sourceRoot":"","sources":["../../../src/client/expect/to_match_image_snapshot.logic.ts"],"names":[],"mappings":"AAGA,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,GAAG,OAOrD"}
@@ -0,0 +1,11 @@
1
+ import { isBase64String } from "../../shared/base64.js";
2
+ import { convertElementToCssSelector } from "../selector.js";
3
+ export function parseImageSnapshotSubject(subject) {
4
+ if (subject instanceof Element)
5
+ return convertElementToCssSelector(subject);
6
+ if (subject?.['selector'])
7
+ return subject['selector'];
8
+ if (isBase64String(subject))
9
+ return subject;
10
+ throw new Error(`'toMatchImageSnapshot()' expects the subject to be an element, locator, or image encoded in base64 string, but got: ${subject}`);
11
+ }
@@ -0,0 +1,7 @@
1
+ import type { ImageSnapshotCompareOptions, ImageSnapshotIdOptions, ImageSnapshotTimeoutOptions } from '../../shared/types.ts';
2
+ export interface ImageSnapshotMatcher {
3
+ toMatchImageSnapshot(options?: ToMatchImageSnapshotOptions | undefined): Promise<void>;
4
+ }
5
+ export interface ToMatchImageSnapshotOptions extends ImageSnapshotTimeoutOptions, ImageSnapshotIdOptions, ImageSnapshotCompareOptions {
6
+ }
7
+ //# sourceMappingURL=to_match_image_snapshot.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to_match_image_snapshot.types.d.ts","sourceRoot":"","sources":["../../../src/client/expect/to_match_image_snapshot.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAE9B,MAAM,WAAW,oBAAoB;IACpC,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtF;AAED,MAAM,WAAW,2BAChB,SAAQ,2BAA2B,EAClC,sBAAsB,EACtB,2BAA2B;CAAG"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { type HasImageSnapshotAction } from './has_image_snapshot.ts';
2
+ declare module '@vitest/browser/context' {
3
+ interface BrowserPage extends HasImageSnapshotAction {
4
+ }
5
+ }
6
+ //# sourceMappingURL=extend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/client/page/extend.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,sBAAsB,EAAoB,MAAM,yBAAyB,CAAA;AAEvF,OAAO,QAAQ,yBAAyB,CAAC;IACxC,UAAU,WAAY,SAAQ,sBAAsB;KAAG;CACvD"}
@@ -0,0 +1,3 @@
1
+ import { page } from '@vitest/browser/context';
2
+ import { hasImageSnapshot } from "./has_image_snapshot.js";
3
+ page.extend({ hasImageSnapshot });
@@ -0,0 +1,10 @@
1
+ import { type BrowserPage } from '@vitest/browser/context';
2
+ import type { ImageSnapshotIdOptions } from '../../shared/types.ts';
3
+ export interface HasImageSnapshotAction {
4
+ hasImageSnapshot(this: BrowserPage, options?: ImageSnapshotIdOptions | undefined): Promise<boolean>;
5
+ }
6
+ /**
7
+ * Check if the snapshot image exists.
8
+ */
9
+ export declare function hasImageSnapshot(this: BrowserPage, options?: ImageSnapshotIdOptions | undefined): Promise<boolean>;
10
+ //# sourceMappingURL=has_image_snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/client/page/has_image_snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,yBAAyB,CAAA;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAInE,MAAM,WAAW,sBAAsB;IACtC,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,SAAS,oBAoB/F"}
@@ -0,0 +1,23 @@
1
+ import { commands } from '@vitest/browser/context';
2
+ import { ctx } from "../ctx.js";
3
+ import { toTaskId } from "../task_id.js";
4
+ /**
5
+ * Check if the snapshot image exists.
6
+ */
7
+ export function hasImageSnapshot(options) {
8
+ const test = ctx.getCurrentTest();
9
+ if (!test) {
10
+ throw new Error('`hasImageSnapshot()` must be called in a test.');
11
+ }
12
+ if (test.concurrent) {
13
+ throw new Error('`hasImageSnapshot()` cannot be called in a concurrent test because ' +
14
+ "concurrent tests run at the same time in the same iframe and affect each other's environment. ");
15
+ }
16
+ const taskId = toTaskId(test);
17
+ if (options?.customizeSnapshotId) {
18
+ return commands
19
+ .imageSnapshotNextIndex(taskId)
20
+ .then((index) => commands.hasImageSnapshot(taskId, options.customizeSnapshotId(taskId, index)));
21
+ }
22
+ return commands.hasImageSnapshot(taskId);
23
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Most of the code in this file is copied from Vitest.
3
+ *
4
+ * @see https://github.com/vitest-dev/vitest/blob/main/packages/browser/src/client/utils.ts
5
+ */
6
+ import type { Locator } from '@vitest/browser/context';
7
+ export declare function convertToSelector(elementOrLocator: Element | Locator): string;
8
+ export declare function convertElementToCssSelector(element: Element): string;
9
+ //# sourceMappingURL=selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/client/selector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEtD,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAW7E;AACD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,UAM3D"}
@@ -0,0 +1,104 @@
1
+ export function convertToSelector(elementOrLocator) {
2
+ if (!elementOrLocator) {
3
+ throw new Error('Expected element or locator to be defined.');
4
+ }
5
+ if (elementOrLocator instanceof Element) {
6
+ return convertElementToCssSelector(elementOrLocator);
7
+ }
8
+ if ('selector' in elementOrLocator) {
9
+ return elementOrLocator.selector;
10
+ }
11
+ throw new Error('Expected element or locator to be an instance of Element or Locator.');
12
+ }
13
+ export function convertElementToCssSelector(element) {
14
+ if (!element || !(element instanceof Element)) {
15
+ throw new Error(`Expected DOM element to be an instance of Element, received ${typeof element}`);
16
+ }
17
+ return getUniqueCssSelector(element);
18
+ }
19
+ function escapeIdForCSSSelector(id) {
20
+ return id
21
+ .split('')
22
+ .map((char) => {
23
+ const code = char.charCodeAt(0);
24
+ if (char === ' ' ||
25
+ char === '#' ||
26
+ char === '.' ||
27
+ char === ':' ||
28
+ char === '[' ||
29
+ char === ']' ||
30
+ char === '>' ||
31
+ char === '+' ||
32
+ char === '~' ||
33
+ char === '\\') {
34
+ // Escape common special characters with backslashes
35
+ return `\\${char}`;
36
+ }
37
+ if (code >= 0x10000) {
38
+ // Unicode escape for characters outside the BMP
39
+ return `\\${code.toString(16).toUpperCase().padStart(6, '0')} `;
40
+ }
41
+ if (code < 0x20 || code === 0x7f) {
42
+ // Non-printable ASCII characters (0x00-0x1F and 0x7F) are escaped
43
+ return `\\${code.toString(16).toUpperCase().padStart(2, '0')} `;
44
+ }
45
+ if (code >= 0x80) {
46
+ // Non-ASCII characters (0x80 and above) are escaped
47
+ return `\\${code.toString(16).toUpperCase().padStart(2, '0')} `;
48
+ }
49
+ // Allowable characters are used directly
50
+ return char;
51
+ })
52
+ .join('');
53
+ }
54
+ function getUniqueCssSelector(el) {
55
+ const path = [];
56
+ let parent;
57
+ let hasShadowRoot = false;
58
+ // eslint-disable-next-line no-cond-assign
59
+ while ((parent = getParent(el))) {
60
+ if (parent.shadowRoot) {
61
+ hasShadowRoot = true;
62
+ }
63
+ const tag = el.tagName;
64
+ if (el.id) {
65
+ path.push(`#${escapeIdForCSSSelector(el.id)}`);
66
+ }
67
+ else if (!el.nextElementSibling && !el.previousElementSibling) {
68
+ path.push(tag.toLowerCase());
69
+ }
70
+ else {
71
+ let index = 0;
72
+ let sameTagSiblings = 0;
73
+ let elementIndex = 0;
74
+ for (const sibling of parent.children) {
75
+ index++;
76
+ if (sibling.tagName === tag) {
77
+ sameTagSiblings++;
78
+ }
79
+ if (sibling === el) {
80
+ elementIndex = index;
81
+ }
82
+ }
83
+ if (sameTagSiblings > 1) {
84
+ path.push(`${tag.toLowerCase()}:nth-child(${elementIndex})`);
85
+ }
86
+ else {
87
+ path.push(tag.toLowerCase());
88
+ }
89
+ }
90
+ el = parent;
91
+ }
92
+ return `${getBrowserState().provider === 'webdriverio' && hasShadowRoot ? '>>>' : ''}${path.reverse().join(' > ')}`;
93
+ }
94
+ function getParent(el) {
95
+ const parent = el.parentNode;
96
+ if (parent instanceof ShadowRoot) {
97
+ return parent.host;
98
+ }
99
+ return parent;
100
+ }
101
+ function getBrowserState() {
102
+ // @ts-expect-error not typed global
103
+ return window.__vitest_browser_runner__;
104
+ }
@@ -0,0 +1,10 @@
1
+ import type { SnapshotMeta } from './snapshot_options.ts';
2
+ /**
3
+ * Determine should snapshot be taken.
4
+ *
5
+ * not story: false
6
+ * no `snapshot` tag: false
7
+ * disabled by `!snapshot` tag: false
8
+ */
9
+ export declare function shouldTakeSnapshot(meta?: SnapshotMeta | undefined): boolean;
10
+ //# sourceMappingURL=should_take_snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"should_take_snapshot.d.ts","sourceRoot":"","sources":["../../src/client/should_take_snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,WAGjE"}
@@ -0,0 +1,13 @@
1
+ import { ctx } from "./ctx.js";
2
+ import { getAutoSnapshotOptions } from "./snapshot_options.internal.js";
3
+ /**
4
+ * Determine should snapshot be taken.
5
+ *
6
+ * not story: false
7
+ * no `snapshot` tag: false
8
+ * disabled by `!snapshot` tag: false
9
+ */
10
+ export function shouldTakeSnapshot(meta) {
11
+ const m = meta ?? getAutoSnapshotOptions(ctx.getCurrentTest());
12
+ return document.body.childElementCount > 0 && m?.enable !== false;
13
+ }
@@ -0,0 +1,34 @@
1
+ import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts';
2
+ export type SnapshotMeta = ToMatchImageSnapshotOptions & {
3
+ enable?: boolean | undefined;
4
+ };
5
+ type Suite = {
6
+ meta: Record<string, any>;
7
+ suite?: Suite | undefined;
8
+ };
9
+ export type MetaTask = {
10
+ file?: {
11
+ meta: Record<string, any>;
12
+ } | undefined;
13
+ suite?: Suite | undefined;
14
+ meta: Record<string, any>;
15
+ } | undefined;
16
+ /**
17
+ * Set the snapshot options for auto snapshot.
18
+ *
19
+ * ```ts
20
+ * beforeAll((suite) => setAutoSnapshotOptions(suite, ...))
21
+ * beforeEach(({ task }) => setAutoSnapshotOptions(task, ...))
22
+ *
23
+ * it('...', ({ task }) => {
24
+ * setAutoSnapshotOptions(task, ...)
25
+ * })
26
+ * ```
27
+ *
28
+ * @param task Optional. Suite or task to set the options.
29
+ * If not provided, it will set the options for the current test.
30
+ */
31
+ export declare function setAutoSnapshotOptions(task: MetaTask, meta: SnapshotMeta | boolean): void;
32
+ export declare function setAutoSnapshotOptions(meta: SnapshotMeta | boolean): void;
33
+ export {};
34
+ //# sourceMappingURL=snapshot_options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot_options.d.ts","sourceRoot":"","sources":["../../src/client/snapshot_options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AAE5F,MAAM,MAAM,YAAY,GAAG,2BAA2B,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,CAAA;AAEzF,KAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;CAAE,CAAA;AAErE,MAAM,MAAM,QAAQ,GACjB;IACA,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IAChD,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACxB,GACD,SAAS,CAAA;AAEZ;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,IAAI,CAAA;AAC1F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,IAAI,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { MetaTask, SnapshotMeta } from './snapshot_options.ts';
2
+ export declare function getAutoSnapshotOptions(task: MetaTask): SnapshotMeta | undefined;
3
+ //# sourceMappingURL=snapshot_options.internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot_options.internal.d.ts","sourceRoot":"","sources":["../../src/client/snapshot_options.internal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEnE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,CAkB/E"}
@@ -0,0 +1,20 @@
1
+ import { NAME } from "../shared/constants.js";
2
+ export function getAutoSnapshotOptions(task) {
3
+ if (!task)
4
+ return;
5
+ const list = [];
6
+ let current = task;
7
+ while (current?.suite) {
8
+ list.unshift(current.suite.meta);
9
+ current = current.suite;
10
+ }
11
+ list.unshift(task.file?.meta);
12
+ list.push(task.meta);
13
+ return list.reduce((acc, cur) => {
14
+ if (cur?.[NAME]) {
15
+ const { [NAME]: meta } = cur;
16
+ return Object.assign({}, acc, meta);
17
+ }
18
+ return acc;
19
+ }, {});
20
+ }
@@ -0,0 +1,16 @@
1
+ import { NAME } from "../shared/constants.js";
2
+ import { ctx } from "./ctx.js";
3
+ export function setAutoSnapshotOptions(...args) {
4
+ const [task, meta] = parseArgs(args);
5
+ if (task)
6
+ task.meta[NAME] = {
7
+ ...task.meta[NAME],
8
+ ...meta,
9
+ };
10
+ }
11
+ function parseArgs(args) {
12
+ return args.length === 1 ? [ctx.getCurrentTest(), parseMeta(args[0])] : [args[0], parseMeta(args[1])];
13
+ }
14
+ function parseMeta(meta) {
15
+ return typeof meta === 'boolean' ? { enable: meta } : { enable: true, ...meta };
16
+ }
@@ -0,0 +1,7 @@
1
+ type Task = {
2
+ name: string;
3
+ suite?: Task | undefined;
4
+ };
5
+ export declare function toTaskId(task: Task): string;
6
+ export {};
7
+ //# sourceMappingURL=task_id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task_id.d.ts","sourceRoot":"","sources":["../../src/client/task_id.ts"],"names":[],"mappings":"AAAA,KAAK,IAAI,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACxB,CAAA;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,UAUlC"}
@@ -0,0 +1,10 @@
1
+ export function toTaskId(task) {
2
+ const l = [];
3
+ let t = task;
4
+ while (t?.suite) {
5
+ l.unshift(t.suite.name.replace(/[^a-z0-9]/gi, '-').toLowerCase());
6
+ t = t.suite;
7
+ }
8
+ l.push(task.name.replace(/[^a-z0-9]/gi, '-').toLowerCase());
9
+ return l.join('/');
10
+ }
@@ -0,0 +1,8 @@
1
+ export * from './client/expect/expectation_result.ts';
2
+ export * from './client/expect/to_match_image_snapshot.logic.ts';
3
+ export type * from './client/expect/to_match_image_snapshot.types.ts';
4
+ export * from './client/should_take_snapshot.ts';
5
+ export * from './client/snapshot_options.ts';
6
+ export * from './client/task_id.ts';
7
+ export type * from './shared/types.ts';
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AACrD,cAAc,kDAAkD,CAAA;AAChE,mBAAmB,kDAAkD,CAAA;AACrE,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,mBAAmB,mBAAmB,CAAA"}
package/esm/client.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./client/expect/expectation_result.js";
2
+ export * from "./client/expect/to_match_image_snapshot.logic.js";
3
+ export * from "./client/should_take_snapshot.js";
4
+ export * from "./client/snapshot_options.js";
5
+ export * from "./client/task_id.js";
@@ -0,0 +1,5 @@
1
+ export * from './server/commands/has_image_snapshot.ts';
2
+ export * from './server/commands/image_snapshot_next_index.ts';
3
+ export * from './server/commands/match_image_snapshot.ts';
4
+ export * from './server/commands/setup_vis_suite.ts';
5
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAA;AACvD,cAAc,gDAAgD,CAAA;AAC9D,cAAc,2CAA2C,CAAA;AACzD,cAAc,sCAAsC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from "./server/commands/has_image_snapshot.js";
2
+ export * from "./server/commands/image_snapshot_next_index.js";
3
+ export * from "./server/commands/match_image_snapshot.js";
4
+ export * from "./server/commands/setup_vis_suite.js";
@@ -0,0 +1,35 @@
1
+ import type { ToMatchImageSnapshotOptions } from '../client/expect/to_match_image_snapshot.types.ts';
2
+ export interface VisOptions extends ToMatchImageSnapshotOptions {
3
+ /**
4
+ * Loads the `test.setupFiles` of the specified preset.
5
+ */
6
+ preset?: 'manual' | 'auto' | 'none' | undefined;
7
+ /**
8
+ * The snapshot folder relative to the root of the project.
9
+ *
10
+ * Default: `__vis__`
11
+ */
12
+ snapshotRootDir?: string | undefined;
13
+ /**
14
+ * Customize the snapshot subpath.
15
+ *
16
+ * The snapshot subpath is used along with `snapshotRootDir` to determine the folder of the snapshots:
17
+ *
18
+ * - baseline: `<snapshotRootDir>/<platform>/<snapshotSubpath>/<snapshotId>.png`
19
+ * - result: `<snapshotRootDir>/__results__/<snapshotSubpath>/<snapshotId>.png`
20
+ * - diff: `<snapshotRootDir>/__diffs__/<snapshotSubpath>/<snapshotId>.png`
21
+ *
22
+ * Typically, you place your test files either in a dedicated `tests` folder or in the `src` folder along with your source code.
23
+ * By default, the snapshot subpath is the test file path with that folder removed to reduces nesting of the snapshot folders.
24
+ *
25
+ * If you place your test files in multiple folders,
26
+ * such as in both `tests` and `src` folders,
27
+ * and they might have files with the same name and create conflicting snapshots,
28
+ * you can set this to customize the snapshot subpath.
29
+ *
30
+ * @param subPath - The path of the test file to be used as the snapshot sub path.
31
+ * If you want to keep the full path, you can simply return it.
32
+ */
33
+ customizeSnapshotSubpath?: (subPath: string) => string;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,mDAAmD,CAAA;AAEpG,MAAM,WAAW,UAAW,SAAQ,2BAA2B;IAC9D;;OAEG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC/C;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;CACtD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { VisOptions } from './types.ts';
2
+ /**
3
+ * Create a Vite plugin for visual testing.
4
+ *
5
+ * If options are not provided, the plugin will use the default options,
6
+ * which enables the `auto` preset.
7
+ */
8
+ export declare function vis(options?: VisOptions): {
9
+ name: string;
10
+ config(this: void): {
11
+ test: {
12
+ browser: {
13
+ name: string;
14
+ commands: {
15
+ setupVisSuite: import("vitest/node").BrowserCommand<[]>;
16
+ imageSnapshotNextIndex: import("vitest/node").BrowserCommand<[taskId: string]>;
17
+ hasImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, snapshotId?: string | undefined]>;
18
+ matchImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, subject: string, options?: import("../commands.ts").MatchImageSnapshotOptions | undefined]>;
19
+ };
20
+ };
21
+ setupFiles: string[] | undefined;
22
+ };
23
+ };
24
+ };
25
+ //# sourceMappingURL=vis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis.d.ts","sourceRoot":"","sources":["../../src/config/vis.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,GAAE,UAA+B;;;;;sBASxB,MAAM;;;;;;;;;;;EAQzC"}
@@ -0,0 +1,27 @@
1
+ import { commands } from "../server/commands/extend.js";
2
+ import { visContext } from "../server/vis_context.js";
3
+ import { NAME } from "../shared/constants.js";
4
+ /**
5
+ * Create a Vite plugin for visual testing.
6
+ *
7
+ * If options are not provided, the plugin will use the default options,
8
+ * which enables the `auto` preset.
9
+ */
10
+ export function vis(options = { preset: 'auto' }) {
11
+ visContext.setOptions(options);
12
+ const preset = options?.preset;
13
+ return {
14
+ name: NAME,
15
+ config() {
16
+ return {
17
+ test: {
18
+ browser: {
19
+ name: undefined,
20
+ commands,
21
+ },
22
+ setupFiles: preset && preset !== 'none' ? [`vitest-plugin-vis/presets/${preset}`] : undefined,
23
+ },
24
+ };
25
+ },
26
+ };
27
+ }
@@ -0,0 +1,4 @@
1
+ export type * from './config/types.ts';
2
+ export * from './config/vis.ts';
3
+ export * from './shared/trim_common_folder.ts';
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,mBAAmB,mBAAmB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gCAAgC,CAAA"}
package/esm/config.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./config/vis.js";
2
+ export * from "./shared/trim_common_folder.js";
package/esm/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './client/snapshot_options.ts';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,8BAA8B,CAAA"}
package/esm/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // `vitest-plugin-vis` provides code that can be used in test files.
2
+ export * from "./client/snapshot_options.js";
@@ -0,0 +1,2 @@
1
+ import 'vitest-browser-react';
2
+ //# sourceMappingURL=auto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../../src/presets/auto.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAA"}