vitest-plugin-vis 2.2.0 → 2.3.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 (52) hide show
  1. package/esm/client/ctx.d.ts +2 -2
  2. package/esm/client/ctx.d.ts.map +1 -1
  3. package/esm/client/ctx.js +2 -2
  4. package/esm/client/expect/to_match_image_snapshot.d.ts +1 -1
  5. package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -1
  6. package/esm/client/expect/to_match_image_snapshot.types.d.ts +1 -8
  7. package/esm/client/expect/to_match_image_snapshot.types.d.ts.map +1 -1
  8. package/esm/client/image_snapshot_matcher.d.ts +2 -3
  9. package/esm/client/image_snapshot_matcher.d.ts.map +1 -1
  10. package/esm/client/image_snapshot_matcher.js +6 -3
  11. package/esm/client/image_snapshot_matcher.logic.d.ts +1 -1
  12. package/esm/client/image_snapshot_matcher.logic.d.ts.map +1 -1
  13. package/esm/client/page/has_image_snapshot.d.ts.map +1 -1
  14. package/esm/client/page/has_image_snapshot.js +1 -1
  15. package/esm/client/should_take_snapshot.d.ts +1 -1
  16. package/esm/client/should_take_snapshot.d.ts.map +1 -1
  17. package/esm/client/should_take_snapshot.js +2 -2
  18. package/esm/client/snapshot_options.d.ts +2 -7
  19. package/esm/client/snapshot_options.d.ts.map +1 -1
  20. package/esm/client/snapshot_options.js +3 -6
  21. package/esm/client/vitest_suite_proxy.d.ts +2 -1
  22. package/esm/client/vitest_suite_proxy.d.ts.map +1 -1
  23. package/esm/client.d.ts +1 -1
  24. package/esm/client.d.ts.map +1 -1
  25. package/esm/index.d.ts +2 -1
  26. package/esm/index.d.ts.map +1 -1
  27. package/esm/server/vis_context.d.ts.map +1 -1
  28. package/esm/server/vis_context.logic.d.ts.map +1 -1
  29. package/esm/server/vis_context.logic.js +4 -0
  30. package/esm/setup/create_vis.d.ts +5 -5
  31. package/esm/setup/create_vis.d.ts.map +1 -1
  32. package/esm/setup/create_vis.js +6 -5
  33. package/esm/setup/vis.d.ts +1 -1
  34. package/esm/setup/vis.d.ts.map +1 -1
  35. package/esm/shared/types.d.ts +21 -0
  36. package/esm/shared/types.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/readme.md +4 -3
  39. package/src/client/ctx.ts +2 -2
  40. package/src/client/expect/to_match_image_snapshot.ts +1 -1
  41. package/src/client/expect/to_match_image_snapshot.types.ts +1 -16
  42. package/src/client/image_snapshot_matcher.logic.ts +1 -1
  43. package/src/client/image_snapshot_matcher.ts +12 -5
  44. package/src/client/page/has_image_snapshot.ts +6 -1
  45. package/src/client/should_take_snapshot.ts +3 -2
  46. package/src/client/snapshot_options.ts +6 -14
  47. package/src/client/vitest_suite_proxy.ts +3 -1
  48. package/src/client.ts +1 -1
  49. package/src/index.ts +2 -1
  50. package/src/server/vis_context.logic.ts +5 -1
  51. package/src/setup/create_vis.ts +19 -17
  52. package/src/shared/types.ts +22 -2
