vitest-plugin-vis 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/esm/client/ctx.d.ts +6 -0
  2. package/esm/client/ctx.d.ts.map +1 -0
  3. package/esm/client/ctx.js +7 -0
  4. package/esm/client/expect/expectation_result.d.ts +3 -0
  5. package/esm/client/expect/expectation_result.d.ts.map +1 -0
  6. package/esm/client/expect/expectation_result.js +5 -0
  7. package/esm/client/expect/extend.d.ts +8 -0
  8. package/esm/client/expect/extend.d.ts.map +1 -0
  9. package/esm/client/expect/extend.js +3 -0
  10. package/esm/client/expect/to_match_image_snapshot.d.ts +9 -0
  11. package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -0
  12. package/esm/client/expect/to_match_image_snapshot.js +32 -0
  13. package/esm/client/expect/to_match_image_snapshot.logic.d.ts +2 -0
  14. package/esm/client/expect/to_match_image_snapshot.logic.d.ts.map +1 -0
  15. package/esm/client/expect/to_match_image_snapshot.logic.js +11 -0
  16. package/esm/client/expect/to_match_image_snapshot.types.d.ts +7 -0
  17. package/esm/client/expect/to_match_image_snapshot.types.d.ts.map +1 -0
  18. package/esm/client/expect/to_match_image_snapshot.types.js +1 -0
  19. package/esm/client/page/extend.d.ts +6 -0
  20. package/esm/client/page/extend.d.ts.map +1 -0
  21. package/esm/client/page/extend.js +3 -0
  22. package/esm/client/page/has_image_snapshot.d.ts +10 -0
  23. package/esm/client/page/has_image_snapshot.d.ts.map +1 -0
  24. package/esm/client/page/has_image_snapshot.js +23 -0
  25. package/esm/client/selector.d.ts +9 -0
  26. package/esm/client/selector.d.ts.map +1 -0
  27. package/esm/client/selector.js +104 -0
  28. package/esm/client/should_take_snapshot.d.ts +10 -0
  29. package/esm/client/should_take_snapshot.d.ts.map +1 -0
  30. package/esm/client/should_take_snapshot.js +13 -0
  31. package/esm/client/snapshot_options.d.ts +34 -0
  32. package/esm/client/snapshot_options.d.ts.map +1 -0
  33. package/esm/client/snapshot_options.internal.d.ts +3 -0
  34. package/esm/client/snapshot_options.internal.d.ts.map +1 -0
  35. package/esm/client/snapshot_options.internal.js +20 -0
  36. package/esm/client/snapshot_options.js +16 -0
  37. package/esm/client/task_id.d.ts +7 -0
  38. package/esm/client/task_id.d.ts.map +1 -0
  39. package/esm/client/task_id.js +10 -0
  40. package/esm/client.d.ts +8 -0
  41. package/esm/client.d.ts.map +1 -0
  42. package/esm/client.js +5 -0
  43. package/esm/commands.d.ts +5 -0
  44. package/esm/commands.d.ts.map +1 -0
  45. package/esm/commands.js +4 -0
  46. package/esm/config/types.d.ts +35 -0
  47. package/esm/config/types.d.ts.map +1 -0
  48. package/esm/config/types.js +1 -0
  49. package/esm/config/vis.d.ts +25 -0
  50. package/esm/config/vis.d.ts.map +1 -0
  51. package/esm/config/vis.js +27 -0
  52. package/esm/config.d.ts +4 -0
  53. package/esm/config.d.ts.map +1 -0
  54. package/esm/config.js +2 -0
  55. package/esm/index.d.ts +2 -0
  56. package/esm/index.d.ts.map +1 -0
  57. package/esm/index.js +2 -0
  58. package/esm/presets/auto.d.ts +2 -0
  59. package/esm/presets/auto.d.ts.map +1 -0
  60. package/esm/presets/auto.js +3 -0
  61. package/esm/presets/manual.d.ts +2 -0
  62. package/esm/presets/manual.d.ts.map +1 -0
  63. package/esm/presets/manual.js +3 -0
  64. package/esm/server/browser_provider/browser_api.d.ts +3 -0
  65. package/esm/server/browser_provider/browser_api.d.ts.map +1 -0
  66. package/esm/server/browser_provider/browser_api.js +11 -0
  67. package/esm/server/browser_provider/playwright.d.ts +4 -0
  68. package/esm/server/browser_provider/playwright.d.ts.map +1 -0
  69. package/esm/server/browser_provider/playwright.js +13 -0
  70. package/esm/server/browser_provider/types.d.ts +6 -0
  71. package/esm/server/browser_provider/types.d.ts.map +1 -0
  72. package/esm/server/browser_provider/types.js +1 -0
  73. package/esm/server/browser_provider/webdriverio.d.ts +4 -0
  74. package/esm/server/browser_provider/webdriverio.d.ts.map +1 -0
  75. package/esm/server/browser_provider/webdriverio.js +10 -0
  76. package/esm/server/commands/extend.d.ts +15 -0
  77. package/esm/server/commands/extend.d.ts.map +1 -0
  78. package/esm/server/commands/extend.js +10 -0
  79. package/esm/server/commands/has_image_snapshot.d.ts +6 -0
  80. package/esm/server/commands/has_image_snapshot.d.ts.map +1 -0
  81. package/esm/server/commands/has_image_snapshot.js +7 -0
  82. package/esm/server/commands/image_snapshot_next_index.d.ts +9 -0
  83. package/esm/server/commands/image_snapshot_next_index.d.ts.map +1 -0
  84. package/esm/server/commands/image_snapshot_next_index.js +7 -0
  85. package/esm/server/commands/is_ci.d.ts +2 -0
  86. package/esm/server/commands/is_ci.d.ts.map +1 -0
  87. package/esm/server/commands/is_ci.js +6 -0
  88. package/esm/server/commands/match_image_snapshot.d.ts +17 -0
  89. package/esm/server/commands/match_image_snapshot.d.ts.map +1 -0
  90. package/esm/server/commands/match_image_snapshot.js +88 -0
  91. package/esm/server/commands/setup_vis_suite.d.ts +13 -0
  92. package/esm/server/commands/setup_vis_suite.d.ts.map +1 -0
  93. package/esm/server/commands/setup_vis_suite.js +4 -0
  94. package/esm/server/compare_image.d.ts +8 -0
  95. package/esm/server/compare_image.d.ts.map +1 -0
  96. package/esm/server/compare_image.js +16 -0
  97. package/esm/server/file.d.ts +6 -0
  98. package/esm/server/file.d.ts.map +1 -0
  99. package/esm/server/file.js +14 -0
  100. package/esm/server/snapshot_path.d.ts +4 -0
  101. package/esm/server/snapshot_path.d.ts.map +1 -0
  102. package/esm/server/snapshot_path.js +9 -0
  103. package/esm/server/vis_context.ctx.d.ts +29 -0
  104. package/esm/server/vis_context.ctx.d.ts.map +1 -0
  105. package/esm/server/vis_context.ctx.js +11 -0
  106. package/esm/server/vis_context.d.ts +33 -0
  107. package/esm/server/vis_context.d.ts.map +1 -0
  108. package/esm/server/vis_context.js +2 -0
  109. package/esm/server/vis_context.logic.d.ts +63 -0
  110. package/esm/server/vis_context.logic.d.ts.map +1 -0
  111. package/esm/server/vis_context.logic.js +116 -0
  112. package/esm/server/vis_context.types.d.ts +20 -0
  113. package/esm/server/vis_context.types.d.ts.map +1 -0
  114. package/esm/server/vis_context.types.js +1 -0
  115. package/esm/setup/create_vis.d.ts +39 -0
  116. package/esm/setup/create_vis.d.ts.map +1 -0
  117. package/esm/setup/create_vis.js +96 -0
  118. package/esm/setup/vis.d.ts +18 -0
  119. package/esm/setup/vis.d.ts.map +1 -0
  120. package/esm/setup/vis.js +6 -0
  121. package/esm/setup.d.ts +5 -0
  122. package/esm/setup.d.ts.map +1 -0
  123. package/esm/setup.js +7 -0
  124. package/esm/shared/base64.d.ts +2 -0
  125. package/esm/shared/base64.d.ts.map +1 -0
  126. package/esm/shared/base64.js +3 -0
  127. package/esm/shared/constants.d.ts +5 -0
  128. package/esm/shared/constants.d.ts.map +1 -0
  129. package/esm/shared/constants.js +4 -0
  130. package/esm/shared/convert_threshold_unit.d.ts +6 -0
  131. package/esm/shared/convert_threshold_unit.d.ts.map +1 -0
  132. package/esm/shared/convert_threshold_unit.js +10 -0
  133. package/esm/shared/get_max_size.d.ts +11 -0
  134. package/esm/shared/get_max_size.d.ts.map +1 -0
  135. package/esm/shared/get_max_size.js +5 -0
  136. package/esm/shared/is_same_size.d.ts +8 -0
  137. package/esm/shared/is_same_size.d.ts.map +1 -0
  138. package/esm/shared/is_same_size.js +3 -0
  139. package/esm/shared/trim_common_folder.d.ts +6 -0
  140. package/esm/shared/trim_common_folder.d.ts.map +1 -0
  141. package/esm/shared/trim_common_folder.js +10 -0
  142. package/esm/shared/types.d.ts +37 -0
  143. package/esm/shared/types.d.ts.map +1 -0
  144. package/esm/shared/types.js +1 -0
  145. package/esm/testing/constants.d.ts +9 -0
  146. package/esm/testing/constants.d.ts.map +1 -0
  147. package/esm/testing/constants.js +1933 -0
  148. package/esm/testing.d.ts +2 -0
  149. package/esm/testing.d.ts.map +1 -0
  150. package/esm/testing.js +1 -0
  151. package/package.json +115 -0
  152. package/readme.md +264 -0
  153. package/src/client/ctx.ts +8 -0
  154. package/src/client/expect/expectation_result.ts +7 -0
  155. package/src/client/expect/extend.ts +12 -0
  156. package/src/client/expect/to_match_image_snapshot.logic.ts +11 -0
  157. package/src/client/expect/to_match_image_snapshot.ts +43 -0
  158. package/src/client/expect/to_match_image_snapshot.types.ts +14 -0
  159. package/src/client/page/extend.ts +8 -0
  160. package/src/client/page/has_image_snapshot.ts +33 -0
  161. package/src/client/selector.ts +118 -0
  162. package/src/client/should_take_snapshot.ts +15 -0
  163. package/src/client/snapshot_options.internal.ts +22 -0
  164. package/src/client/snapshot_options.ts +53 -0
  165. package/src/client/task_id.ts +16 -0
  166. package/src/client.ts +7 -0
  167. package/src/commands.ts +4 -0
  168. package/src/config/readme.md +4 -0
  169. package/src/config/types.ts +35 -0
  170. package/src/config/vis.ts +30 -0
  171. package/src/config.ts +3 -0
  172. package/src/index.ts +2 -0
  173. package/src/presets/auto.ts +4 -0
  174. package/src/presets/manual.ts +4 -0
  175. package/src/server/browser_provider/browser_api.ts +13 -0
  176. package/src/server/browser_provider/playwright.ts +16 -0
  177. package/src/server/browser_provider/types.ts +11 -0
  178. package/src/server/browser_provider/webdriverio.ts +13 -0
  179. package/src/server/commands/extend.ts +19 -0
  180. package/src/server/commands/has_image_snapshot.ts +18 -0
  181. package/src/server/commands/image_snapshot_next_index.ts +17 -0
  182. package/src/server/commands/is_ci.ts +7 -0
  183. package/src/server/commands/match_image_snapshot.ts +139 -0
  184. package/src/server/commands/setup_vis_suite.ts +17 -0
  185. package/src/server/compare_image.ts +34 -0
  186. package/src/server/file.ts +15 -0
  187. package/src/server/readme.md +5 -0
  188. package/src/server/snapshot_path.ts +12 -0
  189. package/src/server/vis_context.ctx.ts +12 -0
  190. package/src/server/vis_context.logic.ts +141 -0
  191. package/src/server/vis_context.ts +3 -0
  192. package/src/server/vis_context.types.ts +25 -0
  193. package/src/setup/create_vis.ts +98 -0
  194. package/src/setup/vis.ts +7 -0
  195. package/src/setup.ts +9 -0
  196. package/src/shared/base64.ts +3 -0
  197. package/src/shared/constants.ts +4 -0
  198. package/src/shared/convert_threshold_unit.ts +13 -0
  199. package/src/shared/get_max_size.ts +5 -0
  200. package/src/shared/is_same_size.ts +3 -0
  201. package/src/shared/trim_common_folder.ts +10 -0
  202. package/src/shared/types.ts +39 -0
  203. package/src/testing/constants.ts +1936 -0
  204. package/src/testing.ts +1 -0
