vitest-plugin-vis 2.3.3 → 2.4.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 (46) hide show
  1. package/esm/client/image_snapshot_matcher.d.ts +2 -2
  2. package/esm/client/image_snapshot_matcher.d.ts.map +1 -1
  3. package/esm/client/image_snapshot_matcher.js +3 -3
  4. package/esm/client/snapshot_options.js +1 -1
  5. package/esm/commands.d.ts +1 -2
  6. package/esm/commands.d.ts.map +1 -1
  7. package/esm/commands.js +1 -2
  8. package/esm/config/types.d.ts +3 -3
  9. package/esm/config/types.d.ts.map +1 -1
  10. package/esm/config/vis.d.ts +0 -1
  11. package/esm/config/vis.d.ts.map +1 -1
  12. package/esm/server/commands/browser_command_context.d.ts +1 -1
  13. package/esm/server/commands/browser_command_context.d.ts.map +1 -1
  14. package/esm/server/commands/extend.d.ts +1 -3
  15. package/esm/server/commands/extend.d.ts.map +1 -1
  16. package/esm/server/commands/extend.js +0 -2
  17. package/esm/server/commands/image_snapshot_next_index.js +1 -1
  18. package/esm/server/commands/match_image_snapshot.js +1 -1
  19. package/esm/server/commands/prepare_image_snapshot_comparison.d.ts +18 -0
  20. package/esm/server/commands/prepare_image_snapshot_comparison.d.ts.map +1 -1
  21. package/esm/server/commands/prepare_image_snapshot_comparison.js +8 -6
  22. package/esm/server/snapshot_path.js +2 -2
  23. package/esm/server/vis_context.d.ts +8 -7
  24. package/esm/server/vis_context.d.ts.map +1 -1
  25. package/esm/server/vis_context.logic.d.ts +11 -10
  26. package/esm/server/vis_context.logic.d.ts.map +1 -1
  27. package/esm/server/vis_context.logic.js +37 -32
  28. package/esm/server/vis_context.types.d.ts +10 -7
  29. package/esm/server/vis_context.types.d.ts.map +1 -1
  30. package/package.json +2 -1
  31. package/src/client/image_snapshot_matcher.ts +6 -6
  32. package/src/client/snapshot_options.ts +1 -1
  33. package/src/commands.ts +1 -2
  34. package/src/config/types.ts +3 -3
  35. package/src/server/commands/browser_command_context.ts +1 -1
  36. package/src/server/commands/extend.ts +0 -3
  37. package/src/server/commands/image_snapshot_next_index.ts +1 -1
  38. package/src/server/commands/match_image_snapshot.ts +1 -1
  39. package/src/server/commands/prepare_image_snapshot_comparison.ts +26 -6
  40. package/src/server/snapshot_path.ts +2 -2
  41. package/src/server/vis_context.logic.ts +59 -35
  42. package/src/server/vis_context.types.ts +12 -8
  43. package/esm/server/commands/write_image_snapshot.d.ts +0 -12
  44. package/esm/server/commands/write_image_snapshot.d.ts.map +0 -1
  45. package/esm/server/commands/write_image_snapshot.js +0 -9
  46. package/src/server/commands/write_image_snapshot.ts +0 -26
@@ -1,9 +1,9 @@
1
+ import type { BrowserCommands } from '@vitest/browser/context';
1
2
  import type { ImageSnapshotNextIndexCommand } from '../commands.ts';
2
3
  import type { PrepareImageSnapshotComparisonCommand } from '../server/commands/prepare_image_snapshot_comparison.ts';
3
- import type { WriteImageSnapshotCommand } from '../server/commands/write_image_snapshot.ts';
4
4
  import type { ToMatchImageSnapshotOptions } from '../shared/types.ts';
5
5
  import type { CurrentTest } from './vitest_suite_proxy.ts';
6
- export declare function imageSnapshotMatcher(commands: PrepareImageSnapshotComparisonCommand & WriteImageSnapshotCommand & ImageSnapshotNextIndexCommand): (test: CurrentTest & {}, subject: any, options?: ToMatchImageSnapshotOptions<any>) => Promise<void>;
6
+ export declare function imageSnapshotMatcher(commands: BrowserCommands & PrepareImageSnapshotComparisonCommand & ImageSnapshotNextIndexCommand): (test: CurrentTest & {}, subject: any, options?: ToMatchImageSnapshotOptions<any>) => Promise<void>;
7
7
  /**
8
8
  * @deprecated internalized. Use `matchImageSnapshot` directly instead.
9
9
  */
@@ -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,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,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAOrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAE1D,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,qCAAqC,GAAG,yBAAyB,GAAG,6BAA6B,UAGpG,WAAW,GAAG,EAAE,WACb,GAAG,YACF,2BAA2B,CAAC,GAAG,CAAC,mBAqE3C;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":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAG9D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yDAAyD,CAAA;AAGpH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAOrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAE1D,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,eAAe,GAAG,qCAAqC,GAAG,6BAA6B,UAG1F,WAAW,GAAG,EAAE,WACb,GAAG,YACF,2BAA2B,CAAC,GAAG,CAAC,mBAqE3C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,GAAG,OAOrD"}
@@ -37,10 +37,10 @@ export function imageSnapshotMatcher(commands) {
37
37
  return;
38
38
  }
39
39
  if (server.config.snapshotOptions.updateSnapshot === 'all' && !options?.expectToFail) {
40
- await writeSnapshot(commands, info.baselinePath, resultImage);
40
+ await writeSnapshot(commands, resolve(info.projectRoot, info.baselinePath), resultImage);
41
41
  return;
42
42
  }