@@ -1,6 +1,6 @@
1
1
  export declare const ctx: {
2
- autoEnabled: boolean;
3
- getCurrentTest: () => import("vitest").RunnerTestCase<object> | undefined;
2
+ autoEnabled: boolean | undefined;
3
+ getCurrentTest: () => import("../index.ts").CurrentTest;
4
4
  getCurrentSuite: () => import("vitest").SuiteCollector<object>;
5
5
  __test__reset(): void;
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ctx.d.ts","sourceRoot":"","sources":["../../src/client/ctx.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;;;;;CASf,CAAA"}
1
+ {"version":3,"file":"ctx.d.ts","sourceRoot":"","sources":["../../src/client/ctx.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;iBACW,OAAO,GAAG,SAAS;;;;CAQ7C,CAAA"}
package/esm/client/ctx.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { getCurrentSuite, getCurrentTest } from "./vitest_suite_proxy.js";
2
2
  export const ctx = {
3
- autoEnabled: false,
3
+ autoEnabled: undefined,
4
4
  getCurrentTest,
5
5
  getCurrentSuite,
6
6
  __test__reset() {
7
7
  ctx.getCurrentTest = getCurrentTest;
8
8
  ctx.getCurrentSuite = getCurrentSuite;
9
- ctx.autoEnabled = false;
9
+ ctx.autoEnabled = undefined;
10
10
  },
11
11
  };
@@ -1,5 +1,5 @@
1
1
  import type { AsyncExpectationResult } from '@vitest/expect';
2
- import type { ToMatchImageSnapshotOptions } from './to_match_image_snapshot.types.ts';
2
+ import type { ToMatchImageSnapshotOptions } from '../../shared/types.ts';
3
3
  export declare function toMatchImageSnapshot(
4
4
  /**
5
5
  * The element or locator to take the snapshot of,
@@ -1 +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;AAI5D,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,CAcxB"}
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;AAC5D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAKxE,wBAAgB,oBAAoB;AACnC;;;GAGG;AACH,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,2BAA2B,GAAG,SAAS,GAC/C,sBAAsB,CAcxB"}
@@ -1,12 +1,5 @@
1
- import type { ComparisonMethod, ImageSnapshotCompareOptions, ImageSnapshotIdOptions, ImageSnapshotTimeoutOptions } from '../../shared/types.ts';
1
+ import type { ComparisonMethod, ToMatchImageSnapshotOptions } from '../../shared/types.ts';
2
2
  export interface ImageSnapshotMatcher {
3
3
  toMatchImageSnapshot<M extends ComparisonMethod>(options?: ToMatchImageSnapshotOptions<M> | undefined): Promise<void>;
4
4
  }
5
- export type ToMatchImageSnapshotOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTimeoutOptions & ImageSnapshotIdOptions & ImageSnapshotCompareOptions<M> & {
6
- /**
7
- * Expect the matcher to fail.
8
- * If it passes, it will throw an error with details.
9
- */
10
- expectToFail?: boolean | undefined;
11
- };
12
5
  //# sourceMappingURL=to_match_image_snapshot.types.d.ts.map
@@ -1 +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,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAE9B,MAAM,WAAW,oBAAoB;IACpC,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,EAAE,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrH;AAED,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,2BAA2B,GAC1G,sBAAsB,GACtB,2BAA2B,CAAC,CAAC,CAAC,GAAG;IAChC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAClC,CAAA"}
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,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAE1F,MAAM,WAAW,oBAAoB;IACpC,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,EAAE,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrH"}
@@ -1,9 +1,8 @@
1
- import type { Task } from 'vitest';
2
1
  import type { ImageSnapshotNextIndexCommand } from '../commands.ts';
3
2
  import type { PrepareImageSnapshotComparisonCommand } from '../server/commands/prepare_image_snapshot_comparison.ts';
4
3
  import type { WriteImageSnapshotCommand } from '../server/commands/write_image_snapshot.ts';
5
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts';
6
- export declare function imageSnapshotMatcher(commands: PrepareImageSnapshotComparisonCommand & WriteImageSnapshotCommand & ImageSnapshotNextIndexCommand): (test: Task, subject: any, options?: ToMatchImageSnapshotOptions<any>) => Promise<void>;
4
+ import type { CurrentTest, ToMatchImageSnapshotOptions } from '../shared/types.ts';
5
+ export declare function imageSnapshotMatcher(commands: PrepareImageSnapshotComparisonCommand & WriteImageSnapshotCommand & ImageSnapshotNextIndexCommand): (test: CurrentTest & {}, subject: any, options?: ToMatchImageSnapshotOptions<any>) => Promise<void>;
7
6
  /**
8
7
  * @deprecated internalized. Use `matchImageSnapshot` directly instead.
9
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"image_snapshot_matcher.d.ts","sourceRoot":"","sources":["../../src/client/image_snapshot_matcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAClC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yDAAyD,CAAA;AACpH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAA;AAI3F,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AAO5F,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,qCAAqC,GAAG,yBAAyB,GAAG,6BAA6B,UAE5D,IAAI,WAAW,GAAG,YAAY,2BAA2B,CAAC,GAAG,CAAC,mBAgE7G;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,GAAG,OAOrD"}
1
+ {"version":3,"file":"image_snapshot_matcher.d.ts","sourceRoot":"","sources":["../../src/client/image_snapshot_matcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yDAAyD,CAAA;AACpH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAA;AAG3F,OAAO,KAAK,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAQlF,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,qCAAqC,GAAG,yBAAyB,GAAG,6BAA6B,UAGpG,WAAW,GAAG,EAAE,WACb,GAAG,YACF,2BAA2B,CAAC,GAAG,CAAC,mBAoE3C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,GAAG,OAOrD"}
@@ -10,8 +10,11 @@ import { toTaskId } from "./task_id.js";
10
10
  import { server } from "./vitest_browser_context_proxy.js";
11
11
  export function imageSnapshotMatcher(commands) {
12
12
  return async function matchImageSnapshot(test, subject, options) {
13
+ const isAutoSnapshot = !!test.meta.vis?.isAutoSnapshot;
13
14
  const taskId = toTaskId(test);
14
- const info = await commands.prepareImageSnapshotComparison(taskId, parseImageSnapshotSubject(subject), options?.customizeSnapshotId ? await parseImageSnapshotOptions(commands, taskId, options) : options);
15
+ const info = await commands.prepareImageSnapshotComparison(taskId, parseImageSnapshotSubject(subject), options?.customizeSnapshotId
16
+ ? await parseImageSnapshotOptions(commands, taskId, isAutoSnapshot, options)
17
+ : options);
15
18
  if (!info)
16
19
  return;
17
20
  options = { ...info, ...options };
@@ -69,9 +72,9 @@ async function writeSnapshot(commands, path, image) {
69
72
  const content = (await toDataURL(image)).split(',')[1];
70
73
  return commands.writeImageSnapshot(path, content);
71
74
  }
72
- async function parseImageSnapshotOptions(commands, taskId, options) {
75
+ async function parseImageSnapshotOptions(commands, taskId, isAutoSnapshot, options) {
73
76
  const index = await commands.imageSnapshotNextIndex(taskId);
74
77
  const { customizeSnapshotId, ...rest } = options;
75
- const snapshotFileId = customizeSnapshotId({ id: taskId, index });
78
+ const snapshotFileId = customizeSnapshotId({ id: taskId, index, isAutoSnapshot });
76
79
  return { ...rest, snapshotFileId };
77
80
  }
@@ -1,3 +1,3 @@
1
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts';
1
+ import type { ToMatchImageSnapshotOptions } from '../shared/types.ts';
2
2
  export declare function prettifyOptions(options: ToMatchImageSnapshotOptions<any> | undefined): string;
3
3
  //# sourceMappingURL=image_snapshot_matcher.logic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image_snapshot_matcher.logic.d.ts","sourceRoot":"","sources":["../../src/client/image_snapshot_matcher.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AAE5F,wBAAgB,eAAe,CAAC,OAAO,EAAE,2BAA2B,CAAC,GAAG,CAAC,GAAG,SAAS,UAWpF"}
1
+ {"version":3,"file":"image_snapshot_matcher.logic.d.ts","sourceRoot":"","sources":["../../src/client/image_snapshot_matcher.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAErE,wBAAgB,eAAe,CAAC,OAAO,EAAE,2BAA2B,CAAC,GAAG,CAAC,GAAG,SAAS,UAWpF"}
@@ -1 +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"}
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,oBAyB/F"}
@@ -17,7 +17,7 @@ export function hasImageSnapshot(options) {
17
17
  if (options?.customizeSnapshotId) {
18
18
  return commands
19
19
  .imageSnapshotNextIndex(taskId)
20
- .then((index) => commands.hasImageSnapshot(taskId, options.customizeSnapshotId({ id: taskId, index })));
20
+ .then((index) => commands.hasImageSnapshot(taskId, options.customizeSnapshotId({ id: taskId, index, isAutoSnapshot: !!test.meta.vis?.isAutoSnapshot })));
21
21
  }
22
22
  return commands.hasImageSnapshot(taskId);
23
23
  }
@@ -1,4 +1,4 @@
1
- import { type SnapshotMeta } from './snapshot_options.ts';
1
+ import type { SnapshotMeta } from '../shared/types.ts';
2
2
  /**
3
3
  * Determine should snapshot be taken.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"should_take_snapshot.d.ts","sourceRoot":"","sources":["../../src/client/should_take_snapshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAA0B,MAAM,uBAAuB,CAAA;AAEjF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,uBAGtE"}
1
+ {"version":3,"file":"should_take_snapshot.d.ts","sourceRoot":"","sources":["../../src/client/should_take_snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAItD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,uBAGtE"}
@@ -1,5 +1,5 @@
1
1
  import { ctx } from "./ctx.js";
2
- import { getAutoSnapshotOptions } from "./snapshot_options.js";
2
+ import { extractAutoSnapshotOptions } from "./snapshot_options.js";
3
3
  /**
4
4
  * Determine should snapshot be taken.
5
5
  *
@@ -8,6 +8,6 @@ import { getAutoSnapshotOptions } from "./snapshot_options.js";
8
8
  * disabled by `!snapshot` tag: false
9
9
  */
10
10
  export function shouldTakeSnapshot(meta) {
11
- const m = meta ?? getAutoSnapshotOptions(ctx.getCurrentTest());
11
+ const m = meta ?? extractAutoSnapshotOptions(ctx.getCurrentTest());
12
12
  return document.body.childElementCount > 0 && m?.enable;
13
13
  }
@@ -1,9 +1,4 @@
1
- import type { AutoSnapshotOptions, ComparisonMethod } from '../shared/types.ts';
2
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts';
3
- export type SnapshotMeta<M extends ComparisonMethod> = ToMatchImageSnapshotOptions<M> & AutoSnapshotOptions & {
4
- enable?: boolean | undefined;
5
- [key: string]: unknown;
6
- };
1
+ import type { ComparisonMethod, SnapshotMeta } from '../shared/types.ts';
7
2
  type Suite = {
8
3
  meta: Record<string, any>;
9
4
  suite?: Suite | undefined;
@@ -33,6 +28,6 @@ export declare function enableAuto(): void;
33
28
  */
34
29
  export declare function setAutoSnapshotOptions<M extends ComparisonMethod>(task: MetaTask, meta: SnapshotMeta<M> | boolean): void;
35
30
  export declare function setAutoSnapshotOptions<M extends ComparisonMethod>(meta: SnapshotMeta<M> | boolean): void;
36
- export declare function getAutoSnapshotOptions<M extends SnapshotMeta<any> = SnapshotMeta<any>>(task: MetaTask): M | undefined;
31
+ export declare function extractAutoSnapshotOptions<M extends SnapshotMeta<any> = SnapshotMeta<any>>(task: MetaTask): M | undefined;
37
32
  export {};
38
33
  //# sourceMappingURL=snapshot_options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot_options.d.ts","sourceRoot":"","sources":["../../src/client/snapshot_options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE/E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AAE5F,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,gBAAgB,IAAI,2BAA2B,CAAC,CAAC,CAAC,GACpF,mBAAmB,GAAG;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB,CAAA;AAEF,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,wBAAgB,UAAU,SAEzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAChE,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,GAC7B,IAAI,CAAA;AACP,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,CAAA;AAwBzG,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,GAAG,CAAC,GAAG,SAAS,CAqBrH"}
1
+ {"version":3,"file":"snapshot_options.d.ts","sourceRoot":"","sources":["../../src/client/snapshot_options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGxE,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,wBAAgB,UAAU,SAEzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAChE,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,GAC7B,IAAI,CAAA;AACP,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,CAAA;AAwBzG,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,EACzF,IAAI,EAAE,QAAQ,GACZ,CAAC,GAAG,SAAS,CAkBf"}
@@ -19,7 +19,7 @@ function parseArgs(args) {
19
19
  function parseMeta(meta) {
20
20
  return typeof meta === 'boolean' ? { enable: meta } : { enable: true, ...meta };
21
21
  }
22
- export function getAutoSnapshotOptions(task) {
22
+ export function extractAutoSnapshotOptions(task) {
23
23
  if (!task)
24
24
  return;
25
25
  const list = [];
@@ -31,10 +31,7 @@ export function getAutoSnapshotOptions(task) {
31
31
  list.unshift(task.file?.meta);
32
32
  list.push(task.meta);
33
33
  return list.reduce((acc, cur) => {
34
- if (cur?.[NAME]) {
35
- const { [NAME]: meta } = cur;
36
- return Object.assign({}, acc, meta);
37
- }
38
- return acc;
34
+ const meta = cur?.[NAME];
35
+ return meta ? Object.assign({}, acc, meta) : acc;
39
36
  }, { enable: ctx.autoEnabled });
40
37
  }
@@ -1,3 +1,4 @@
1
- export declare const getCurrentTest: () => import("vitest").RunnerTestCase<object> | undefined;
1
+ import type { CurrentTest } from '../shared/types.ts';
2
+ export declare const getCurrentTest: () => CurrentTest;
2
3
  export declare const getCurrentSuite: () => import("vitest").SuiteCollector<object>;
3
4
  //# sourceMappingURL=vitest_suite_proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest_suite_proxy.d.ts","sourceRoot":"","sources":["../../src/client/vitest_suite_proxy.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,2DAAsC,CAAA;AACjE,eAAO,MAAM,eAAe,+CAAuC,CAAA"}
1
+ {"version":3,"file":"vitest_suite_proxy.d.ts","sourceRoot":"","sources":["../../src/client/vitest_suite_proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAUrD,eAAO,MAAM,cAAc,QAA0C,WAAW,CAAA;AAChF,eAAO,MAAM,eAAe,+CAAuC,CAAA"}
package/esm/client.d.ts CHANGED
@@ -2,7 +2,7 @@ export * from './client/expect/expectation_result.ts';
2
2
  export type * from './client/expect/to_match_image_snapshot.types.ts';
3
3
  export * from './client/image_snapshot_matcher.ts';
4
4
  export * from './client/should_take_snapshot.ts';
5
- export { type MetaTask, type SnapshotMeta, setAutoSnapshotOptions } from './client/snapshot_options.ts';
5
+ export { setAutoSnapshotOptions, type MetaTask } from './client/snapshot_options.ts';
6
6
  export * from './client/task_id.ts';
7
7
  export type * from './shared/types.ts';
8
8
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AACrD,mBAAmB,kDAAkD,CAAA;AACrE,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACvG,cAAc,qBAAqB,CAAA;AACnC,mBAAmB,mBAAmB,CAAA"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AACrD,mBAAmB,kDAAkD,CAAA;AACrE,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACpF,cAAc,qBAAqB,CAAA;AACnC,mBAAmB,mBAAmB,CAAA"}
package/esm/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import './client/expect/augment.ts';
2
2
  import './client/page/augment.ts';
3
- export { type MetaTask, type SnapshotMeta, setAutoSnapshotOptions } from './client/snapshot_options.ts';
3
+ export { setAutoSnapshotOptions, type MetaTask } from './client/snapshot_options.ts';
4
+ export type * from './shared/types.ts';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,sBAAsB,EAAE,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACpF,mBAAmB,mBAAmB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBAC69C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CADz8C,CAAA"}
1
+ {"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBACikD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAD7iD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"vis_context.logic.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.logic.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAKpD,OAAO,KAAK,EAAE,4BAA4B,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEpF,wBAAgB,gBAAgB;eAMnB,CAAC,SAAS,OAAO,GAAG,MAAM,YAAW,UAAU,CAAC,CAAC,CAAC;;;;IAY7D;;;;OAIG;wBACuB,4BAA4B;8BAa5B,MAAM,QAAQ,MAAM,YAAY;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAkB1E,MAAM,UAAU,MAAM;+BAGlB,MAAM,UAAU,MAAM,kBAAkB,MAAM,GAAG,SAAS;8BAI3D;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,kBAAkB,MAAM,GAAG,SAAS;2BASlF,MAAM,UAAU,MAAM;;;;;;;;;;EAe9C;AAyBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC;;;;;;;;EAWnH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC,UAElH"}
1
+ {"version":3,"file":"vis_context.logic.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.logic.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAMpD,OAAO,KAAK,EAAE,4BAA4B,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEpF,wBAAgB,gBAAgB;eAMnB,CAAC,SAAS,OAAO,GAAG,MAAM,YAAW,UAAU,CAAC,CAAC,CAAC;;;;IAY7D;;;;OAIG;wBACuB,4BAA4B;8BAa5B,MAAM,QAAQ,MAAM,YAAY;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAkB1E,MAAM,UAAU,MAAM;+BAGlB,MAAM,UAAU,MAAM,kBAAkB,MAAM,GAAG,SAAS;8BAI3D;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,kBAAkB,MAAM,GAAG,SAAS;2BAWlF,MAAM,UAAU,MAAM;;;;;;;;;;EAe9C;AAyBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC;;;;;;;;EAWnH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC,UAElH"}
@@ -1,5 +1,6 @@
1
1
  import { join, relative } from 'pathe';
2
2
  import { pick } from 'type-plus';
3
+ import { getCurrentTest } from 'vitest/suite';
3
4
  import { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from "../shared/constants.js";
4
5
  import { file } from "./file.js";
5
6
  import { getSnapshotSubpath, resolveSnapshotRootDir } from "./snapshot_path.js";
@@ -64,10 +65,13 @@ export function createVisContext() {
64
65
  getSnapshotFilename(info, snapshotFileId) {
65
66
  if (snapshotFileId)
66
67
  return `${snapshotFileId}.png`;
68
+ const test = getCurrentTest();
69
+ const isAutoSnapshot = !!test?.meta.vis?.isAutoSnapshot;
67
70
  const customizeSnapshotId = visOptions.customizeSnapshotId ?? (({ id, index }) => `${id}-${index}`);
68
71
  return `${customizeSnapshotId({
69
72
  id: info.taskId,
70
73
  index: info.task.count,
74
+ isAutoSnapshot,
71
75
  })}.png`;
72
76
  },
73
77
  getSuiteInfo(testPath, taskId) {
@@ -1,9 +1,9 @@
1
- import { type SnapshotMeta } from '../client.ts';
1
+ import { type ComparisonMethod, type SnapshotMeta } from '../client.ts';
2
2
  import type { SetupVisSuiteCommand } from '../server/commands/setup_vis_suite.ts';
3
3
  /**
4
4
  * Visual test configuration on the client side.
5
5
  */
6
- export type VisClientConfigurator<M extends SnapshotMeta<any>> = {
6
+ export type VisClientConfigurator<SM extends SnapshotMeta<ComparisonMethod>> = {
7
7
  presets: {
8
8
  /**
9
9
  * Enable visual testing.
@@ -39,15 +39,15 @@ export type VisClientConfigurator<M extends SnapshotMeta<any>> = {
39
39
  * })
40
40
  * ```
41
41
  */
42
- theme(themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>): void;
42
+ theme<M>(themes: Record<string, (options: M & SM) => Promise<boolean> | Promise<void> | boolean | void>): void;
43
43
  };
44
44
  beforeAll: {
45
45
  setup(): Promise<void>;
46
46
  };
47
47
  afterEach: {
48
48
  matchImageSnapshot(): Promise<void>;
49
- matchPerTheme(themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>): () => Promise<void>;
49
+ matchPerTheme<M>(themes: Record<string, (options: M & SM) => Promise<boolean> | Promise<void> | boolean | void>): () => Promise<void>;
50
50
  };
51
51
  };
52
- export declare function createVis<M extends SnapshotMeta<any>>(commands: SetupVisSuiteCommand): VisClientConfigurator<M>;
52
+ export declare function createVis<SM extends SnapshotMeta<ComparisonMethod>>(commands: SetupVisSuiteCommand): VisClientConfigurator<SM>;
53
53
  //# sourceMappingURL=create_vis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create_vis.d.ts","sourceRoot":"","sources":["../../src/setup/create_vis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAoC,MAAM,cAAc,CAAA;AAIlF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAA;AAEjF;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,IAAI;IAChE,OAAO,EAAE;QACR;;;;;WAKG;QACH,MAAM,IAAI,IAAI,CAAA;QACd;;;;WAIG;QACH,MAAM,IAAI,IAAI,CAAA;QACd;;;;WAIG;QACH,IAAI,IAAI,IAAI,CAAA;QACZ;;;;;;;;;;;;;;WAcG;QACH,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;KACtG,CAAA;IACD,SAAS,EAAE;QACV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KACtB,CAAA;IACD,SAAS,EAAE;QACV,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;QACnC,aAAa,CACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GACvF,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KACtB,CAAA;CACD,CAAA;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,oBAAoB,4BAkFpF"}
1
+ {"version":3,"file":"create_vis.d.ts","sourceRoot":"","sources":["../../src/setup/create_vis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAY,MAAM,cAAc,CAAA;AAIjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAA;AAEjF;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,EAAE,SAAS,YAAY,CAAC,gBAAgB,CAAC,IAAI;IAC9E,OAAO,EAAE;QACR;;;;;WAKG;QACH,MAAM,IAAI,IAAI,CAAA;QACd;;;;WAIG;QACH,MAAM,IAAI,IAAI,CAAA;QACd;;;;WAIG;QACH,IAAI,IAAI,IAAI,CAAA;QACZ;;;;;;;;;;;;;;WAcG;QACH,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;KAC9G,CAAA;IACD,SAAS,EAAE;QACV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KACtB,CAAA;IACD,SAAS,EAAE;QACV,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;QACnC,aAAa,CAAC,CAAC,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GAC5F,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KACtB,CAAA;CACD,CAAA;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAS,YAAY,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,oBAAoB,6BAoFlG"}
@@ -1,9 +1,9 @@
1
1
  import dedent from 'dedent';
2
2
  import { afterEach, beforeAll } from 'vitest';
3
- import { setAutoSnapshotOptions, toTaskId } from "../client.js";
3
+ import { toTaskId } from "../client.js";
4
4
  import { ctx } from "../client/ctx.js";
5
5
  import { shouldTakeSnapshot } from "../client/should_take_snapshot.js";
6
- import { enableAuto, getAutoSnapshotOptions } from "../client/snapshot_options.js";
6
+ import { enableAuto, extractAutoSnapshotOptions } from "../client/snapshot_options.js";
7
7
  export function createVis(commands) {
8
8
  let subjectDataTestId;
9
9
  const vis = {
@@ -35,9 +35,10 @@ export function createVis(commands) {
35
35
  const test = ctx.getCurrentTest();
36
36
  if ((test?.result?.errors?.length ?? 0) > 0)
37
37
  return;
38
- const meta = getAutoSnapshotOptions(test);
38
+ const meta = extractAutoSnapshotOptions(test);
39
39
  if (!shouldTakeSnapshot(meta))
40
40
  return;
41
+ test.meta.vis = { ...test.meta.vis, isAutoSnapshot: true };
41
42
  await test.context.expect(getSubject(meta?.subjectDataTestId ?? subjectDataTestId)).toMatchImageSnapshot(meta);
42
43
  },
43
44
  matchPerTheme(themes) {
@@ -45,7 +46,7 @@ export function createVis(commands) {
45
46
  const test = ctx.getCurrentTest();
46
47
  if ((test?.result?.errors?.length ?? 0) > 0)
47
48
  return;
48
- const meta = getAutoSnapshotOptions(test);
49
+ const meta = extractAutoSnapshotOptions(test);
49
50
  if (!shouldTakeSnapshot(meta))
50
51
  return;
51
52
  const errors = [];
@@ -60,7 +61,7 @@ export function createVis(commands) {
60
61
  .toMatchImageSnapshot({
61
62
  ...meta,
62
63
  customizeSnapshotId: meta?.customizeSnapshotId
63
- ? ({ id, index }) => `${meta.customizeSnapshotId({ id, index })}-${themeId}`
64
+ ? ({ id, index }) => `${meta.customizeSnapshotId({ id, index, isAutoSnapshot: true })}-${themeId}`
64
65
  : ({ id }) => `${id}-${themeId}`,
65
66
  });
66
67
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Visual test configuration on the client side.
3
3
  */
4
- export declare const vis: import("./create_vis.ts").VisClientConfigurator<import("../index.ts").SnapshotMeta<any>>;
4
+ export declare const vis: import("./create_vis.ts").VisClientConfigurator<import("../index.ts").SnapshotMeta<import("../index.ts").ComparisonMethod>>;
5
5
  //# sourceMappingURL=vis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vis.d.ts","sourceRoot":"","sources":["../../src/setup/vis.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,GAAG,0FAAsB,CAAA"}
1
+ {"version":3,"file":"vis.d.ts","sourceRoot":"","sources":["../../src/setup/vis.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,GAAG,6HAAsB,CAAA"}
@@ -1,5 +1,7 @@
1
1
  import type pixelMatch from 'pixelmatch';
2
2
  import type { Options as SsimOptions } from 'ssim.js';
3
+ import type { getCurrentTest } from 'vitest/suite';
4
+ import type { NAME } from './constants.ts';
3
5
  export interface ImageSnapshotTimeoutOptions {
4
6
  /**
5
7
  * Timeout for taking the snapshot.
@@ -18,6 +20,7 @@ export interface ImageSnapshotIdOptions {
18
20
  customizeSnapshotId?: (context: {
19
21
  id: string;
20
22
  index: number;
23
+ isAutoSnapshot: boolean;
21
24
  }) => string;
22
25
  }
23
26
  export type ComparisonMethod = 'pixel' | 'ssim';
@@ -59,4 +62,22 @@ export type AutoSnapshotOptions = {
59
62
  */
60
63
  subjectDataTestId?: string | undefined;
61
64
  };
65
+ export type ToMatchImageSnapshotOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTimeoutOptions & ImageSnapshotIdOptions & ImageSnapshotCompareOptions<M> & {
66
+ /**
67
+ * Expect the matcher to fail.
68
+ * If it passes, it will throw an error with details.
69
+ */
70
+ expectToFail?: boolean | undefined;
71
+ };
72
+ export type SnapshotMeta<M extends ComparisonMethod> = ToMatchImageSnapshotOptions<M> & AutoSnapshotOptions & {
73
+ enable?: boolean | undefined;
74
+ [key: string]: unknown;
75
+ };
76
+ export type CurrentTest = ReturnType<typeof getCurrentTest> & {
77
+ meta: {
78
+ [NAME]?: SnapshotMeta<'pixel' | 'ssim'> & {
79
+ isAutoSnapshot?: boolean | undefined;
80
+ };
81
+ };
82
+ };
62
83
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,SAAS,CAAA;AAErD,MAAM,WAAW,2BAA2B;IAC3C;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACtC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC/B,EAAE,EAAE,MAAM,CAAA;QAGV,KAAK,EAAE,MAAM,CAAA;KACb,KAAK,MAAM,CAAA;CACZ;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAA;AAE/C,MAAM,MAAM,uBAAuB,GAAG;IACrC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;IACtD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,MAAM,IAAI;IAC/C,gBAAgB,EAAE,CAAC,CAAA;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS,CAAA;CAC9C,CAAA;AACD,MAAM,MAAM,sBAAsB,CAAC,CAAC,GAAG,OAAO,IAAI;IACjD,gBAAgB,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;IAChC;;OAEG;IACH,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,CAAC,CAAC,SAAS,MAAM,GAC9F,qBAAqB,CAAC,CAAC,CAAC,GACxB,sBAAsB,CAAC,CAAC,CAAC,CAAC,GAC5B,uBAAuB,CAAA;AAExB,MAAM,MAAM,mBAAmB,GAAG;IACjC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,WAAW,2BAA2B;IAC3C;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACtC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC/B,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,OAAO,CAAA;KACvB,KAAK,MAAM,CAAA;CACZ;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAA;AAE/C,MAAM,MAAM,uBAAuB,GAAG;IACrC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;IACtD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,MAAM,IAAI;IAC/C,gBAAgB,EAAE,CAAC,CAAA;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS,CAAA;CAC9C,CAAA;AACD,MAAM,MAAM,sBAAsB,CAAC,CAAC,GAAG,OAAO,IAAI;IACjD,gBAAgB,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;IAChC;;OAEG;IACH,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,CAAC,CAAC,SAAS,MAAM,GAC9F,qBAAqB,CAAC,CAAC,CAAC,GACxB,sBAAsB,CAAC,CAAC,CAAC,CAAC,GAC5B,uBAAuB,CAAA;AAExB,MAAM,MAAM,mBAAmB,GAAG;IACjC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC,CAAA;AACD,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,2BAA2B,GAC1G,sBAAsB,GACtB,2BAA2B,CAAC,CAAC,CAAC,GAAG;IAChC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAClC,CAAA;AAEF,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,gBAAgB,IAAI,2BAA2B,CAAC,CAAC,CAAC,GACpF,mBAAmB,GAAG;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,GAAG;IAC7D,IAAI,EAAE;QAAE,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG;YAAE,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;SAAE,CAAA;KAAE,CAAA;CAC5F,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-plugin-vis",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Vitest visual testing plugin",
5
5
  "keywords": [
6
6
  "image-snapshot",
package/readme.md CHANGED
@@ -83,7 +83,8 @@ export default defineConfig({
83
83
  }) => `__vis__/${ci ? platform : 'local'}`,
84
84
  platform: '...', // {process.platform} or `local` (deprecated use `snapshotRootDir` instead)
85
85
  customizeSnapshotSubpath: (subpath) => trimCommonFolder(subpath),
86
- customizeSnapshotId: ({ id, index }) => `${id}-${index}`,
86
+ // will change to "isAutoSnapshot ? `${id}-auto` : `${id}-${index}`" in the next major release.
87
+ customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-${index}`,
87
88
  // set a default subject (e.g. 'subject') to capture image snapshot
88
89
  subjectDataTestId: undefined,
89
90
  comparisonMethod: 'pixel',
@@ -217,7 +218,7 @@ setAutoSnapshotOptions(true /* or false */)
217
218
  setAutoSnapshotOptions({
218
219
  enable: true,
219
220
  comparisonMethod: 'pixel',
220
- customizeSnapshotId: ({ id, index }) => `${id}-custom-${index}`,
221
+ customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-custom-${index}`,
221
222
  // pixelmatch or ssim.js options, depending on `comparisonMethod`.
222
223
  diffOptions: { threshold: 0.01 },
223
224
  failureThreshold: 0.01,
@@ -285,7 +286,7 @@ it('manual snapshot with options', async ({ expect }) => {
285
286
  page.render(<div data-testid="subject">hello world</div>)
286
287
  const subject = page.getByTestId('subject')
287
288
  await expect(subject).toMatchImageSnapshot({
288
- customizeSnapshotId: ({ id, index }) => `${id}-custom-${index}`,
289
+ customizeSnapshotId: ({ id, index, isAutoSnapshot }) => `${id}-custom-${index}`,
289
290
  failureThreshold: 0.01,
290
291
  failureThresholdType: 'percent',
291
292
  diffOptions: {
package/src/client/ctx.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { getCurrentSuite, getCurrentTest } from './vitest_suite_proxy.ts'
2
2
 
3
3
  export const ctx = {
4
- autoEnabled: false,
4
+ autoEnabled: undefined as boolean | undefined,
5
5
  getCurrentTest,
6
6
  getCurrentSuite,
7
7
  __test__reset() {
8
8
  ctx.getCurrentTest = getCurrentTest
9
9
  ctx.getCurrentSuite = getCurrentSuite
10
- ctx.autoEnabled = false
10
+ ctx.autoEnabled = undefined
11
11
  },
12
12
  }
@@ -1,9 +1,9 @@
1
1
  import { commands } from '@vitest/browser/context'
2
2
  import type { AsyncExpectationResult } from '@vitest/expect'
3
+ import type { ToMatchImageSnapshotOptions } from '../../shared/types.ts'
3
4
  import { ctx } from '../ctx.ts'
4
5
  import { imageSnapshotMatcher } from '../image_snapshot_matcher.ts'
5
6
  import { success } from './expectation_result.ts'
6
- import type { ToMatchImageSnapshotOptions } from './to_match_image_snapshot.types.ts'
7
7
 
8
8
  export function toMatchImageSnapshot(
9
9
  /**
@@ -1,20 +1,5 @@
1
- import type {
2
- ComparisonMethod,
3
- ImageSnapshotCompareOptions,
4
- ImageSnapshotIdOptions,
5
- ImageSnapshotTimeoutOptions,
6
- } from '../../shared/types.ts'
1
+ import type { ComparisonMethod, ToMatchImageSnapshotOptions } from '../../shared/types.ts'
7
2
 
8
3
  export interface ImageSnapshotMatcher {
9
4
  toMatchImageSnapshot<M extends ComparisonMethod>(options?: ToMatchImageSnapshotOptions<M> | undefined): Promise<void>
10
5
  }
11
-
12
- export type ToMatchImageSnapshotOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTimeoutOptions &
13
- ImageSnapshotIdOptions &
14
- ImageSnapshotCompareOptions<M> & {
15
- /**
16
- * Expect the matcher to fail.
17
- * If it passes, it will throw an error with details.
18
- */
19
- expectToFail?: boolean | undefined
20
- }
@@ -1,4 +1,4 @@
1
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts'
1
+ import type { ToMatchImageSnapshotOptions } from '../shared/types.ts'
2
2
 
3
3
  export function prettifyOptions(options: ToMatchImageSnapshotOptions<any> | undefined) {
4
4
  if (!options) return 'none'
@@ -1,13 +1,12 @@
1
1
  import dedent from 'dedent'
2
2
  import { resolve } from 'pathe'
3
- import type { Task } from 'vitest'
4
3
  import type { ImageSnapshotNextIndexCommand } from '../commands.ts'
5
4
  import type { PrepareImageSnapshotComparisonCommand } from '../server/commands/prepare_image_snapshot_comparison.ts'
6
5
  import type { WriteImageSnapshotCommand } from '../server/commands/write_image_snapshot.ts'
7
6
  import { isBase64String } from '../shared/base64.ts'
8
7
  import { compareImage } from '../shared/compare_image.ts'
8
+ import type { CurrentTest, ToMatchImageSnapshotOptions } from '../shared/types.ts'
9
9
  import { alignImagesToSameSize } from './align_images.ts'
10
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts'
11
10
  import { toDataURL, toImageData } from './image_data.ts'
12
11
  import { prettifyOptions } from './image_snapshot_matcher.logic.ts'
13
12
  import { convertElementToCssSelector } from './selector.ts'
@@ -17,12 +16,19 @@ import { server } from './vitest_browser_context_proxy.ts'
17
16
  export function imageSnapshotMatcher(
18
17
  commands: PrepareImageSnapshotComparisonCommand & WriteImageSnapshotCommand & ImageSnapshotNextIndexCommand,
19
18
  ) {
20
- return async function matchImageSnapshot(test: Task, subject: any, options?: ToMatchImageSnapshotOptions<any>) {
19
+ return async function matchImageSnapshot(
20
+ test: CurrentTest & {},
21
+ subject: any,
22
+ options?: ToMatchImageSnapshotOptions<any>,
23
+ ) {
24
+ const isAutoSnapshot = !!test.meta.vis?.isAutoSnapshot
21
25
  const taskId = toTaskId(test)
22
26
  const info = await commands.prepareImageSnapshotComparison(
23
27
  taskId,
24
28
  parseImageSnapshotSubject(subject),
25
- options?.customizeSnapshotId ? await parseImageSnapshotOptions(commands, taskId, options) : options,
29
+ options?.customizeSnapshotId
30
+ ? await parseImageSnapshotOptions(commands, taskId, isAutoSnapshot, options)
31
+ : options,
26
32
  )
27
33
 
28
34
  if (!info) return
@@ -103,10 +109,11 @@ async function writeSnapshot(commands: WriteImageSnapshotCommand, path: string,
103
109
  async function parseImageSnapshotOptions(
104
110
  commands: ImageSnapshotNextIndexCommand,
105
111
  taskId: string,
112
+ isAutoSnapshot: boolean,
106
113
  options: ToMatchImageSnapshotOptions<any>,
107
114
  ) {
108
115
  const index = await commands.imageSnapshotNextIndex(taskId)
109
116
  const { customizeSnapshotId, ...rest } = options
110
- const snapshotFileId = customizeSnapshotId!({ id: taskId, index })
117
+ const snapshotFileId = customizeSnapshotId!({ id: taskId, index, isAutoSnapshot })
111
118
  return { ...rest, snapshotFileId }
112
119
  }
@@ -26,7 +26,12 @@ export function hasImageSnapshot(this: BrowserPage, options?: ImageSnapshotIdOpt
26
26
  if (options?.customizeSnapshotId) {
27
27
  return commands
28
28
  .imageSnapshotNextIndex(taskId)
29
- .then((index) => commands.hasImageSnapshot(taskId, options.customizeSnapshotId!({ id: taskId, index })))
29
+ .then((index) =>
30
+ commands.hasImageSnapshot(
31
+ taskId,
32
+ options.customizeSnapshotId!({ id: taskId, index, isAutoSnapshot: !!test.meta.vis?.isAutoSnapshot }),
33
+ ),
34
+ )
30
35
  }
31
36
 
32
37
  return commands.hasImageSnapshot(taskId)
@@ -1,5 +1,6 @@
1
+ import type { SnapshotMeta } from '../shared/types.ts'
1
2
  import { ctx } from './ctx.ts'
2
- import { type SnapshotMeta, getAutoSnapshotOptions } from './snapshot_options.ts'
3
+ import { extractAutoSnapshotOptions } from './snapshot_options.ts'
3
4
 
4
5
  /**
5
6
  * Determine should snapshot be taken.
@@ -9,6 +10,6 @@ import { type SnapshotMeta, getAutoSnapshotOptions } from './snapshot_options.ts
9
10
  * disabled by `!snapshot` tag: false
10
11
  */
11
12
  export function shouldTakeSnapshot(meta?: SnapshotMeta<any> | undefined) {
12
- const m = meta ?? getAutoSnapshotOptions(ctx.getCurrentTest())
13
+ const m = meta ?? extractAutoSnapshotOptions(ctx.getCurrentTest())
13
14
  return document.body.childElementCount > 0 && m?.enable
14
15
  }
@@ -1,13 +1,6 @@
1
1
  import { NAME } from '../shared/constants.ts'
2
- import type { AutoSnapshotOptions, ComparisonMethod } from '../shared/types.ts'
2
+ import type { ComparisonMethod, SnapshotMeta } from '../shared/types.ts'
3
3
  import { ctx } from './ctx.ts'
4
- import type { ToMatchImageSnapshotOptions } from './expect/to_match_image_snapshot.types.ts'
5
-
6
- export type SnapshotMeta<M extends ComparisonMethod> = ToMatchImageSnapshotOptions<M> &
7
- AutoSnapshotOptions & {
8
- enable?: boolean | undefined
9
- [key: string]: unknown
10
- }
11
4
 
12
5
  type Suite = { meta: Record<string, any>; suite?: Suite | undefined }
13
6
 
@@ -66,7 +59,9 @@ function parseMeta<M extends ComparisonMethod>(meta: boolean | SnapshotMeta<M>):
66
59
  return typeof meta === 'boolean' ? ({ enable: meta } as any) : { enable: true, ...meta }
67
60
  }
68
61
 
69
- export function getAutoSnapshotOptions<M extends SnapshotMeta<any> = SnapshotMeta<any>>(task: MetaTask): M | undefined {
62
+ export function extractAutoSnapshotOptions<M extends SnapshotMeta<any> = SnapshotMeta<any>>(
63
+ task: MetaTask,
64
+ ): M | undefined {
70
65
  if (!task) return
71
66
 
72
67
  const list: any[] = []
@@ -79,11 +74,8 @@ export function getAutoSnapshotOptions<M extends SnapshotMeta<any> = SnapshotMet
79
74
  list.push(task.meta)
80
75
  return list.reduce(
81
76
  (acc, cur) => {
82
- if (cur?.[NAME]) {
83
- const { [NAME]: meta } = cur
84
- return Object.assign({}, acc, meta)
85
- }
86
- return acc
77
+ const meta = cur?.[NAME]
78
+ return meta ? Object.assign({}, acc, meta) : acc
87
79
  },
88
80
  { enable: ctx.autoEnabled },
89
81
  )
@@ -1,3 +1,5 @@
1
+ import type { CurrentTest } from '../shared/types.ts'
2
+
1
3
  let vitestSuite: Awaited<typeof import('vitest/suite')>
2
4
 
3
5
  if ((globalThis as any).__vitest_browser__) {
@@ -6,5 +8,5 @@ if ((globalThis as any).__vitest_browser__) {
6
8
  })
7
9
  }
8
10
 
9
- export const getCurrentTest = () => vitestSuite?.getCurrentTest()
11
+ export const getCurrentTest = () => vitestSuite?.getCurrentTest() as CurrentTest
10
12
  export const getCurrentSuite = () => vitestSuite?.getCurrentSuite()
package/src/client.ts CHANGED
@@ -2,6 +2,6 @@ export * from './client/expect/expectation_result.ts'
2
2
  export type * from './client/expect/to_match_image_snapshot.types.ts'
3
3
  export * from './client/image_snapshot_matcher.ts'
4
4
  export * from './client/should_take_snapshot.ts'
5
- export { type MetaTask, type SnapshotMeta, setAutoSnapshotOptions } from './client/snapshot_options.ts'
5
+ export { setAutoSnapshotOptions, type MetaTask } from './client/snapshot_options.ts'
6
6
  export * from './client/task_id.ts'
7
7
  export type * from './shared/types.ts'
package/src/index.ts CHANGED
@@ -2,4 +2,5 @@
2
2
  import './client/expect/augment.ts'
3
3
  import './client/page/augment.ts'
4
4
 
5
- export { type MetaTask, type SnapshotMeta, setAutoSnapshotOptions } from './client/snapshot_options.ts'
5
+ export { setAutoSnapshotOptions, type MetaTask } from './client/snapshot_options.ts'
6
+ export type * from './shared/types.ts'
@@ -1,7 +1,9 @@
1
1
  import { join, relative } from 'pathe'
2
2
  import { pick } from 'type-plus'
3
+ import { getCurrentTest } from 'vitest/suite'
3
4
  import type { VisOptions } from '../config/types.ts'
4
5
  import { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from '../shared/constants.ts'
6
+ import type { CurrentTest } from '../shared/types.ts'
5
7
  import { file } from './file.ts'
6
8
  import { getSnapshotSubpath, resolveSnapshotRootDir } from './snapshot_path.ts'
7
9
  import { ctx } from './vis_context.ctx.ts'
@@ -70,11 +72,13 @@ export function createVisContext() {
70
72
  },
71
73
  getSnapshotFilename(info: { taskId: string; task: { count: number } }, snapshotFileId: string | undefined) {
72
74
  if (snapshotFileId) return `${snapshotFileId}.png`
73
-
75
+ const test = getCurrentTest() as CurrentTest
76
+ const isAutoSnapshot = !!test?.meta.vis?.isAutoSnapshot
74
77
  const customizeSnapshotId = visOptions.customizeSnapshotId ?? (({ id, index }) => `${id}-${index}`)
75
78
  return `${customizeSnapshotId({
76
79
  id: info.taskId,
77
80
  index: info.task.count,
81
+ isAutoSnapshot,
78
82
  })}.png`
79
83
  },
80
84
  getSuiteInfo(testPath: string, taskId: string) {
@@ -1,15 +1,15 @@
1
1
  import dedent from 'dedent'
2
2
  import { afterEach, beforeAll } from 'vitest'
3
- import { type SnapshotMeta, setAutoSnapshotOptions, toTaskId } from '../client.ts'
3
+ import { type ComparisonMethod, type SnapshotMeta, toTaskId } from '../client.ts'
4
4
  import { ctx } from '../client/ctx.ts'
5
5
  import { shouldTakeSnapshot } from '../client/should_take_snapshot.ts'
6
- import { enableAuto, getAutoSnapshotOptions } from '../client/snapshot_options.ts'
6
+ import { enableAuto, extractAutoSnapshotOptions } from '../client/snapshot_options.ts'
7
7
  import type { SetupVisSuiteCommand } from '../server/commands/setup_vis_suite.ts'
8
8
 
9
9
  /**
10
10
  * Visual test configuration on the client side.
11
11
  */
12
- export type VisClientConfigurator<M extends SnapshotMeta<any>> = {
12
+ export type VisClientConfigurator<SM extends SnapshotMeta<ComparisonMethod>> = {
13
13
  presets: {
14
14
  /**
15
15
  * Enable visual testing.
@@ -45,23 +45,23 @@ export type VisClientConfigurator<M extends SnapshotMeta<any>> = {
45
45
  * })
46
46
  * ```
47
47
  */
48
- theme(themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>): void
48
+ theme<M>(themes: Record<string, (options: M & SM) => Promise<boolean> | Promise<void> | boolean | void>): void
49
49
  }
50
50
  beforeAll: {
51
51
  setup(): Promise<void>
52
52
  }
53
53
  afterEach: {
54
54
  matchImageSnapshot(): Promise<void>
55
- matchPerTheme(
56
- themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>,
55
+ matchPerTheme<M>(
56
+ themes: Record<string, (options: M & SM) => Promise<boolean> | Promise<void> | boolean | void>,
57
57
  ): () => Promise<void>
58
58
  }
59
59
  }
60
60
 
61
- export function createVis<M extends SnapshotMeta<any>>(commands: SetupVisSuiteCommand) {
61
+ export function createVis<SM extends SnapshotMeta<ComparisonMethod>>(commands: SetupVisSuiteCommand) {
62
62
  let subjectDataTestId: string | undefined
63
63
 
64
- const vis: VisClientConfigurator<M> = {
64
+ const vis: VisClientConfigurator<SM> = {
65
65
  presets: {
66
66
  enable() {
67
67
  beforeAll(vis.beforeAll.setup)
@@ -75,7 +75,7 @@ export function createVis<M extends SnapshotMeta<any>>(commands: SetupVisSuiteCo
75
75
  afterEach(vis.afterEach.matchImageSnapshot)
76
76
  enableAuto()
77
77
  },
78
- theme(themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>) {
78
+ theme(themes) {
79
79
  beforeAll(vis.beforeAll.setup)
80
80
  afterEach(vis.afterEach.matchPerTheme(themes))
81
81
  },
@@ -91,38 +91,40 @@ export function createVis<M extends SnapshotMeta<any>>(commands: SetupVisSuiteCo
91
91
 
92
92
  if ((test?.result?.errors?.length ?? 0) > 0) return
93
93
 
94
- const meta = getAutoSnapshotOptions(test)
94
+ const meta = extractAutoSnapshotOptions(test)
95
95
  if (!shouldTakeSnapshot(meta)) return
96
96
 
97
+ test.meta.vis = { ...test.meta.vis, isAutoSnapshot: true }
98
+
97
99
  await test!.context.expect(getSubject(meta?.subjectDataTestId ?? subjectDataTestId)).toMatchImageSnapshot(meta)
98
100
  },
99
- matchPerTheme(themes: Record<string, (options: M) => Promise<boolean> | Promise<void> | boolean | void>) {
101
+ matchPerTheme(themes) {
100
102
  return async function matchImageSnapshot() {
101
103
  const test = ctx.getCurrentTest()
102
104
  if ((test?.result?.errors?.length ?? 0) > 0) return
103
105
 
104
- const meta = getAutoSnapshotOptions<M>(test)
106
+ const meta = extractAutoSnapshotOptions(test)
105
107
  if (!shouldTakeSnapshot(meta)) return
106
- const errors: any[] = []
108
+ const errors: Array<[string, Error]> = []
107
109
  for (const themeId in themes) {
108
110
  try {
109
111
  await new Promise((a) => setTimeout(a, 10))
110
- const r = await themes[themeId]!(meta!)
112
+ const r = await themes[themeId]!(meta! as any)
111
113
  if (r === false) continue
112
114
  await test!.context
113
115
  .expect(getSubject(meta?.subjectDataTestId ?? subjectDataTestId))
114
116
  .toMatchImageSnapshot({
115
117
  ...meta,
116
118
  customizeSnapshotId: meta?.customizeSnapshotId
117
- ? ({ id, index }) => `${meta.customizeSnapshotId!({ id, index })}-${themeId}`
119
+ ? ({ id, index }) => `${meta.customizeSnapshotId!({ id, index, isAutoSnapshot: true })}-${themeId}`
118
120
  : ({ id }) => `${id}-${themeId}`,
119
121
  })
120
122
  } catch (error) {
121
- errors.push([themeId, error])
123
+ errors.push([themeId, error as Error])
122
124
  }
123
125
  }
124
126
  if (errors.length > 0) {
125
- if (errors.length === 1) throw errors[0][1]
127
+ if (errors.length === 1) throw errors[0]![1]
126
128
  const taskId = toTaskId(test!)
127
129
  throw new AggregateError(
128
130
  errors,
@@ -1,5 +1,7 @@
1
1
  import type pixelMatch from 'pixelmatch'
2
2
  import type { Options as SsimOptions } from 'ssim.js'
3
+ import type { getCurrentTest } from 'vitest/suite'
4
+ import type { NAME } from './constants.ts'
3
5
 
4
6
  export interface ImageSnapshotTimeoutOptions {
5
7
  /**
@@ -19,9 +21,8 @@ export interface ImageSnapshotIdOptions {
19
21
  */
20
22
  customizeSnapshotId?: (context: {
21
23
  id: string
22
- // width: number
23
- // height: number
24
24
  index: number
25
+ isAutoSnapshot: boolean
25
26
  }) => string
26
27
  }
27
28
 
@@ -71,3 +72,22 @@ export type AutoSnapshotOptions = {
71
72
  */
72
73
  subjectDataTestId?: string | undefined
73
74
  }
75
+ export type ToMatchImageSnapshotOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTimeoutOptions &
76
+ ImageSnapshotIdOptions &
77
+ ImageSnapshotCompareOptions<M> & {
78
+ /**
79
+ * Expect the matcher to fail.
80
+ * If it passes, it will throw an error with details.
81
+ */
82
+ expectToFail?: boolean | undefined
83
+ }
84
+
85
+ export type SnapshotMeta<M extends ComparisonMethod> = ToMatchImageSnapshotOptions<M> &
86
+ AutoSnapshotOptions & {
87
+ enable?: boolean | undefined
88
+ [key: string]: unknown
89
+ }
90
+
91
+ export type CurrentTest = ReturnType<typeof getCurrentTest> & {
92
+ meta: { [NAME]?: SnapshotMeta<'pixel' | 'ssim'> & { isAutoSnapshot?: boolean | undefined } }
93
+ }