@@ -0,0 +1,3 @@
1
+ import 'vitest-browser-react';
2
+ import { vis } from "../setup/vis.js";
3
+ vis.presets.auto();
@@ -0,0 +1,2 @@
1
+ import 'vitest-browser-react';
2
+ //# sourceMappingURL=manual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../src/presets/manual.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAA"}
@@ -0,0 +1,3 @@
1
+ import 'vitest-browser-react';
2
+ import { vis } from "../setup/vis.js";
3
+ vis.presets.manual();
@@ -0,0 +1,3 @@
1
+ import type { BrowserCommandContext } from 'vitest/node';
2
+ export declare function browserApi(context: BrowserCommandContext): import("./types.ts").BrowserApi;
3
+ //# sourceMappingURL=browser_api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser_api.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/browser_api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAIxD,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,mCAQxD"}
@@ -0,0 +1,11 @@
1
+ import { playwright } from "./playwright.js";
2
+ import { webdriverio } from "./webdriverio.js";
3
+ export function browserApi(context) {
4
+ if (context.provider.name === 'playwright') {
5
+ return playwright(context);
6
+ }
7
+ if (context.provider.name === 'webdriverio') {
8
+ return webdriverio(context);
9
+ }
10
+ throw new Error(`Unsupported provider: ${context.provider.name}`);
11
+ }
@@ -0,0 +1,4 @@
1
+ import type { BrowserCommandContext } from 'vitest/node';
2
+ import type { BrowserApi } from './types.ts';
3
+ export declare function playwright(context: BrowserCommandContext): BrowserApi;
4
+ //# sourceMappingURL=playwright.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/playwright.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAYrE"}
@@ -0,0 +1,13 @@
1
+ export function playwright(context) {
2
+ return {
3
+ async takeScreenshot(filePath, selector, options) {
4
+ // The `Locator` type from `vitest` has less props than the `Locator` in `playwright`
5
+ const subject = context.iframe.locator(selector ?? 'body');
6
+ const buffer = await subject.screenshot({
7
+ timeout: options?.timeout,
8
+ path: filePath,
9
+ });
10
+ return buffer.toString('base64');
11
+ },
12
+ };
13
+ }
@@ -0,0 +1,6 @@
1
+ export interface BrowserApi {
2
+ takeScreenshot(filePath: string, selector: string, options: {
3
+ timeout?: number | undefined;
4
+ } | undefined): Promise<string>;
5
+ }
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,cAAc,CACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EACJ;QACA,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,GACD,SAAS,GACV,OAAO,CAAC,MAAM,CAAC,CAAA;CAClB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { BrowserCommandContext } from 'vitest/node';
2
+ import type { BrowserApi } from './types.ts';
3
+ export declare function webdriverio(context: BrowserCommandContext): BrowserApi;
4
+ //# sourceMappingURL=webdriverio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdriverio.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/webdriverio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAStE"}
@@ -0,0 +1,10 @@
1
+ export function webdriverio(context) {
2
+ const page = context.provider.browser;
3
+ return {
4
+ async takeScreenshot(filePath, selector) {
5
+ const element = await page.$(`${selector ?? 'body'}`);
6
+ const buffer = await element.saveScreenshot(filePath);
7
+ return buffer.toString('base64');
8
+ },
9
+ };
10
+ }
@@ -0,0 +1,15 @@
1
+ import { type HasImageSnapshotCommand } from './has_image_snapshot.ts';
2
+ import { type ImageSnapshotNextIndexCommand } from './image_snapshot_next_index.ts';
3
+ import { type MatchImageSnapshotCommand } from './match_image_snapshot.ts';
4
+ import { type SetupVisSuiteCommand } from './setup_vis_suite.ts';
5
+ declare module '@vitest/browser/context' {
6
+ interface BrowserCommands extends SetupVisSuiteCommand, ImageSnapshotNextIndexCommand, HasImageSnapshotCommand, MatchImageSnapshotCommand {
7
+ }
8
+ }
9
+ export declare const commands: {
10
+ setupVisSuite: import("vitest/node").BrowserCommand<[]>;
11
+ imageSnapshotNextIndex: import("vitest/node").BrowserCommand<[taskId: string]>;
12
+ hasImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, snapshotId?: string | undefined]>;
13
+ matchImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, subject: string, options?: import("./match_image_snapshot.ts").MatchImageSnapshotOptions | undefined]>;
14
+ };
15
+ //# sourceMappingURL=extend.d.ts.map
@@ -0,0 +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,EAAE,KAAK,oBAAoB,EAAiB,MAAM,sBAAsB,CAAA;AAE/E,OAAO,QAAQ,yBAAyB,CAAC;IACxC,UAAU,eACT,SAAQ,oBAAoB,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB;KAAG;CAC9B;AAED,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { hasImageSnapshot } from "./has_image_snapshot.js";
2
+ import { imageSnapshotNextIndex } from "./image_snapshot_next_index.js";
3
+ import { matchImageSnapshot } from "./match_image_snapshot.js";
4
+ import { setupVisSuite } from "./setup_vis_suite.js";
5
+ export const commands = {
6
+ setupVisSuite,
7
+ imageSnapshotNextIndex,
8
+ hasImageSnapshot,
9
+ matchImageSnapshot,
10
+ };
@@ -0,0 +1,6 @@
1
+ import type { BrowserCommand } from 'vitest/node';
2
+ export interface HasImageSnapshotCommand {
3
+ hasImageSnapshot(taskId: string, snapshotId?: string | undefined): Promise<boolean>;
4
+ }
5
+ export declare const hasImageSnapshot: BrowserCommand<[taskId: string, snapshotId?: string | undefined]>;
6
+ //# sourceMappingURL=has_image_snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/has_image_snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,uBAAuB;IACvC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnF;AAED,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,CAU9F,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { visContext } from "../vis_context.js";
2
+ export const hasImageSnapshot = async (context, taskId, snapshotId) => {
3
+ if (!context.testPath) {
4
+ throw new Error('Cannot take snapshot without testPath');
5
+ }
6
+ return visContext.hasImageSnapshot(context.testPath, taskId, snapshotId);
7
+ };
@@ -0,0 +1,9 @@
1
+ import type { BrowserCommand } from 'vitest/node';
2
+ export interface ImageSnapshotNextIndexCommand {
3
+ /**
4
+ * Get the index of the snapshot image to be created.
5
+ */
6
+ imageSnapshotNextIndex(taskId: string): Promise<number>;
7
+ }
8
+ export declare const imageSnapshotNextIndex: BrowserCommand<[taskId: string]>;
9
+ //# sourceMappingURL=image_snapshot_next_index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image_snapshot_next_index.d.ts","sourceRoot":"","sources":["../../../src/server/commands/image_snapshot_next_index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,6BAA6B;IAC7C;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAMnE,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { visContext } from "../vis_context.js";
2
+ export const imageSnapshotNextIndex = async (context, taskId) => {
3
+ if (!context.testPath) {
4
+ throw new Error('Cannot take snapshot without testPath');
5
+ }
6
+ return visContext.getTaskCount(context.testPath, taskId);
7
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=is_ci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is_ci.d.ts","sourceRoot":"","sources":["../../../src/server/commands/is_ci.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ // import ci from 'is-ci'
2
+ export {};
3
+ // export interface IsCICommand {
4
+ // isCI: () => Promise<boolean>
5
+ // }
6
+ // export const isCI = async () => ci
@@ -0,0 +1,17 @@
1
+ import type { BrowserCommand } from 'vitest/node';
2
+ import type { ImageSnapshotCompareOptions, ImageSnapshotIdOptions, ImageSnapshotTimeoutOptions } from '../../shared/types.ts';
3
+ export interface MatchImageSnapshotCommand {
4
+ matchImageSnapshot: (taskId: string | undefined, subject: string, options?: MatchImageSnapshotOptions | undefined) => Promise<void>;
5
+ }
6
+ export interface MatchImageSnapshotOptions extends ImageSnapshotTimeoutOptions, ImageSnapshotIdOptions, ImageSnapshotCompareOptions {
7
+ /**
8
+ * The snapshot file id calculated on the client side.
9
+ */
10
+ snapshotFileId?: string | undefined;
11
+ }
12
+ export declare const matchImageSnapshot: BrowserCommand<[
13
+ taskId: string,
14
+ subject: string,
15
+ options?: MatchImageSnapshotOptions | undefined
16
+ ]>;
17
+ //# sourceMappingURL=match_image_snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/match_image_snapshot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAA;AAIxE,OAAO,KAAK,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAM9B,MAAM,WAAW,yBAAyB;IACzC,kBAAkB,EAAE,CACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,yBAChB,SAAQ,2BAA2B,EAClC,sBAAsB,EACtB,2BAA2B;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAC9C;IAAC,MAAM,EAAE,MAAM;IAAE,OAAO,EAAE,MAAM;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,CA2DlF,CAAA"}
@@ -0,0 +1,88 @@
1
+ import dedent from 'dedent';
2
+ import ci from 'is-ci';
3
+ import { mkdirp } from 'mkdirp';
4
+ import { dirname, resolve } from 'pathe';
5
+ import { PNG } from 'pngjs';
6
+ import { isBase64String } from "../../shared/base64.js";
7
+ import { getMaxSize } from "../../shared/get_max_size.js";
8
+ import { isSameSize } from "../../shared/is_same_size.js";
9
+ import { browserApi } from "../browser_provider/browser_api.js";
10
+ import { compareImage } from "../compare_image.js";
11
+ import { file } from "../file.js";
12
+ import { visContext } from "../vis_context.js";
13
+ export const matchImageSnapshot = async (context, taskId, subject, options) => {
14
+ if (!context.testPath) {
15
+ throw new Error('Cannot match snapshot without testPath');
16
+ }
17
+ // vitest:browser passes in `null` when not defined
18
+ if (!options)
19
+ options = {};
20
+ options.timeout = options.timeout ?? (ci ? 30000 : 5000);
21
+ const info = visContext.getSnapshotInfo(context.testPath, taskId, options);
22
+ const baselineBase64 = await file.tryReadFileBase64(info.baselinePath);
23
+ if (!baselineBase64) {
24
+ await takeSnapshot(context, subject, info.baselinePath, options);
25
+ return;
26
+ }
27
+ const resultBase64 = await takeSnapshot(context, subject, info.resultPath, options);
28
+ const baselineImage = PNG.sync.read(Buffer.from(baselineBase64, 'base64'));
29
+ const resultImage = PNG.sync.read(Buffer.from(resultBase64, 'base64'));
30
+ const [baselineAlignedImage, resultAlignedImage] = isSameSize(baselineImage, resultImage)
31
+ ? [baselineImage, resultImage]
32
+ : alignImageSizes(baselineImage, resultImage);
33
+ const { pass, diffAmount, diffImage } = compareImage(baselineAlignedImage, resultAlignedImage, options);
34
+ if (pass) {
35
+ if (sizeNotChanged(baselineImage, baselineAlignedImage)) {
36
+ return;
37
+ }
38
+ throw new Error(dedent `Snapshot \`${taskId}\` mismatched
39
+
40
+ The image size changed form ${baselineImage.width}x${baselineImage.height} to ${resultImage.width}x${resultImage.height}
41
+
42
+ Expected: ${resolve(context.project.runner.root, info.baselinePath)}
43
+ Actual: ${resolve(context.project.runner.root, info.resultPath)}`);
44
+ }
45
+ const diffBase64 = PNG.sync.write(diffImage).toString('base64');
46
+ await writeSnapshot(diffBase64, info.diffPath);
47
+ throw new Error(dedent `Snapshot \`${taskId}\` mismatched
48
+
49
+ ${options?.failureThreshold
50
+ ? options?.failureThresholdType === 'percent'
51
+ ? `Expected image to match within ${options.failureThreshold}% but was differ by ${diffAmount}%.`
52
+ : `Expected image to match within ${options.failureThreshold} pixels but was differ by ${diffAmount} pixels.`
53
+ : `Expected image to match but was differ by ${options?.failureThresholdType === 'percent' ? `${diffAmount}%` : `${diffAmount} pixels`}.`}
54
+
55
+ Options: ${JSON.stringify(options)}
56
+
57
+ Expected: ${resolve(context.project.runner.root, info.baselinePath)}
58
+ Actual: ${resolve(context.project.runner.root, info.resultPath)}
59
+ Difference: ${resolve(context.project.runner.root, info.diffPath)}`);
60
+ };
61
+ async function takeSnapshot(context, subject, filePath, options) {
62
+ if (isBase64String(subject)) {
63
+ return writeSnapshot(subject, filePath);
64
+ }
65
+ await mkdirp(dirname(filePath));
66
+ const browser = browserApi(context);
67
+ return browser.takeScreenshot(filePath, subject, {
68
+ timeout: options?.timeout,
69
+ });
70
+ }
71
+ async function writeSnapshot(subject, filePath) {
72
+ await mkdirp(dirname(filePath));
73
+ await file.writeFileBase64(filePath, subject);
74
+ return subject;
75
+ }
76
+ function alignImageSizes(baseline, result) {
77
+ const size = getMaxSize(baseline, result);
78
+ const baselineAligned = new PNG(size);
79
+ const resultAligned = new PNG(size);
80
+ baselineAligned.data.fill(0);
81
+ resultAligned.data.fill(0);
82
+ PNG.bitblt(baseline, baselineAligned, 0, 0, baseline.width, baseline.height);
83
+ PNG.bitblt(result, resultAligned, 0, 0, result.width, result.height);
84
+ return [baselineAligned, resultAligned];
85
+ }
86
+ function sizeNotChanged(baselineImage, baselineAlignedImage) {
87
+ return baselineImage === baselineAlignedImage;
88
+ }
@@ -0,0 +1,13 @@
1
+ import type { BrowserCommand } from 'vitest/node';
2
+ export interface SetupVisSuiteCommand {
3
+ /**
4
+ * Sets up the visual testing suite by cleaning up previous snapshot and diff output directories.
5
+ * When this command is run for the first time,
6
+ * it will remove the results and diffs directory of all suites.
7
+ *
8
+ * In subsequent runs, it will only remove the results and diffs directory of the current suite.
9
+ */
10
+ setupVisSuite: () => Promise<void>;
11
+ }
12
+ export declare const setupVisSuite: BrowserCommand<[]>;
13
+ //# sourceMappingURL=setup_vis_suite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup_vis_suite.d.ts","sourceRoot":"","sources":["../../../src/server/commands/setup_vis_suite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,oBAAoB;IACpC;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,EAAE,CAE5C,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { visContext } from "../vis_context.js";
2
+ export const setupVisSuite = async (context) => {
3
+ await visContext.setupSuite(context);
4
+ };
@@ -0,0 +1,8 @@
1
+ import { PNG } from 'pngjs';
2
+ import type { ImageSnapshotCompareOptions } from '../shared/types.ts';
3
+ export declare function compareImage(baselineImage: PNG, resultImage: PNG, { failureThreshold, failureThresholdType, diffOptions }?: ImageSnapshotCompareOptions): {
4
+ pass: boolean;
5
+ diffAmount: number;
6
+ diffImage: PNG;
7
+ };
8
+ //# sourceMappingURL=compare_image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare_image.d.ts","sourceRoot":"","sources":["../../src/server/compare_image.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAE3B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAErE,wBAAgB,YAAY,CAC3B,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,GAAG,EAChB,EAAE,gBAAoB,EAAE,oBAA8B,EAAE,WAAW,EAAE,GAAE,2BAAgC;;;;EAyBvG"}
@@ -0,0 +1,16 @@
1
+ import pixelmatch from 'pixelmatch';
2
+ import { PNG } from 'pngjs';
3
+ import { convertThresholdUnit } from "../shared/convert_threshold_unit.js";
4
+ export function compareImage(baselineImage, resultImage, { failureThreshold = 0, failureThresholdType = 'pixel', diffOptions } = {}) {
5
+ const diffImage = new PNG({
6
+ width: baselineImage.width,
7
+ height: baselineImage.height,
8
+ });
9
+ const pixelDiff = pixelmatch(resultImage.data, baselineImage.data, diffImage.data, baselineImage.width, baselineImage.height, diffOptions);
10
+ const diffAmount = convertThresholdUnit({ failureThresholdType, width: baselineImage.width, height: baselineImage.height }, pixelDiff);
11
+ return {
12
+ pass: diffAmount <= failureThreshold,
13
+ diffAmount,
14
+ diffImage,
15
+ };
16
+ }
@@ -0,0 +1,6 @@
1
+ export declare const file: {
2
+ tryReadFileBase64(filePath: string): Promise<string | undefined>;
3
+ writeFileBase64(filePath: string, data: string): Promise<void>;
4
+ existFile(filePath: string): Promise<boolean>;
5
+ };
6
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI;gCACkB,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;8BAG5C,MAAM,QAAQ,MAAM;wBAG1B,MAAM;CAK1B,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { readFile, stat, writeFile } from 'node:fs/promises';
2
+ export const file = {
3
+ async tryReadFileBase64(filePath) {
4
+ return readFile(filePath, { encoding: 'base64' }).catch(() => undefined);
5
+ },
6
+ writeFileBase64(filePath, data) {
7
+ return writeFile(filePath, data, { encoding: 'base64' });
8
+ },
9
+ existFile(filePath) {
10
+ return stat(filePath)
11
+ .then((s) => s.isFile())
12
+ .catch(() => false);
13
+ },
14
+ };
@@ -0,0 +1,4 @@
1
+ import type { VisOptions } from '../config/types.ts';
2
+ export declare function resolveSnapshotRootDir(options: VisOptions | undefined): string;
3
+ export declare function getSnapshotSubpath(suiteName: string, options: VisOptions): string;
4
+ //# sourceMappingURL=snapshot_path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot_path.d.ts","sourceRoot":"","sources":["../../src/server/snapshot_path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAIpD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,UAErE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,UAGxE"}
@@ -0,0 +1,9 @@
1
+ import { SNAPSHOT_ROOT_DIR } from "../shared/constants.js";
2
+ import { trimCommonFolder } from "../shared/trim_common_folder.js";
3
+ export function resolveSnapshotRootDir(options) {
4
+ return options?.snapshotRootDir ?? SNAPSHOT_ROOT_DIR;
5
+ }
6
+ export function getSnapshotSubpath(suiteName, options) {
7
+ const customizeSnapshotSubpath = options.customizeSnapshotSubpath ?? trimCommonFolder;
8
+ return customizeSnapshotSubpath(suiteName);
9
+ }
@@ -0,0 +1,29 @@
1
+ export declare const ctx: {
2
+ rimraf: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
3
+ rimraf: (path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>;
4
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
5
+ rimrafSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
6
+ manual: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
7
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
8
+ };
9
+ manualSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
10
+ native: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
11
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
12
+ };
13
+ nativeSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
14
+ posix: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
15
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
16
+ };
17
+ posixSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
18
+ windows: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
19
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
20
+ };
21
+ windowsSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
22
+ moveRemove: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
23
+ sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
24
+ };
25
+ moveRemoveSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
26
+ };
27
+ getSnapshotPlatform(): NodeJS.Platform | "local";
28
+ };
29
+ //# sourceMappingURL=vis_context.ctx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_context.ctx.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ctx.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,GAAG;;6CAQ2qD,CAAC;2CAAkF,CAAC;iDAA8E,CAAC;8CAA2E,CAAC;+CAA0F,CAAC;;iDAAqF,CAAC;8CAA2E,CAAC;+CAA0F,CAAC;;iDAAqF,CAAC;6CAA0E,CAAC;+CAA0F,CAAC;;gDAAoF,CAAC;+CAA4E,CAAC;+CAA0F,CAAC;;kDAAsF,CAAC;kDAA+E,CAAC;+CAA0F,CAAC;;qDAAyF,CAAC;;;CAFtlG,CAAA"}
@@ -0,0 +1,11 @@
1
+ /* v8 ignore start */
2
+ import ci from 'is-ci';
3
+ import { rimraf } from 'rimraf';
4
+ export const ctx = {
5
+ rimraf,
6
+ getSnapshotPlatform() {
7
+ /* v8 ignore next */
8
+ return ci ? process.platform : 'local';
9
+ },
10
+ };
11
+ /* v8 ignore end */
@@ -0,0 +1,33 @@
1
+ export declare const visContext: {
2
+ setOptions(options?: import("../config.ts").VisOptions): void;
3
+ __test__getOptions(): import("../config.ts").VisOptions;
4
+ __test__reset(): void;
5
+ __test__getState(): import("./vis_context.types.ts").VisState;
6
+ setupSuite(context: import("./vis_context.logic.ts").PartialBrowserCommandContext): Promise<void>;
7
+ getSnapshotInfo(testPath: string, name: string, options?: {
8
+ snapshotFileId?: string | undefined;
9
+ }): {
10
+ baselinePath: string;
11
+ resultPath: string;
12
+ diffPath: string;
13
+ };
14
+ getTaskCount(testPath: string, taskId: string): number;
15
+ hasImageSnapshot(testPath: string, taskId: string, snapshotFileId: string | undefined): Promise<boolean>;
16
+ getSnapshotFilename(info: {
17
+ taskId: string;
18
+ task: {
19
+ count: number;
20
+ };
21
+ }, snapshotFileId: string | undefined): string;
22
+ getSuiteInfo(testPath: string, taskId: string): {
23
+ suiteId: string;
24
+ taskId: string;
25
+ baselineDir: string;
26
+ resultDir: string;
27
+ diffDir: string;
28
+ task: {
29
+ count: number;
30
+ };
31
+ };
32
+ };
33
+ //# sourceMappingURL=vis_context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBAC4iD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CADxhD,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { createVisContext } from "./vis_context.logic.js";
2
+ export const visContext = createVisContext();
@@ -0,0 +1,63 @@
1
+ import type { VisOptions } from '../config/types.ts';
2
+ import type { VisState } from './vis_context.types.ts';
3
+ export type PartialBrowserCommandContext = {
4
+ project: {
5
+ config: {
6
+ root: string;
7
+ snapshotOptions: {
8
+ updateSnapshot: 'all' | 'new' | 'none';
9
+ };
10
+ testTimeout: number;
11
+ hookTimeout: number;
12
+ };
13
+ };
14
+ testPath: string | undefined;
15
+ };
16
+ export declare function createVisContext(): {
17
+ setOptions(options?: VisOptions): void;
18
+ __test__getOptions(): VisOptions;
19
+ __test__reset(): void;
20
+ __test__getState(): VisState;
21
+ /**
22
+ * Setup suite is called on each test file's beforeAll hook.
23
+ * Test files include vitest test files and storybook story files.
24
+ * It needs to make sure there is no race condition between the test files.
25
+ */
26
+ setupSuite(context: PartialBrowserCommandContext): Promise<void>;
27
+ getSnapshotInfo(testPath: string, name: string, options?: {
28
+ snapshotFileId?: string | undefined;
29
+ }): {
30
+ baselinePath: string;
31
+ resultPath: string;
32
+ diffPath: string;
33
+ };
34
+ getTaskCount(testPath: string, taskId: string): number;
35
+ hasImageSnapshot(testPath: string, taskId: string, snapshotFileId: string | undefined): Promise<boolean>;
36
+ getSnapshotFilename(info: {
37
+ taskId: string;
38
+ task: {
39
+ count: number;
40
+ };
41
+ }, snapshotFileId: string | undefined): string;
42
+ getSuiteInfo(testPath: string, taskId: string): {
43
+ suiteId: string;
44
+ taskId: string;
45
+ baselineDir: string;
46
+ resultDir: string;
47
+ diffDir: string;
48
+ task: {
49
+ count: number;
50
+ };
51
+ };
52
+ };
53
+ export declare function getSuiteId(state: VisState, testPath: string, options: VisOptions): string;
54
+ export declare function createSuite(state: VisState, testPath: string, options: VisOptions): {
55
+ suiteId: string;
56
+ suite: {
57
+ baselineDir: string;
58
+ resultDir: string;
59
+ diffDir: string;
60
+ tasks: {};
61
+ };
62
+ };
63
+ //# sourceMappingURL=vis_context.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_context.logic.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.logic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAKpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEtD,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;KACD,CAAA;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B,CAAA;AAED,wBAAgB,gBAAgB;yBAMV,UAAU;;;;IAY9B;;;;OAIG;wBACuB,4BAA4B;8BAY5B,MAAM,QAAQ,MAAM,YAAY;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;2BAiB1E,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;2BAMlF,MAAM,UAAU,MAAM;;;;;;;;;;EAe9C;AAuBD,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,UAEhF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;;;;;;;;EAWjF"}