43
- await writeSnapshot(commands, info.diffPath, diffImage);
43
+ await writeSnapshot(commands, resolve(info.projectRoot, info.diffPath), diffImage);
44
44
  throw new Error(dedent `Snapshot \`${taskId}\` mismatched
45
45
 
46
46
  ${options?.failureThreshold
@@ -70,7 +70,7 @@ export function parseImageSnapshotSubject(subject) {
70
70
  }
71
71
  async function writeSnapshot(commands, path, image) {
72
72
  const content = (await toDataURL(image)).split(',')[1];
73
- return commands.writeImageSnapshot(path, content);
73
+ return commands.writeFile(path, content, { encoding: 'base64' });
74
74
  }
75
75
  async function parseImageSnapshotOptions(commands, taskId, isAutoSnapshot, options) {
76
76
  const index = await commands.imageSnapshotNextIndex(taskId);
@@ -13,7 +13,7 @@ export function setAutoSnapshotOptions(...args) {
13
13
  }
14
14
  function parseArgs(args) {
15
15
  return args.length === 1
16
- ? [ctx.getCurrentTest() ?? ctx.getCurrentSuite().tasks?.[0]?.file, parseMeta(args[0])]
16
+ ? [ctx.getCurrentTest() ?? ctx.getCurrentSuite()?.tasks?.[0]?.file, parseMeta(args[0])]
17
17
  : [args[0], parseMeta(args[1])];
18
18
  }
19
19
  function parseMeta(meta) {
package/esm/commands.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from './server/commands/has_image_snapshot.ts';
2
2
  export * from './server/commands/image_snapshot_next_index.ts';
3
3
  export * from './server/commands/match_image_snapshot.ts';
4
- export * from './server/commands/setup_vis_suite.ts';
5
4
  export * from './server/commands/prepare_image_snapshot_comparison.ts';
6
- export * from './server/commands/write_image_snapshot.ts';
5
+ export * from './server/commands/setup_vis_suite.ts';
7
6
  //# sourceMappingURL=commands.d.ts.map
@@ -1 +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;AACpD,cAAc,wDAAwD,CAAA;AACtE,cAAc,2CAA2C,CAAA"}
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,wDAAwD,CAAA;AACtE,cAAc,sCAAsC,CAAA"}
package/esm/commands.js CHANGED
@@ -1,6 +1,5 @@
1
1
  export * from "./server/commands/has_image_snapshot.js";
2
2
  export * from "./server/commands/image_snapshot_next_index.js";
3
3
  export * from "./server/commands/match_image_snapshot.js";
4
- export * from "./server/commands/setup_vis_suite.js";
5
4
  export * from "./server/commands/prepare_image_snapshot_comparison.js";
6
- export * from "./server/commands/write_image_snapshot.js";
5
+ export * from "./server/commands/setup_vis_suite.js";
@@ -22,11 +22,11 @@ export type VisOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTime
22
22
  */
23
23
  snapshotRootDir?: string | ((context: {
24
24
  ci: boolean;
25
- browserName: string;
25
+ browserName?: string | undefined;
26
26
  providerName: string;
27
27
  platform: string;
28
- screenshotFailures: boolean | undefined;
29
- screenshotDirectory: string | undefined;
28
+ screenshotFailures?: boolean | undefined;
29
+ screenshotDirectory?: string | undefined;
30
30
  }) => string) | undefined;
31
31
  /**
32
32
  * Customize the snapshot subpath.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,mBAAmB,EACnB,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,2BAA2B,GACzF,sBAAsB,GACtB,2BAA2B,CAAC,CAAC,CAAC,GAC9B,mBAAmB,GAAG;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC1D;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B;;;;OAIG;IACH,eAAe,CAAC,EACb,MAAM,GACN,CAAC,CAAC,OAAO,EAAE;QACX,EAAE,EAAE,OAAO,CAAA;QACX,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAA;QAChB,kBAAkB,EAAE,OAAO,GAAG,SAAS,CAAA;QACvC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;KACtC,KAAK,MAAM,CAAC,GACb,SAAS,CAAA;IACZ;;;;;;;;;;;;;;;;;;;OAmBG;IACH,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;CACtD,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,mBAAmB,EACnB,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,IAAI,2BAA2B,GACzF,sBAAsB,GACtB,2BAA2B,CAAC,CAAC,CAAC,GAC9B,mBAAmB,GAAG;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC1D;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B;;;;OAIG;IACH,eAAe,CAAC,EACb,MAAM,GACN,CAAC,CAAC,OAAO,EAAE;QACX,EAAE,EAAE,OAAO,CAAA;QACX,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAChC,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAA;QAChB,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;QACxC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KACvC,KAAK,MAAM,CAAC,GACb,SAAS,CAAA;IACZ;;;;;;;;;;;;;;;;;;;OAmBG;IACH,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;CACtD,CAAA"}
@@ -18,7 +18,6 @@ export declare function vis<M extends ComparisonMethod = 'pixel'>(options?: VisO
18
18
  hasImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, snapshotId: string | undefined, isAutoSnapshot: boolean]>;
19
19
  matchImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, subject: string, isAutoSnapshot: boolean, options?: import("../commands.ts").MatchImageSnapshotOptions | undefined]>;
20
20
  prepareImageSnapshotComparison: import("vitest/node").BrowserCommand<[taskId: string, snapshotId: string, isAutoSnapshot: boolean, options?: import("../commands.ts").MatchImageSnapshotOptions | undefined]>;
21
- writeImageSnapshot: import("vitest/node").BrowserCommand<[relativeFilePath: string, imageBase64: string]>;
22
21
  };
23
22
  };
24
23
  setupFiles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"vis.d.ts","sourceRoot":"","sources":["../../src/config/vis.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,EAAE,OAAO,GAAE,UAAU,CAAC,CAAC,CAA6B;;;;;sBAWxE,MAAM;;;;;;;;;;;;;EAQzC"}
1
+ {"version":3,"file":"vis.d.ts","sourceRoot":"","sources":["../../src/config/vis.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,gBAAgB,GAAG,OAAO,EAAE,OAAO,GAAE,UAAU,CAAC,CAAC,CAA6B;;;;;sBAWxE,MAAM;;;;;;;;;;;;EAQzC"}
@@ -4,7 +4,7 @@ export declare function getProjectName(context: {
4
4
  vite: {
5
5
  config: {
6
6
  test?: {
7
- name: string;
7
+ name?: string | undefined;
8
8
  };
9
9
  };
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"browser_command_context.d.ts","sourceRoot":"","sources":["../../../src/server/commands/browser_command_context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE;YAAE,MAAM,EAAE;gBAAE,IAAI,CAAC,EAAE;oBAAE,IAAI,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,sBAErG;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,qBAAqB,wCAE3E"}
1
+ {"version":3,"file":"browser_command_context.d.ts","sourceRoot":"","sources":["../../../src/server/commands/browser_command_context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE;YAAE,MAAM,EAAE;gBAAE,IAAI,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,sBAElH;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,qBAAqB,wCAE3E"}
@@ -3,9 +3,8 @@ import { type ImageSnapshotNextIndexCommand } from './image_snapshot_next_index.
3
3
  import { type MatchImageSnapshotCommand } from './match_image_snapshot.ts';
4
4
  import { type PrepareImageSnapshotComparisonCommand } from './prepare_image_snapshot_comparison.ts';
5
5
  import { type SetupVisSuiteCommand } from './setup_vis_suite.ts';
6
- import { type WriteImageSnapshotCommand } from './write_image_snapshot.ts';
7
6
  declare module '@vitest/browser/context' {
8
- interface BrowserCommands extends SetupVisSuiteCommand, ImageSnapshotNextIndexCommand, HasImageSnapshotCommand, PrepareImageSnapshotComparisonCommand, WriteImageSnapshotCommand, MatchImageSnapshotCommand {
7
+ interface BrowserCommands extends SetupVisSuiteCommand, ImageSnapshotNextIndexCommand, HasImageSnapshotCommand, PrepareImageSnapshotComparisonCommand, MatchImageSnapshotCommand {
9
8
  }
10
9
  }
11
10
  export declare const commands: {
@@ -14,6 +13,5 @@ export declare const commands: {
14
13
  hasImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, snapshotId: string | undefined, isAutoSnapshot: boolean]>;
15
14
  matchImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, subject: string, isAutoSnapshot: boolean, options?: import("./match_image_snapshot.ts").MatchImageSnapshotOptions | undefined]>;
16
15
  prepareImageSnapshotComparison: import("vitest/node").BrowserCommand<[taskId: string, snapshotId: string, isAutoSnapshot: boolean, options?: import("./match_image_snapshot.ts").MatchImageSnapshotOptions | undefined]>;
17
- writeImageSnapshot: import("vitest/node").BrowserCommand<[relativeFilePath: string, imageBase64: string]>;
18
16
  };
19
17
  //# sourceMappingURL=extend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/server/commands/extend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAoB,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,KAAK,6BAA6B,EAA0B,MAAM,gCAAgC,CAAA;AAC3G,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EACN,KAAK,qCAAqC,EAE1C,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,KAAK,oBAAoB,EAAiB,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,2BAA2B,CAAA;AAE9F,OAAO,QAAQ,yBAAyB,CAAC;IACxC,UAAU,eACT,SAAQ,oBAAoB,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,qCAAqC,EACrC,yBAAyB,EACzB,yBAAyB;KAAG;CAC9B;AAED,eAAO,MAAM,QAAQ;;;;;;;CAOpB,CAAA"}
1
+ {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/server/commands/extend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAoB,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,KAAK,6BAA6B,EAA0B,MAAM,gCAAgC,CAAA;AAC3G,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EACN,KAAK,qCAAqC,EAE1C,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,KAAK,oBAAoB,EAAiB,MAAM,sBAAsB,CAAA;AAE/E,OAAO,QAAQ,yBAAyB,CAAC;IACxC,UAAU,eACT,SAAQ,oBAAoB,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,qCAAqC,EACrC,yBAAyB;KAAG;CAC9B;AAED,eAAO,MAAM,QAAQ;;;;;;CAMpB,CAAA"}
@@ -3,12 +3,10 @@ import { imageSnapshotNextIndex } from "./image_snapshot_next_index.js";
3
3
  import { matchImageSnapshot } from "./match_image_snapshot.js";
4
4
  import { prepareImageSnapshotComparison, } from "./prepare_image_snapshot_comparison.js";
5
5
  import { setupVisSuite } from "./setup_vis_suite.js";
6
- import { writeImageSnapshot } from "./write_image_snapshot.js";
7
6
  export const commands = {
8
7
  setupVisSuite,
9
8
  imageSnapshotNextIndex,
10
9
  hasImageSnapshot,
11
10
  matchImageSnapshot,
12
11
  prepareImageSnapshotComparison,
13
- writeImageSnapshot,
14
12
  };
@@ -2,5 +2,5 @@ import { visContext } from "../vis_context.js";
2
2
  import { assertTestPathDefined } from "./_assertions.js";
3
3
  export const imageSnapshotNextIndex = async (context, taskId) => {
4
4
  assertTestPathDefined(context, 'imageSnapshotNextIndex');
5
- return visContext.getTaskCount(context.testPath, taskId);
5
+ return visContext.getTaskCount(context, taskId);
6
6
  };
@@ -15,7 +15,7 @@ export const matchImageSnapshot = async (context, taskId, subject, isAutoSnapsho
15
15
  if (!options)
16
16
  options = {};
17
17
  options.timeout = options.timeout ?? 30000;
18
- const info = visContext.getSnapshotInfo(context, taskId, isAutoSnapshot, options);
18
+ const info = await visContext.getSnapshotInfo(context, taskId, isAutoSnapshot, options);
19
19
  const baselineBuffer = await file.tryReadFile(info.baselinePath);
20
20
  if (!baselineBuffer) {
21
21
  if (isBase64String(subject)) {
@@ -2,11 +2,29 @@ import type { BrowserCommand } from 'vitest/node';
2
2
  import type { FailureThresholdOptions, ImageSnapshotTimeoutOptions, PixelComparisonOptions, SsimComparisonOptions } from '../../shared/types.ts';
3
3
  import type { MatchImageSnapshotOptions } from './match_image_snapshot.ts';
4
4
  type ImageSnapshotComparisonInfo = {
5
+ /**
6
+ * Path to the project root.
7
+ */
5
8
  projectRoot: string;
9
+ /**
10
+ * Path to the baseline image relative to the project root.
11
+ */
6
12
  baselinePath: string;
13
+ /**
14
+ * Path to the result image relative to the project root.
15
+ */
7
16
  resultPath: string;
17
+ /**
18
+ * Path to the diff image relative to the project root.
19
+ */
8
20
  diffPath: string;
21
+ /**
22
+ * Base64 encoded baseline image.
23
+ */
9
24
  baseline: string;
25
+ /**
26
+ * Base64 encoded result image.
27
+ */
10
28
  result: string;
11
29
  } & ImageSnapshotTimeoutOptions & FailureThresholdOptions & (SsimComparisonOptions | PixelComparisonOptions);
12
30
  export interface PrepareImageSnapshotComparisonCommand {
@@ -1 +1 @@
1
- {"version":3,"file":"prepare_image_snapshot_comparison.d.ts","sourceRoot":"","sources":["../../../src/server/commands/prepare_image_snapshot_comparison.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,KAAK,EACX,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,qBAAqB,EACrB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAE1E,KAAK,2BAA2B,GAAG;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACd,GAAG,2BAA2B,GAC9B,uBAAuB,GACvB,CAAC,qBAAqB,GAAG,sBAAsB,CAAC,CAAA;AAEjD,MAAM,WAAW,qCAAqC;IACrD,8BAA8B,EAAE,CAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAAA;CACrD;AAED,eAAO,MAAM,8BAA8B,EAAE,cAAc,CAC1D;IAAC,MAAM,EAAE,MAAM;IAAE,UAAU,EAAE,MAAM;IAAE,cAAc,EAAE,OAAO;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,CAyB9G,CAAA"}
1
+ {"version":3,"file":"prepare_image_snapshot_comparison.d.ts","sourceRoot":"","sources":["../../../src/server/commands/prepare_image_snapshot_comparison.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,KAAK,EACX,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,qBAAqB,EACrB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAE1E,KAAK,2BAA2B,GAAG;IAClC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACd,GAAG,2BAA2B,GAC9B,uBAAuB,GACvB,CAAC,qBAAqB,GAAG,sBAAsB,CAAC,CAAA;AAEjD,MAAM,WAAW,qCAAqC;IACrD,8BAA8B,EAAE,CAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAAA;CACrD;AAED,eAAO,MAAM,8BAA8B,EAAE,cAAc,CAC1D;IAAC,MAAM,EAAE,MAAM;IAAE,UAAU,EAAE,MAAM;IAAE,cAAc,EAAE,OAAO;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,CA0B9G,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { resolve } from 'pathe';
1
2
  import { isBase64String } from "../../shared/base64.js";
2
3
  import { file } from "../file.js";
3
4
  import { takeSnapshot, takeSnapshotByBrowser, writeSnapshot } from "../snapshot.js";
@@ -9,21 +10,22 @@ export const prepareImageSnapshotComparison = async (context, taskId, subject, i
9
10
  if (!options)
10
11
  options = {};
11
12
  options.timeout = options.timeout ?? 30000;
12
- const info = visContext.getSnapshotInfo(context, taskId, isAutoSnapshot, options);
13
- const baselineBuffer = await file.tryReadFile(info.baselinePath);
13
+ const projectRoot = context.project.config.root;
14
+ const info = await visContext.getSnapshotInfo(context, taskId, isAutoSnapshot, options);
15
+ const baselineBuffer = await file.tryReadFile(resolve(projectRoot, info.baselinePath));
14
16
  if (!baselineBuffer) {
15
17
  if (isBase64String(subject)) {
16
- await writeSnapshot(info.baselinePath, subject);
18
+ await writeSnapshot(resolve(projectRoot, info.baselinePath), subject);
17
19
  }
18
20
  else {
19
- await takeSnapshotByBrowser(context, info.baselinePath, subject, options);
21
+ await takeSnapshotByBrowser(context, resolve(projectRoot, info.baselinePath), subject, options);
20
22
  }
21
23
  return;
22
24
  }
23
- const resultBuffer = await takeSnapshot(context, info.resultPath, subject, options);
25
+ const resultBuffer = await takeSnapshot(context, resolve(projectRoot, info.resultPath), subject, options);
24
26
  return {
25
27
  ...info,
26
- projectRoot: context.project.config.root,
28
+ projectRoot,
27
29
  baseline: baselineBuffer.toString('base64'),
28
30
  result: resultBuffer.toString('base64'),
29
31
  };
@@ -12,8 +12,8 @@ export function resolveSnapshotRootDir(suite, options) {
12
12
  browserName: suite.provider.browserName,
13
13
  providerName: suite.provider.name,
14
14
  platform: process.platform,
15
- screenshotFailures: suite.provider.options.screenshotFailures,
16
- screenshotDirectory: suite.provider.options.screenshotDirectory,
15
+ screenshotFailures: suite.provider.options?.screenshotFailures,
16
+ screenshotDirectory: suite.provider.options?.screenshotDirectory,
17
17
  });
18
18
  }
19
19
  function getSnapshotRootDir(snapshotRootDir, platform = process.platform) {
@@ -2,11 +2,11 @@ export declare const visContext: {
2
2
  setOptions<M extends "pixel" | "ssim">(projectName: string | undefined, options?: import("../config.ts").VisOptions<M>): void;
3
3
  __test__getOptions(projectName: string): import("../config.ts").VisOptions<any> | undefined;
4
4
  __test__reset(): void;
5
- __test__getState(): import("./vis_context.types.ts").VisState;
6
- setupSuite(context: import("./vis_context.types.ts").PartialBrowserCommandContext): Promise<import("type-plus").Pick._<import("./vis_context.types.ts").VisState, "subjectDataTestId">>;
5
+ __test__getState(context: import("./vis_context.types.ts").PartialBrowserCommandContext): Promise<import("./vis_context.types.ts").VisProjectState>;
6
+ setupSuite(context: import("./vis_context.types.ts").PartialBrowserCommandContext): Promise<import("type-plus").Pick._<import("./vis_context.types.ts").VisProjectState, "subjectDataTestId">>;
7
7
  getSnapshotInfo(browserContext: import("./vis_context.types.ts").PartialBrowserCommandContext, name: string, isAutoSnapshot: boolean, options?: {
8
8
  snapshotFileId?: string | undefined;
9
- }): {
9
+ }): Promise<{
10
10
  baselinePath: string;
11
11
  resultPath: string;
12
12
  diffPath: string;
@@ -32,8 +32,8 @@ export declare const visContext: {
32
32
  diffColorAlt?: [number, number, number] | undefined;
33
33
  diffMask?: boolean | undefined;
34
34
  } | undefined;
35
- };
36
- getTaskCount(testPath: string, taskId: string): number;
35
+ }>;
36
+ getTaskCount(browserContext: import("./vis_context.types.ts").PartialBrowserCommandContext, taskId: string): Promise<number>;
37
37
  hasImageSnapshot(browserContext: import("./vis_context.types.ts").PartialBrowserCommandContext, taskId: string, snapshotFileId: string | undefined, isAutoSnapshot: boolean): Promise<boolean>;
38
38
  getSnapshotFilename(browserContext: import("./vis_context.types.ts").PartialBrowserCommandContext, info: {
39
39
  taskId: string;
@@ -41,7 +41,8 @@ export declare const visContext: {
41
41
  count: number;
42
42
  };
43
43
  }, snapshotFileId: string | undefined, isAutoSnapshot: boolean): string;
44
- getSuiteInfo(testPath: string, taskId: string): {
44
+ getSuiteInfo(browserContext: import("./vis_context.types.ts").PartialBrowserCommandContext, taskId: string): Promise<{
45
+ projectRoot: string;
45
46
  suiteId: string;
46
47
  taskId: string;
47
48
  baselineDir: string;
@@ -50,6 +51,6 @@ export declare const visContext: {
50
51
  task: {
51
52
  count: number;
52
53
  };
53
- };
54
+ }>;
54
55
  };
55
56
  //# sourceMappingURL=vis_context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBAC8wD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAD1vD,CAAA"}
1
+ {"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBACq6D,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CADj5D,CAAA"}
@@ -1,19 +1,19 @@
1
1
  import type { VisOptions } from '../config/types.ts';
2
- import type { PartialBrowserCommandContext, VisState } from './vis_context.types.ts';
2
+ import type { PartialBrowserCommandContext, VisProjectState } from './vis_context.types.ts';
3
3
  export declare function createVisContext(): {
4
4
  setOptions<M extends "pixel" | "ssim">(projectName: string | undefined, options?: VisOptions<M>): void;
5
5
  __test__getOptions(projectName: string): VisOptions<any> | undefined;
6
6
  __test__reset(): void;
7
- __test__getState(): VisState;
7
+ __test__getState(context: PartialBrowserCommandContext): Promise<VisProjectState>;
8
8
  /**
9
9
  * Setup suite is called on each test file's beforeAll hook.
10
10
  * Test files include vitest test files and storybook story files.
11
11
  * It needs to make sure there is no race condition between the test files.
12
12
  */
13
- setupSuite(context: PartialBrowserCommandContext): Promise<import("type-plus").Pick._<VisState, "subjectDataTestId">>;
13
+ setupSuite(context: PartialBrowserCommandContext): Promise<import("type-plus").Pick._<VisProjectState, "subjectDataTestId">>;
14
14
  getSnapshotInfo(browserContext: PartialBrowserCommandContext, name: string, isAutoSnapshot: boolean, options?: {
15
15
  snapshotFileId?: string | undefined;
16
- }): {
16
+ }): Promise<{
17
17
  baselinePath: string;
18
18
  resultPath: string;
19
19
  diffPath: string;
@@ -39,8 +39,8 @@ export declare function createVisContext(): {
39
39
  diffColorAlt?: [number, number, number] | undefined;
40
40
  diffMask?: boolean | undefined;
41
41
  } | undefined;
42
- };
43
- getTaskCount(testPath: string, taskId: string): number;
42
+ }>;
43
+ getTaskCount(browserContext: PartialBrowserCommandContext, taskId: string): Promise<number>;
44
44
  hasImageSnapshot(browserContext: PartialBrowserCommandContext, taskId: string, snapshotFileId: string | undefined, isAutoSnapshot: boolean): Promise<boolean>;
45
45
  getSnapshotFilename(browserContext: PartialBrowserCommandContext, info: {
46
46
  taskId: string;
@@ -48,7 +48,8 @@ export declare function createVisContext(): {
48
48
  count: number;
49
49
  };
50
50
  }, snapshotFileId: string | undefined, isAutoSnapshot: boolean): string;
51
- getSuiteInfo(testPath: string, taskId: string): {
51
+ getSuiteInfo(browserContext: PartialBrowserCommandContext, taskId: string): Promise<{
52
+ projectRoot: string;
52
53
  suiteId: string;
53
54
  taskId: string;
54
55
  baselineDir: string;
@@ -57,9 +58,9 @@ export declare function createVisContext(): {
57
58
  task: {
58
59
  count: number;
59
60
  };
60
- };
61
+ }>;
61
62
  };
62
- export declare function createSuite(state: VisState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>): {
63
+ export declare function createSuite(state: VisProjectState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>): {
63
64
  suiteId: string;
64
65
  suite: {
65
66
  baselineDir: string;
@@ -68,5 +69,5 @@ export declare function createSuite(state: VisState, testPath: string, options:
68
69
  tasks: {};
69
70
  };
70
71
  };
71
- export declare function getSuiteId(state: VisState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>): string;
72
+ export declare function getSuiteId(state: VisProjectState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>): string;
72
73
  //# sourceMappingURL=vis_context.logic.d.ts.map
@@ -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;AAMpD,OAAO,KAAK,EAAE,4BAA4B,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEpF,wBAAgB,gBAAgB;eAMnB,CAAC,SAAS,OAAO,GAAG,MAAM,eAAe,MAAM,GAAG,SAAS,YAAW,UAAU,CAAC,CAAC,CAAC;oCAG9D,MAAM;;;IAStC;;;;OAIG;wBACuB,4BAA4B;oCAcrC,4BAA4B,QACtC,MAAM,kBACI,OAAO,YACb;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA+B3B,MAAM,UAAU,MAAM;qCAI5B,4BAA4B,UACpC,MAAM,kBACE,MAAM,GAAG,SAAS,kBAClB,OAAO;wCAQP,4BAA4B,QACtC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,kBACjC,MAAM,GAAG,SAAS,kBAClB,OAAO;2BAWD,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":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAMpD,OAAO,KAAK,EAAE,4BAA4B,EAAE,eAAe,EAAY,MAAM,wBAAwB,CAAA;AAErG,wBAAgB,gBAAgB;eAKnB,CAAC,SAAS,OAAO,GAAG,MAAM,eAAe,MAAM,GAAG,SAAS,YAAW,UAAU,CAAC,CAAC,CAAC;oCAG9D,MAAM;;8BAOZ,4BAA4B;IAItD;;;;OAIG;wBACuB,4BAA4B;oCAgBrC,4BAA4B,QACtC,MAAM,kBACI,OAAO,YACb;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA+Bf,4BAA4B,UAAU,MAAM;qCAI9D,4BAA4B,UACpC,MAAM,kBACE,MAAM,GAAG,SAAS,kBAClB,OAAO;wCAaP,4BAA4B,QACtC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,kBACjC,MAAM,GAAG,SAAS,kBAClB,OAAO;iCAWW,4BAA4B,UAAU,MAAM;;;;;;;;;;;EAmBhF;AAyBD,wBAAgB,WAAW,CAC1B,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC;;;;;;;;EAYrD;AAED,wBAAgB,UAAU,CACzB,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC,UAGrD"}
@@ -1,4 +1,4 @@
1
- import { join, relative } from 'pathe';
1
+ import { join, relative, resolve } from 'pathe';
2
2
  import { pick } from 'type-plus';
3
3
  import { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from "../shared/constants.js";
4
4
  import { getProjectName } from "./commands/browser_command_context.js";
@@ -7,8 +7,7 @@ import { getSnapshotSubpath, resolveSnapshotRootDir } from "./snapshot_path.js";
7
7
  import { ctx } from "./vis_context.ctx.js";
8
8
  export function createVisContext() {
9
9
  let visOptionsRecord = {};
10
- let state;
11
- let globalStateReady;
10
+ let state = {};
12
11
  const context = {
13
12
  setOptions(projectName, options = {}) {
14
13
  visOptionsRecord[projectName ?? '__default'] = options;
@@ -18,9 +17,11 @@ export function createVisContext() {
18
17
  },
19
18
  __test__reset() {
20
19
  visOptionsRecord = {};
20
+ state = {};
21
21
  },
22
- __test__getState() {
23
- return state;
22
+ __test__getState(context) {
23
+ const projectRoot = getProjectRoot(context);
24
+ return state[projectRoot];
24
25
  },
25
26
  /**
26
27
  * Setup suite is called on each test file's beforeAll hook.
@@ -28,20 +29,18 @@ export function createVisContext() {
28
29
  * It needs to make sure there is no race condition between the test files.
29
30
  */
30
31
  async setupSuite(context) {
31
- if (!globalStateReady) {
32
- globalStateReady = setupState(context, getVisOptions(visOptionsRecord, context) ?? {});
33
- state = await globalStateReady;
32
+ const projectRoot = getProjectRoot(context);
33
+ if (!state[projectRoot]) {
34
+ state[projectRoot] = setupState(context, getVisOptions(visOptionsRecord, context) ?? {});
34
35
  }
35
- else {
36
- await globalStateReady;
37
- }
38
- const { suiteId, suite } = createSuite(state, context.testPath, visOptionsRecord);
39
- state.suites[suiteId] = suite;
36
+ const projectState = await state[projectRoot];
37
+ const { suiteId, suite } = createSuite(projectState, context.testPath, visOptionsRecord);
38
+ projectState.suites[suiteId] = suite;
40
39
  await Promise.allSettled([ctx.rimraf(suite.diffDir), ctx.rimraf(suite.resultDir)]);
41
- return pick(state, 'subjectDataTestId');
40
+ return pick(projectState, 'subjectDataTestId');
42
41
  },
43
- getSnapshotInfo(browserContext, name, isAutoSnapshot, options) {
44
- const suiteInfo = context.getSuiteInfo(browserContext.testPath, name);
42
+ async getSnapshotInfo(browserContext, name, isAutoSnapshot, options) {
43
+ const suiteInfo = await context.getSuiteInfo(browserContext, name);
45
44
  const snapshotFilename = context.getSnapshotFilename(browserContext, suiteInfo, options?.snapshotFileId, isAutoSnapshot);
46
45
  const { baselineDir, resultDir, diffDir, task } = suiteInfo;
47
46
  task.count = task.count + 1;
@@ -55,12 +54,12 @@ export function createVisContext() {
55
54
  diffPath,
56
55
  };
57
56
  },
58
- getTaskCount(testPath, taskId) {
59
- return context.getSuiteInfo(testPath, taskId).task.count;
57
+ async getTaskCount(browserContext, taskId) {
58
+ return (await context.getSuiteInfo(browserContext, taskId)).task.count;
60
59
  },
61
- hasImageSnapshot(browserContext, taskId, snapshotFileId, isAutoSnapshot) {
62
- const info = context.getSuiteInfo(browserContext.testPath, taskId);
63
- return file.existFile(join(info.baselineDir, context.getSnapshotFilename(browserContext, info, snapshotFileId, isAutoSnapshot)));
60
+ async hasImageSnapshot(browserContext, taskId, snapshotFileId, isAutoSnapshot) {
61
+ const info = await context.getSuiteInfo(browserContext, taskId);
62
+ return file.existFile(resolve(info.projectRoot, info.baselineDir, context.getSnapshotFilename(browserContext, info, snapshotFileId, isAutoSnapshot)));
64
63
  },
65
64
  getSnapshotFilename(browserContext, info, snapshotFileId, isAutoSnapshot) {
66
65
  if (snapshotFileId)
@@ -72,11 +71,14 @@ export function createVisContext() {
72
71
  isAutoSnapshot,
73
72
  })}.png`;
74
73
  },
75
- getSuiteInfo(testPath, taskId) {
76
- const suiteId = getSuiteId(state, testPath, visOptionsRecord);
77
- const suite = state.suites[suiteId];
74
+ async getSuiteInfo(browserContext, taskId) {
75
+ const projectRoot = getProjectRoot(browserContext);
76
+ const projectState = await state[projectRoot];
77
+ const suiteId = getSuiteId(projectState, browserContext.testPath, visOptionsRecord);
78
+ const suite = projectState.suites[suiteId];
78
79
  const task = (suite.tasks[taskId] = suite.tasks[taskId] ?? { count: 1 });
79
80
  return {
81
+ projectRoot,
80
82
  suiteId,
81
83
  taskId,
82
84
  baselineDir: suite.baselineDir,
@@ -88,18 +90,18 @@ export function createVisContext() {
88
90
  };
89
91
  return context;
90
92
  }
91
- async function setupState(suite, visOptions) {
92
- const snapshotRootDir = resolveSnapshotRootDir(suite, visOptions);
93
- const projectPath = suite.project.config.root;
93
+ async function setupState(browserContext, visOptions) {
94
+ const snapshotRootDir = resolveSnapshotRootDir(browserContext, visOptions);
95
+ const projectRoot = getProjectRoot(browserContext);
94
96
  const state = {
95
- projectPath,
96
- testTimeout: suite.project.config.testTimeout,
97
- hookTimeout: suite.project.config.hookTimeout,
97
+ projectRoot,
98
+ testTimeout: browserContext.project.config.testTimeout,
99
+ hookTimeout: browserContext.project.config.hookTimeout,
98
100
  snapshotRootDir,
99
101
  snapshotBaselineDir: join(snapshotRootDir, BASELINE_DIR),
100
102
  snapshotResultDir: join(snapshotRootDir, RESULT_DIR),
101
103
  snapshotDiffDir: join(snapshotRootDir, DIFF_DIR),
102
- snapshotRootPath: join(projectPath, snapshotRootDir),
104
+ snapshotRootPath: join(projectRoot, snapshotRootDir),
103
105
  subjectDataTestId: visOptions.subjectDataTestId,
104
106
  suites: {},
105
107
  };
@@ -119,8 +121,11 @@ export function createSuite(state, testPath, options) {
119
121
  };
120
122
  }
121
123
  export function getSuiteId(state, testPath, options) {
122
- return getSnapshotSubpath(relative(state.projectPath, testPath), options);
124
+ return getSnapshotSubpath(relative(state.projectRoot, testPath), options);
123
125
  }
124
126
  function getVisOptions(visOptionsRecord, context) {
125
127
  return visOptionsRecord[getProjectName(context) ?? '__default'];
126
128
  }
129
+ function getProjectRoot(context) {
130
+ return context.project.config.root;
131
+ }
@@ -1,5 +1,8 @@
1
1
  export type VisState = {
2
- projectPath: string;
2
+ [projectPath: string]: Promise<VisProjectState>;
3
+ };
4
+ export type VisProjectState = {
5
+ projectRoot: string;
3
6
  testTimeout: number;
4
7
  hookTimeout: number;
5
8
  snapshotRootDir: string;
@@ -30,18 +33,18 @@ export type PartialBrowserCommandContext = {
30
33
  vite: {
31
34
  config: {
32
35
  test?: {
33
- name: string;
36
+ name?: string | undefined;
34
37
  };
35
38
  };
36
39
  };
37
40
  };
38
41
  provider: {
39
42
  name: string;
40
- browserName: string;
41
- options: {
42
- headless: boolean | undefined;
43
- screenshotFailures: boolean | undefined;
44
- screenshotDirectory: string | undefined;
43
+ browserName?: string | undefined;
44
+ options?: {
45
+ headless?: boolean | undefined;
46
+ screenshotFailures?: boolean | undefined;
47
+ screenshotDirectory?: string | undefined;
45
48
  };
46
49
  };
47
50
  testPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"vis_context.types.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,MAAM,CAAA;IAEnB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,iBAAiB,EAAE,MAAM,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,MAAM,CACb,MAAM,EACN;QACC,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CACZ,MAAM,EACN;YACC,KAAK,EAAE,MAAM,CAAA;SACb,CACD,CAAA;KACD,CACD,CAAA;CACD,CAAA;AACD,MAAM,MAAM,4BAA4B,GAAG;IAC1C,OAAO,EAAE;QACR,MAAM,EAAE;YACP,IAAI,EAAE,MAAM,CAAA;YACZ,eAAe,EAAE;gBAChB,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;aACtC,CAAA;YACD,WAAW,EAAE,MAAM,CAAA;YACnB,WAAW,EAAE,MAAM,CAAA;SACnB,CAAA;QACD,IAAI,EAAE;YACL,MAAM,EAAE;gBACP,IAAI,CAAC,EAAE;oBACN,IAAI,EAAE,MAAM,CAAA;iBACZ,CAAA;aACD,CAAA;SACD,CAAA;KACD,CAAA;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,OAAO,EAAE;YACR,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;YAC7B,kBAAkB,EAAE,OAAO,GAAG,SAAS,CAAA;YACvC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;SACvC,CAAA;KACD,CAAA;IACD,QAAQ,EAAE,MAAM,CAAA;CAChB,CAAA"}
1
+ {"version":3,"file":"vis_context.types.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACtB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAC/C,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,iBAAiB,EAAE,MAAM,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,MAAM,CACb,MAAM,EACN;QACC,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CACZ,MAAM,EACN;YACC,KAAK,EAAE,MAAM,CAAA;SACb,CACD,CAAA;KACD,CACD,CAAA;CACD,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IAC1C,OAAO,EAAE;QACR,MAAM,EAAE;YACP,IAAI,EAAE,MAAM,CAAA;YACZ,eAAe,EAAE;gBAChB,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;aACtC,CAAA;YACD,WAAW,EAAE,MAAM,CAAA;YACnB,WAAW,EAAE,MAAM,CAAA;SACnB,CAAA;QACD,IAAI,EAAE;YACL,MAAM,EAAE;gBACP,IAAI,CAAC,EAAE;oBACN,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;iBACzB,CAAA;aACD,CAAA;SACD,CAAA;KACD,CAAA;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAChC,OAAO,CAAC,EAAE;YACT,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;YAC9B,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;YACxC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SACxC,CAAA;KACD,CAAA;IACD,QAAQ,EAAE,MAAM,CAAA;CAChB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-plugin-vis",
3
- "version": "2.3.3",
3
+ "version": "2.4.0",
4
4
  "description": "Vitest visual testing plugin",
5
5
  "keywords": [
6
6
  "image-snapshot",
@@ -107,6 +107,7 @@
107
107
  "build": "tsc",
108
108
  "build:watch": "tsc -w",
109
109
  "clean": "rimraf coverage esm *.tsbuildinfo vitest.*.timestamp*",
110
+ "clean:vis:local": "rimraf __vis__/local",
110
111
  "cov": "cross-env COVERAGE=true vitest run --coverage",
111
112
  "coverage": "cross-env COVERAGE=true vitest run --coverage",
112
113
  "dev": "run-p build:watch w",
@@ -1,8 +1,8 @@
1
+ import type { BrowserCommands } from '@vitest/browser/context'
1
2
  import dedent from 'dedent'
2
3
  import { resolve } from 'pathe'
3
4
  import type { ImageSnapshotNextIndexCommand } from '../commands.ts'
4
5
  import type { PrepareImageSnapshotComparisonCommand } from '../server/commands/prepare_image_snapshot_comparison.ts'
5
- import type { WriteImageSnapshotCommand } from '../server/commands/write_image_snapshot.ts'
6
6
  import { isBase64String } from '../shared/base64.ts'
7
7
  import { compareImage } from '../shared/compare_image.ts'
8
8
  import type { ToMatchImageSnapshotOptions } from '../shared/types.ts'
@@ -15,7 +15,7 @@ import { server } from './vitest_browser_context_proxy.ts'
15
15
  import type { CurrentTest } from './vitest_suite_proxy.ts'
16
16
 
17
17
  export function imageSnapshotMatcher(
18
- commands: PrepareImageSnapshotComparisonCommand & WriteImageSnapshotCommand & ImageSnapshotNextIndexCommand,
18
+ commands: BrowserCommands & PrepareImageSnapshotComparisonCommand & ImageSnapshotNextIndexCommand,
19
19
  ) {
20
20
  return async function matchImageSnapshot(
21
21
  test: CurrentTest & {},
@@ -65,11 +65,11 @@ export function imageSnapshotMatcher(
65
65
  return
66
66
  }
67
67
  if (server.config.snapshotOptions.updateSnapshot === 'all' && !options?.expectToFail) {
68
- await writeSnapshot(commands, info.baselinePath, resultImage)
68
+ await writeSnapshot(commands, resolve(info.projectRoot, info.baselinePath), resultImage)
69
69
  return
70
70
  }
71
71
 
72
- await writeSnapshot(commands, info.diffPath, diffImage)
72
+ await writeSnapshot(commands, resolve(info.projectRoot, info.diffPath), diffImage)
73
73
 
74
74
  throw new Error(
75
75
  dedent`Snapshot \`${taskId}\` mismatched
@@ -103,9 +103,9 @@ export function parseImageSnapshotSubject(subject: any) {
103
103
  )
104
104
  }
105
105
 
106
- async function writeSnapshot(commands: WriteImageSnapshotCommand, path: string, image: ImageData) {
106
+ async function writeSnapshot(commands: BrowserCommands, path: string, image: ImageData) {
107
107
  const content = (await toDataURL(image)).split(',')[1]!
108
- return commands.writeImageSnapshot(path, content)
108
+ return commands.writeFile(path, content, { encoding: 'base64' })
109
109
  }
110
110
 
111
111
  async function parseImageSnapshotOptions(
@@ -51,7 +51,7 @@ function parseArgs<M extends ComparisonMethod>(
51
51
  args: [task: MetaTask, meta: SnapshotMeta<M> | boolean] | [meta: boolean | SnapshotMeta<M>],
52
52
  ): [MetaTask | undefined, SnapshotMeta<M>] {
53
53
  return args.length === 1
54
- ? [ctx.getCurrentTest() ?? (ctx.getCurrentSuite().tasks?.[0] as any)?.file, parseMeta(args[0])]
54
+ ? [ctx.getCurrentTest() ?? (ctx.getCurrentSuite()?.tasks?.[0] as any)?.file, parseMeta(args[0])]
55
55
  : [args[0], parseMeta(args[1])]
56
56
  }
57
57
 
package/src/commands.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export * from './server/commands/has_image_snapshot.ts'
2
2
  export * from './server/commands/image_snapshot_next_index.ts'
3
3
  export * from './server/commands/match_image_snapshot.ts'
4
- export * from './server/commands/setup_vis_suite.ts'
5
4
  export * from './server/commands/prepare_image_snapshot_comparison.ts'
6
- export * from './server/commands/write_image_snapshot.ts'
5
+ export * from './server/commands/setup_vis_suite.ts'
@@ -35,11 +35,11 @@ export type VisOptions<M extends ComparisonMethod = 'pixel'> = ImageSnapshotTime
35
35
  | string
36
36
  | ((context: {
37
37
  ci: boolean
38
- browserName: string
38
+ browserName?: string | undefined
39
39
  providerName: string
40
40
  platform: string
41
- screenshotFailures: boolean | undefined
42
- screenshotDirectory: string | undefined
41
+ screenshotFailures?: boolean | undefined
42
+ screenshotDirectory?: string | undefined
43
43
  }) => string)
44
44
  | undefined
45
45
  /**
@@ -1,6 +1,6 @@
1
1
  import type { BrowserCommandContext } from 'vitest/node'
2
2
 
3
- export function getProjectName(context: { project: { vite: { config: { test?: { name: string } } } } }) {
3
+ export function getProjectName(context: { project: { vite: { config: { test?: { name?: string | undefined } } } } }) {
4
4
  return context.project.vite.config.test?.name
5
5
  }
6
6
 
@@ -6,7 +6,6 @@ import {
6
6
  prepareImageSnapshotComparison,
7
7
  } from './prepare_image_snapshot_comparison.ts'
8
8
  import { type SetupVisSuiteCommand, setupVisSuite } from './setup_vis_suite.ts'
9
- import { type WriteImageSnapshotCommand, writeImageSnapshot } from './write_image_snapshot.ts'
10
9
 
11
10
  declare module '@vitest/browser/context' {
12
11
  interface BrowserCommands
@@ -14,7 +13,6 @@ declare module '@vitest/browser/context' {
14
13
  ImageSnapshotNextIndexCommand,
15
14
  HasImageSnapshotCommand,
16
15
  PrepareImageSnapshotComparisonCommand,
17
- WriteImageSnapshotCommand,
18
16
  MatchImageSnapshotCommand {}
19
17
  }
20
18
 
@@ -24,5 +22,4 @@ export const commands = {
24
22
  hasImageSnapshot,
25
23
  matchImageSnapshot,
26
24
  prepareImageSnapshotComparison,
27
- writeImageSnapshot,
28
25
  }
@@ -12,5 +12,5 @@ export interface ImageSnapshotNextIndexCommand {
12
12
  export const imageSnapshotNextIndex: BrowserCommand<[taskId: string]> = async (context, taskId) => {
13
13
  assertTestPathDefined(context, 'imageSnapshotNextIndex')
14
14
 
15
- return visContext.getTaskCount(context.testPath, taskId)
15
+ return visContext.getTaskCount(context, taskId)
16
16
  }
@@ -43,7 +43,7 @@ export const matchImageSnapshot: BrowserCommand<
43
43
  if (!options) options = {}
44
44
  options.timeout = options.timeout ?? 30000
45
45
 
46
- const info = visContext.getSnapshotInfo(context as any, taskId, isAutoSnapshot, options)
46
+ const info = await visContext.getSnapshotInfo(context as any, taskId, isAutoSnapshot, options)
47
47
  const baselineBuffer = await file.tryReadFile(info.baselinePath)
48
48
  if (!baselineBuffer) {
49
49
  if (isBase64String(subject)) {
@@ -1,3 +1,4 @@
1
+ import { resolve } from 'pathe'
1
2
  import type { BrowserCommand } from 'vitest/node'
2
3
  import { isBase64String } from '../../shared/base64.ts'
3
4
  import type {
@@ -13,11 +14,29 @@ import { assertTestPathDefined } from './_assertions.ts'
13
14
  import type { MatchImageSnapshotOptions } from './match_image_snapshot.ts'
14
15
 
15
16
  type ImageSnapshotComparisonInfo = {
17
+ /**
18
+ * Path to the project root.
19
+ */
16
20
  projectRoot: string
21
+ /**
22
+ * Path to the baseline image relative to the project root.
23
+ */
17
24
  baselinePath: string
25
+ /**
26
+ * Path to the result image relative to the project root.
27
+ */
18
28
  resultPath: string
29
+ /**
30
+ * Path to the diff image relative to the project root.
31
+ */
19
32
  diffPath: string
33
+ /**
34
+ * Base64 encoded baseline image.
35
+ */
20
36
  baseline: string
37
+ /**
38
+ * Base64 encoded result image.
39
+ */
21
40
  result: string
22
41
  } & ImageSnapshotTimeoutOptions &
23
42
  FailureThresholdOptions &
@@ -40,21 +59,22 @@ export const prepareImageSnapshotComparison: BrowserCommand<
40
59
  if (!options) options = {}
41
60
  options.timeout = options.timeout ?? 30000
42
61
 
43
- const info = visContext.getSnapshotInfo(context as any, taskId, isAutoSnapshot, options)
44
- const baselineBuffer = await file.tryReadFile(info.baselinePath)
62
+ const projectRoot = context.project.config.root
63
+ const info = await visContext.getSnapshotInfo(context as any, taskId, isAutoSnapshot, options)
64
+ const baselineBuffer = await file.tryReadFile(resolve(projectRoot, info.baselinePath))
45
65
  if (!baselineBuffer) {
46
66
  if (isBase64String(subject)) {
47
- await writeSnapshot(info.baselinePath, subject)
67
+ await writeSnapshot(resolve(projectRoot, info.baselinePath), subject)
48
68
  } else {
49
- await takeSnapshotByBrowser(context, info.baselinePath, subject, options)
69
+ await takeSnapshotByBrowser(context, resolve(projectRoot, info.baselinePath), subject, options)
50
70
  }
51
71
  return
52
72
  }
53
73
 
54
- const resultBuffer = await takeSnapshot(context, info.resultPath, subject, options)
74
+ const resultBuffer = await takeSnapshot(context, resolve(projectRoot, info.resultPath), subject, options)
55
75
  return {
56
76
  ...info,
57
- projectRoot: context.project.config.root,
77
+ projectRoot,
58
78
  baseline: baselineBuffer.toString('base64'),
59
79
  result: resultBuffer.toString('base64'),
60
80
  }
@@ -13,8 +13,8 @@ export function resolveSnapshotRootDir(suite: PartialBrowserCommandContext, opti
13
13
  browserName: suite.provider.browserName,
14
14
  providerName: suite.provider.name,
15
15
  platform: process.platform,
16
- screenshotFailures: suite.provider.options.screenshotFailures,
17
- screenshotDirectory: suite.provider.options.screenshotDirectory,
16
+ screenshotFailures: suite.provider.options?.screenshotFailures,
17
+ screenshotDirectory: suite.provider.options?.screenshotDirectory,
18
18
  })
19
19
  }
20
20
 
@@ -1,4 +1,4 @@
1
- import { join, relative } from 'pathe'
1
+ import { join, relative, resolve } from 'pathe'
2
2
  import { pick } from 'type-plus'
3
3
  import type { VisOptions } from '../config/types.ts'
4
4
  import { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from '../shared/constants.ts'
@@ -6,12 +6,11 @@ import { getProjectName } from './commands/browser_command_context.ts'
6
6
  import { file } from './file.ts'
7
7
  import { getSnapshotSubpath, resolveSnapshotRootDir } from './snapshot_path.ts'
8
8
  import { ctx } from './vis_context.ctx.ts'
9
- import type { PartialBrowserCommandContext, VisState } from './vis_context.types.ts'
9
+ import type { PartialBrowserCommandContext, VisProjectState, VisState } from './vis_context.types.ts'
10
10
 
11
11
  export function createVisContext() {
12
12
  let visOptionsRecord: Record<string, VisOptions<any>> = {}
13
- let state: VisState
14
- let globalStateReady: Promise<VisState>
13
+ let state: VisState = {}
15
14
 
16
15
  const context = {
17
16
  setOptions<M extends 'pixel' | 'ssim'>(projectName: string | undefined, options: VisOptions<M> = {} as any) {
@@ -21,10 +20,12 @@ export function createVisContext() {
21
20
  return visOptionsRecord[projectName]
22
21
  },
23
22
  __test__reset() {
24
- visOptionsRecord = {} as any
23
+ visOptionsRecord = {}
24
+ state = {}
25
25
  },
26
- __test__getState() {
27
- return state
26
+ __test__getState(context: PartialBrowserCommandContext) {
27
+ const projectRoot = getProjectRoot(context)
28
+ return state[projectRoot]!
28
29
  },
29
30
  /**
30
31
  * Setup suite is called on each test file's beforeAll hook.
@@ -32,25 +33,27 @@ export function createVisContext() {
32
33
  * It needs to make sure there is no race condition between the test files.
33
34
  */
34
35
  async setupSuite(context: PartialBrowserCommandContext) {
35
- if (!globalStateReady) {
36
- globalStateReady = setupState(context, getVisOptions(visOptionsRecord, context) ?? {})
37
- state = await globalStateReady
38
- } else {
39
- await globalStateReady
36
+ const projectRoot = getProjectRoot(context)
37
+
38
+ if (!state[projectRoot]) {
39
+ state[projectRoot] = setupState(context, getVisOptions(visOptionsRecord, context) ?? {})
40
40
  }
41
41
 
42
- const { suiteId, suite } = createSuite(state, context.testPath, visOptionsRecord)
43
- state.suites[suiteId] = suite
42
+ const projectState = await state[projectRoot]
43
+
44
+ const { suiteId, suite } = createSuite(projectState, context.testPath, visOptionsRecord)
45
+ projectState.suites[suiteId] = suite
46
+
44
47
  await Promise.allSettled([ctx.rimraf(suite.diffDir), ctx.rimraf(suite.resultDir)])
45
- return pick(state, 'subjectDataTestId')
48
+ return pick(projectState, 'subjectDataTestId')
46
49
  },
47
- getSnapshotInfo(
50
+ async getSnapshotInfo(
48
51
  browserContext: PartialBrowserCommandContext,
49
52
  name: string,
50
53
  isAutoSnapshot: boolean,
51
54
  options?: { snapshotFileId?: string | undefined },
52
55
  ) {
53
- const suiteInfo = context.getSuiteInfo(browserContext.testPath, name)
56
+ const suiteInfo = await context.getSuiteInfo(browserContext, name)
54
57
  const snapshotFilename = context.getSnapshotFilename(
55
58
  browserContext,
56
59
  suiteInfo,
@@ -79,18 +82,23 @@ export function createVisContext() {
79
82
  diffPath,
80
83
  }
81
84
  },
82
- getTaskCount(testPath: string, taskId: string) {
83
- return context.getSuiteInfo(testPath, taskId).task.count
85
+ async getTaskCount(browserContext: PartialBrowserCommandContext, taskId: string) {
86
+ return (await context.getSuiteInfo(browserContext, taskId)).task.count
84
87
  },
85
- hasImageSnapshot(
88
+ async hasImageSnapshot(
86
89
  browserContext: PartialBrowserCommandContext,
87
90
  taskId: string,
88
91
  snapshotFileId: string | undefined,
89
92
  isAutoSnapshot: boolean,
90
93
  ) {
91
- const info = context.getSuiteInfo(browserContext.testPath, taskId)
94
+ const info = await context.getSuiteInfo(browserContext, taskId)
95
+
92
96
  return file.existFile(
93
- join(info.baselineDir, context.getSnapshotFilename(browserContext, info, snapshotFileId, isAutoSnapshot)),
97
+ resolve(
98
+ info.projectRoot,
99
+ info.baselineDir,
100
+ context.getSnapshotFilename(browserContext, info, snapshotFileId, isAutoSnapshot),
101
+ ),
94
102
  )
95
103
  },
96
104
  getSnapshotFilename(
@@ -108,11 +116,15 @@ export function createVisContext() {
108
116
  isAutoSnapshot,
109
117
  })}.png`
110
118
  },
111
- getSuiteInfo(testPath: string, taskId: string) {
112
- const suiteId = getSuiteId(state, testPath, visOptionsRecord)
113
- const suite = state.suites[suiteId]!
119
+ async getSuiteInfo(browserContext: PartialBrowserCommandContext, taskId: string) {
120
+ const projectRoot = getProjectRoot(browserContext)
121
+ const projectState = await state[projectRoot]!
122
+
123
+ const suiteId = getSuiteId(projectState, browserContext.testPath, visOptionsRecord)
124
+ const suite = projectState.suites[suiteId]!
114
125
  const task = (suite.tasks[taskId] = suite.tasks[taskId] ?? { count: 1 })
115
126
  return {
127
+ projectRoot,
116
128
  suiteId,
117
129
  taskId,
118
130
  baselineDir: suite.baselineDir,
@@ -126,21 +138,21 @@ export function createVisContext() {
126
138
  }
127
139
 
128
140
  async function setupState(
129
- suite: PartialBrowserCommandContext,
141
+ browserContext: PartialBrowserCommandContext,
130
142
  visOptions: Pick<VisOptions, 'snapshotRootDir' | 'platform' | 'subjectDataTestId'>,
131
143
  ) {
132
- const snapshotRootDir = resolveSnapshotRootDir(suite, visOptions)
133
- const projectPath = suite.project.config.root
144
+ const snapshotRootDir = resolveSnapshotRootDir(browserContext, visOptions)
145
+ const projectRoot = getProjectRoot(browserContext)
134
146
 
135
147
  const state = {
136
- projectPath,
137
- testTimeout: suite.project.config.testTimeout,
138
- hookTimeout: suite.project.config.hookTimeout,
148
+ projectRoot,
149
+ testTimeout: browserContext.project.config.testTimeout,
150
+ hookTimeout: browserContext.project.config.hookTimeout,
139
151
  snapshotRootDir,
140
152
  snapshotBaselineDir: join(snapshotRootDir, BASELINE_DIR),
141
153
  snapshotResultDir: join(snapshotRootDir, RESULT_DIR),
142
154
  snapshotDiffDir: join(snapshotRootDir, DIFF_DIR),
143
- snapshotRootPath: join(projectPath, snapshotRootDir),
155
+ snapshotRootPath: join(projectRoot, snapshotRootDir),
144
156
  subjectDataTestId: visOptions.subjectDataTestId,
145
157
  suites: {},
146
158
  }
@@ -148,7 +160,11 @@ async function setupState(
148
160
  return state
149
161
  }
150
162
 
151
- export function createSuite(state: VisState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>) {
163
+ export function createSuite(
164
+ state: VisProjectState,
165
+ testPath: string,
166
+ options: Pick<VisOptions, 'customizeSnapshotSubpath'>,
167
+ ) {
152
168
  const suiteId = getSuiteId(state, testPath, options)
153
169
  return {
154
170
  suiteId,
@@ -161,10 +177,18 @@ export function createSuite(state: VisState, testPath: string, options: Pick<Vis
161
177
  }
162
178
  }
163
179
 
164
- export function getSuiteId(state: VisState, testPath: string, options: Pick<VisOptions, 'customizeSnapshotSubpath'>) {
165
- return getSnapshotSubpath(relative(state.projectPath, testPath), options)
180
+ export function getSuiteId(
181
+ state: VisProjectState,
182
+ testPath: string,
183
+ options: Pick<VisOptions, 'customizeSnapshotSubpath'>,
184
+ ) {
185
+ return getSnapshotSubpath(relative(state.projectRoot, testPath), options)
166
186
  }
167
187
 
168
188
  function getVisOptions(visOptionsRecord: Record<string, VisOptions<any>>, context: PartialBrowserCommandContext) {
169
189
  return visOptionsRecord[getProjectName(context) ?? '__default']!
170
190
  }
191
+
192
+ function getProjectRoot(context: PartialBrowserCommandContext) {
193
+ return context.project.config.root
194
+ }
@@ -1,6 +1,9 @@
1
1
  export type VisState = {
2
- projectPath: string
3
- // platform: string
2
+ [projectPath: string]: Promise<VisProjectState>
3
+ }
4
+
5
+ export type VisProjectState = {
6
+ projectRoot: string
4
7
  testTimeout: number
5
8
  hookTimeout: number
6
9
  snapshotRootDir: string
@@ -24,6 +27,7 @@ export type VisState = {
24
27
  }
25
28
  >
26
29
  }
30
+
27
31
  export type PartialBrowserCommandContext = {
28
32
  project: {
29
33
  config: {
@@ -37,18 +41,18 @@ export type PartialBrowserCommandContext = {
37
41
  vite: {
38
42
  config: {
39
43
  test?: {
40
- name: string
44
+ name?: string | undefined
41
45
  }
42
46
  }
43
47
  }
44
48
  }
45
49
  provider: {
46
50
  name: string
47
- browserName: string
48
- options: {
49
- headless: boolean | undefined
50
- screenshotFailures: boolean | undefined
51
- screenshotDirectory: string | undefined
51
+ browserName?: string | undefined
52
+ options?: {
53
+ headless?: boolean | undefined
54
+ screenshotFailures?: boolean | undefined
55
+ screenshotDirectory?: string | undefined
52
56
  }
53
57
  }
54
58
  testPath: string
@@ -1,12 +0,0 @@
1
- import type { BrowserCommand } from 'vitest/node';
2
- export interface WriteImageSnapshotCommand {
3
- /**
4
- * Writes the image snapshot to the file system.
5
- * @param relativeFilePath The file path to write the image snapshot to.
6
- * It is relative to the project root.
7
- * @param imageBase64 The base64 encoded image.
8
- */
9
- writeImageSnapshot(relativeFilePath: string, imageBase64: string): Promise<void>;
10
- }
11
- export declare const writeImageSnapshot: BrowserCommand<[relativeFilePath: string, imageBase64: string]>;
12
- //# sourceMappingURL=write_image_snapshot.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/write_image_snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,MAAM,WAAW,yBAAyB;IACzC;;;;;OAKG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChF;AAED,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAS9F,CAAA"}
@@ -1,9 +0,0 @@
1
- import { mkdirp } from 'mkdirp';
2
- import { dirname, isAbsolute } from 'pathe';
3
- import { file } from "../file.js";
4
- import { assertIsRelativePath } from "./_assertions.js";
5
- export const writeImageSnapshot = async (_, relativeFilePath, imageBase64) => {
6
- assertIsRelativePath(relativeFilePath, 'relativeFilePath');
7
- await mkdirp(dirname(relativeFilePath));
8
- await file.writeFile(relativeFilePath, imageBase64, { encoding: 'base64' });
9
- };
@@ -1,26 +0,0 @@
1
- import { mkdirp } from 'mkdirp'
2
- import { dirname, isAbsolute } from 'pathe'
3
- import type { BrowserCommand } from 'vitest/node'
4
- import { file } from '../file.ts'
5
- import { assertIsRelativePath } from './_assertions.ts'
6
-
7
- export interface WriteImageSnapshotCommand {
8
- /**
9
- * Writes the image snapshot to the file system.
10
- * @param relativeFilePath The file path to write the image snapshot to.
11
- * It is relative to the project root.
12
- * @param imageBase64 The base64 encoded image.
13
- */
14
- writeImageSnapshot(relativeFilePath: string, imageBase64: string): Promise<void>
15
- }
16
-
17
- export const writeImageSnapshot: BrowserCommand<[relativeFilePath: string, imageBase64: string]> = async (
18
- _,
19
- relativeFilePath,
20
- imageBase64,
21
- ) => {
22
- assertIsRelativePath(relativeFilePath, 'relativeFilePath')
23
-
24
- await mkdirp(dirname(relativeFilePath))
25
- await file.writeFile(relativeFilePath, imageBase64, { encoding: 'base64' })
26
- }