vitest-plugin-vis 4.2.2 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/auto_snapshots/_extract_auto_snapshot_options.mjs +1 -1
  2. package/dist/auto_snapshots/_extract_auto_snapshot_options.mjs.map +1 -1
  3. package/dist/client/external/vitest/vitest_browser_context_proxy.mjs.map +1 -1
  4. package/dist/client/external/vitest/vitest_suite_proxy.d.mts +1 -3
  5. package/dist/client/external/vitest/vitest_suite_proxy.mjs +5 -5
  6. package/dist/client/external/vitest/vitest_suite_proxy.mjs.map +1 -1
  7. package/dist/client/page/_ctx.d.mts +1 -1
  8. package/dist/client/page/_ctx.mjs.map +1 -1
  9. package/dist/client/snapshot/compare_image_snapshot.logic.mjs +2 -1
  10. package/dist/client/snapshot/compare_image_snapshot.logic.mjs.map +1 -1
  11. package/dist/client/snapshot/compare_image_snapshot.mjs +1 -1
  12. package/dist/client/snapshot/compare_image_snapshot.mjs.map +1 -1
  13. package/dist/client/suite/auto_snapshot_matcher.d.mts +2 -2
  14. package/dist/client/suite/auto_snapshot_matcher.d.mts.map +1 -1
  15. package/dist/client/suite/auto_snapshot_matcher.mjs +4 -2
  16. package/dist/client/suite/auto_snapshot_matcher.mjs.map +1 -1
  17. package/dist/config/types.d.mts +15 -3
  18. package/dist/config/vis.mjs +1 -1
  19. package/dist/config/vis.mjs.map +1 -1
  20. package/dist/{client-api.d.mts → exports/client-api.d.mts} +12 -12
  21. package/dist/exports/client-api.mjs +11 -0
  22. package/dist/exports/config.d.mts +5 -0
  23. package/dist/exports/config.mjs +4 -0
  24. package/dist/exports/presets/auto.mjs +9 -0
  25. package/dist/exports/presets/auto.mjs.map +1 -0
  26. package/dist/exports/presets/manual.mjs +9 -0
  27. package/dist/exports/presets/manual.mjs.map +1 -0
  28. package/dist/exports/server-utils.d.mts +5 -0
  29. package/dist/exports/server-utils.mjs +6 -0
  30. package/dist/exports/setup-api.d.mts +4 -0
  31. package/dist/exports/setup-api.mjs +5 -0
  32. package/dist/exports/setup.d.mts +3 -0
  33. package/dist/exports/setup.mjs +4 -0
  34. package/dist/exports/testing/node.d.mts +4 -0
  35. package/dist/exports/testing/node.mjs +5 -0
  36. package/dist/exports/testing.d.mts +2 -0
  37. package/dist/exports/testing.mjs +3 -0
  38. package/dist/server/commands/prepare_image_snapshot_comparison.mjs.map +1 -1
  39. package/dist/server/commands/prepare_page_image_snapshot_comparison.mjs.map +1 -1
  40. package/dist/server/snapshot_path.d.mts +0 -1
  41. package/dist/server/snapshot_path.d.mts.map +1 -1
  42. package/dist/server/snapshot_path_limits.d.mts +28 -0
  43. package/dist/server/snapshot_path_limits.d.mts.map +1 -0
  44. package/dist/server/snapshot_path_limits.mjs +92 -0
  45. package/dist/server/snapshot_path_limits.mjs.map +1 -0
  46. package/dist/server/suite.mjs +8 -2
  47. package/dist/server/suite.mjs.map +1 -1
  48. package/dist/server/testing/stubBrowserCommandContext.mjs +9 -0
  49. package/dist/server/testing/stubBrowserCommandContext.mjs.map +1 -0
  50. package/dist/server/testing/stubSuite.d.mts +17 -0
  51. package/dist/server/testing/stubSuite.d.mts.map +1 -0
  52. package/dist/server/testing/stubSuite.mjs +23 -0
  53. package/dist/server/testing/stubSuite.mjs.map +1 -0
  54. package/dist/server/testing/stubUserConfig.mjs +8 -0
  55. package/dist/server/testing/stubUserConfig.mjs.map +1 -0
  56. package/dist/server/vis_options.d.mts +120 -0
  57. package/dist/server/vis_options.d.mts.map +1 -0
  58. package/dist/server/vis_options.mjs +7 -1
  59. package/dist/server/vis_options.mjs.map +1 -1
  60. package/dist/server/vis_server_context.logic.mjs +37 -10
  61. package/dist/server/vis_server_context.logic.mjs.map +1 -1
  62. package/dist/server/vis_server_context.types.d.mts +32 -2
  63. package/dist/server/vis_server_context.types.d.mts.map +1 -0
  64. package/dist/setup/create_vis.d.mts +1 -66
  65. package/dist/setup/create_vis.d.mts.map +1 -1
  66. package/dist/setup/create_vis.mjs +9 -45
  67. package/dist/setup/create_vis.mjs.map +1 -1
  68. package/dist/shared/types.d.mts +21 -1
  69. package/dist/shared/types.d.mts.map +1 -1
  70. package/package.json +22 -49
  71. package/readme.md +10 -4
  72. package/src/auto_snapshots/_extract_auto_snapshot_options.ts +1 -1
  73. package/src/client/expect/to_match_image_snapshot.mdx +24 -1
  74. package/src/client/external/vitest/vitest_browser_context_proxy.ts +2 -2
  75. package/src/client/external/vitest/vitest_suite_proxy.ts +6 -6
  76. package/src/client/page/_ctx.ts +2 -2
  77. package/src/client/page/to_match_image_snapshot.mdx +23 -1
  78. package/src/client/snapshot/compare_image_snapshot.logic.ts +1 -0
  79. package/src/client/snapshot/compare_image_snapshot.ts +2 -2
  80. package/src/client/suite/auto_snapshot_matcher.ts +9 -1
  81. package/src/config/types.ts +15 -3
  82. package/src/config/vis.ts +1 -1
  83. package/src/exports/client-api.ts +13 -0
  84. package/src/exports/config.ts +3 -0
  85. package/src/exports/presets/auto.ts +3 -0
  86. package/src/exports/presets/manual.ts +3 -0
  87. package/src/exports/server-utils.ts +7 -0
  88. package/src/exports/setup-api.ts +5 -0
  89. package/src/exports/setup.ts +3 -0
  90. package/src/exports/testing/node.ts +4 -0
  91. package/src/exports/testing.ts +1 -0
  92. package/src/server/commands/prepare_image_snapshot_comparison.ts +2 -2
  93. package/src/server/commands/prepare_page_image_snapshot_comparison.ts +2 -1
  94. package/src/server/snapshot_path_limits.ts +135 -0
  95. package/src/server/suite.ts +19 -4
  96. package/src/server/vis_options.ts +10 -1
  97. package/src/server/vis_server_context.logic.ts +47 -17
  98. package/src/setup/create_vis.mdx +2 -6
  99. package/src/setup/create_vis.ts +13 -123
  100. package/src/shared/types.ts +21 -1
  101. package/dist/client-api.mjs +0 -11
  102. package/dist/config.d.mts +0 -5
  103. package/dist/config.mjs +0 -4
  104. package/dist/presets/auto.mjs +0 -16
  105. package/dist/presets/auto.mjs.map +0 -1
  106. package/dist/presets/enable.d.mts +0 -1
  107. package/dist/presets/enable.mjs +0 -11
  108. package/dist/presets/enable.mjs.map +0 -1
  109. package/dist/presets/manual.mjs +0 -11
  110. package/dist/presets/manual.mjs.map +0 -1
  111. package/dist/server-utils.d.mts +0 -4
  112. package/dist/server-utils.mjs +0 -5
  113. package/dist/setup-api.d.mts +0 -4
  114. package/dist/setup-api.mjs +0 -5
  115. package/dist/setup.d.mts +0 -13
  116. package/dist/setup.d.mts.map +0 -1
  117. package/dist/setup.mjs +0 -13
  118. package/dist/setup.mjs.map +0 -1
  119. package/dist/testing.d.mts +0 -2
  120. package/dist/testing.mjs +0 -3
  121. package/src/client-api.ts +0 -13
  122. package/src/config.ts +0 -3
  123. package/src/presets/auto.ts +0 -9
  124. package/src/presets/enable.ts +0 -5
  125. package/src/presets/manual.ts +0 -5
  126. package/src/server-utils.ts +0 -3
  127. package/src/setup-api.ts +0 -5
  128. package/src/setup.ts +0 -10
  129. package/src/testing.ts +0 -1
  130. /package/dist/{presets → exports/presets}/auto.d.mts +0 -0
  131. /package/dist/{presets → exports/presets}/manual.d.mts +0 -0
@@ -1,9 +1,10 @@
1
1
  import { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from "../shared/constants.mjs";
2
+ import { resolveSnapshotSubpathWithinLimits } from "./snapshot_path_limits.mjs";
2
3
  import { getProjectName, getProjectRoot } from "./project.mjs";
3
4
  import { getSnapshotSubpath, resolveSnapshotRootDir } from "./snapshot_path.mjs";
4
5
  import { getVisOption } from "./vis_options.mjs";
5
6
  import { deps } from "./vis_server_context.deps.mjs";
6
- import { join, relative } from "pathe";
7
+ import { join, relative, resolve } from "pathe";
7
8
 
8
9
  //#region src/server/suite.ts
9
10
  const suites = {};
@@ -71,7 +72,12 @@ function createModule(state, testPath, options) {
71
72
  };
72
73
  }
73
74
  function getTaskSubpath(state, testPath, options) {
74
- return getSnapshotSubpath(relative(state.projectRoot, testPath), options);
75
+ const raw = getSnapshotSubpath(relative(state.projectRoot, testPath), options);
76
+ return resolveSnapshotSubpathWithinLimits({
77
+ snapshotBaselineRootAbs: resolve(state.projectRoot, state.snapshotBaselineDir),
78
+ rawSnapshotSubpath: raw,
79
+ shortenLongSnapshotPaths: options.shortenLongSnapshotPaths === true
80
+ });
75
81
  }
76
82
  function getSuite(context) {
77
83
  return suites[getSuiteId(context)];
@@ -1 +1 @@
1
- {"version":3,"file":"suite.mjs","names":[],"sources":["../../src/server/suite.ts"],"sourcesContent":["import { join, relative } from 'pathe'\nimport type { VisOptions } from '../config/types.ts'\nimport { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from '../shared/constants.ts'\nimport { getProjectName, getProjectRoot } from './project.ts'\nimport { getSnapshotSubpath, resolveSnapshotRootDir } from './snapshot_path.ts'\nimport { getVisOption } from './vis_options.ts'\nimport { deps } from './vis_server_context.deps.ts'\nimport type { ExtendedBrowserCommandContext, VisSuite, VisSuites } from './vis_server_context.types.ts'\n\nconst suites: VisSuites = {}\n\n/**\n * Setup suite is called on each test file's beforeAll hook.\n * Test files include vitest test files and storybook story files.\n * It needs to make sure there is no race condition between the test files.\n */\nexport async function setupSuite(browserContext: ExtendedBrowserCommandContext) {\n\tconst suiteId = getSuiteId(browserContext)\n\tconst visOptions = getVisOption(browserContext)\n\n\tif (!suites[suiteId]) {\n\t\tsuites[suiteId] = createSuite(browserContext, visOptions)\n\t}\n\n\tconst suite = await suites[suiteId]\n\n\tconst { taskSubpath, baselineDir, diffDir, resultDir, tasks } = createModule(\n\t\tsuite,\n\t\tbrowserContext.testPath!,\n\t\tvisOptions,\n\t)\n\tsuite.modules[taskSubpath] = { baselineDir, diffDir, resultDir, tasks }\n\n\tawait Promise.allSettled([deps.rimraf(diffDir), deps.rimraf(resultDir)])\n\treturn {\n\t\tcomparisonMethod: visOptions.comparisonMethod,\n\t\tdiffOptions: visOptions.diffOptions,\n\t\tfailureThreshold: visOptions.failureThreshold,\n\t\tfailureThresholdType: visOptions.failureThresholdType,\n\t\tsnapshotKey: visOptions.snapshotKey,\n\t\tsubject: visOptions.subject,\n\t\ttimeout: visOptions.timeout,\n\t}\n}\n\n/**\n * Suite ID also contains the project name to make it unique\n * across different projects.\n */\nexport function getSuiteId(context: ExtendedBrowserCommandContext) {\n\treturn `${getProjectName(context)}/${context.project.config.name}`\n}\n\nasync function createSuite(\n\tbrowserContext: ExtendedBrowserCommandContext,\n\tvisOptions: Pick<VisOptions, 'snapshotRootDir' | 'subject'>,\n) {\n\t// console.log('visOptions', visOptions)\n\tconst snapshotRootDir = resolveSnapshotRootDir(browserContext, visOptions)\n\tconst projectRoot = getProjectRoot(browserContext)\n\n\tconst state = {\n\t\tprojectRoot,\n\t\ttestTimeout: browserContext.project.config.testTimeout,\n\t\thookTimeout: browserContext.project.config.hookTimeout,\n\t\tsnapshotRootDir,\n\t\tsnapshotBaselineDir: join(snapshotRootDir, BASELINE_DIR),\n\t\tsnapshotResultDir: join(snapshotRootDir, RESULT_DIR),\n\t\tsnapshotDiffDir: join(snapshotRootDir, DIFF_DIR),\n\t\tsnapshotRootPath: join(projectRoot, snapshotRootDir),\n\t\tsubject: visOptions.subject,\n\t\tmodules: {},\n\t}\n\tawait Promise.allSettled([deps.rimraf(join(state.snapshotDiffDir)), deps.rimraf(join(state.snapshotResultDir))])\n\treturn state\n}\n\nexport function createModule(state: VisSuite, testPath: string, options: Pick<VisOptions, 'snapshotSubpath'>) {\n\tconst taskSubpath = getTaskSubpath(state, testPath, options)\n\treturn {\n\t\ttaskSubpath,\n\t\tbaselineDir: join(state.snapshotBaselineDir, taskSubpath),\n\t\tresultDir: join(state.snapshotResultDir, taskSubpath),\n\t\tdiffDir: join(state.snapshotDiffDir, taskSubpath),\n\t\ttasks: {},\n\t}\n}\n\nexport function getTaskSubpath(state: VisSuite, testPath: string, options: Pick<VisOptions, 'snapshotSubpath'>) {\n\treturn getSnapshotSubpath(relative(state.projectRoot, testPath), options)\n}\n\nexport function getSuite(context: ExtendedBrowserCommandContext) {\n\treturn suites[getSuiteId(context)]!\n}\n"],"mappings":";;;;;;;;AASA,MAAM,SAAoB,EAAE;;;;;;AAO5B,eAAsB,WAAW,gBAA+C;CAC/E,MAAM,UAAU,WAAW,eAAe;CAC1C,MAAM,aAAa,aAAa,eAAe;AAE/C,KAAI,CAAC,OAAO,SACX,QAAO,WAAW,YAAY,gBAAgB,WAAW;CAG1D,MAAM,QAAQ,MAAM,OAAO;CAE3B,MAAM,EAAE,aAAa,aAAa,SAAS,WAAW,UAAU,aAC/D,OACA,eAAe,UACf,WACA;AACD,OAAM,QAAQ,eAAe;EAAE;EAAa;EAAS;EAAW;EAAO;AAEvE,OAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,QAAQ,EAAE,KAAK,OAAO,UAAU,CAAC,CAAC;AACxE,QAAO;EACN,kBAAkB,WAAW;EAC7B,aAAa,WAAW;EACxB,kBAAkB,WAAW;EAC7B,sBAAsB,WAAW;EACjC,aAAa,WAAW;EACxB,SAAS,WAAW;EACpB,SAAS,WAAW;EACpB;;;;;;AAOF,SAAgB,WAAW,SAAwC;AAClE,QAAO,GAAG,eAAe,QAAQ,CAAC,GAAG,QAAQ,QAAQ,OAAO;;AAG7D,eAAe,YACd,gBACA,YACC;CAED,MAAM,kBAAkB,uBAAuB,gBAAgB,WAAW;CAC1E,MAAM,cAAc,eAAe,eAAe;CAElD,MAAM,QAAQ;EACb;EACA,aAAa,eAAe,QAAQ,OAAO;EAC3C,aAAa,eAAe,QAAQ,OAAO;EAC3C;EACA,qBAAqB,KAAK,iBAAiB,aAAa;EACxD,mBAAmB,KAAK,iBAAiB,WAAW;EACpD,iBAAiB,KAAK,iBAAiB,SAAS;EAChD,kBAAkB,KAAK,aAAa,gBAAgB;EACpD,SAAS,WAAW;EACpB,SAAS,EAAE;EACX;AACD,OAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,KAAK,MAAM,gBAAgB,CAAC,EAAE,KAAK,OAAO,KAAK,MAAM,kBAAkB,CAAC,CAAC,CAAC;AAChH,QAAO;;AAGR,SAAgB,aAAa,OAAiB,UAAkB,SAA8C;CAC7G,MAAM,cAAc,eAAe,OAAO,UAAU,QAAQ;AAC5D,QAAO;EACN;EACA,aAAa,KAAK,MAAM,qBAAqB,YAAY;EACzD,WAAW,KAAK,MAAM,mBAAmB,YAAY;EACrD,SAAS,KAAK,MAAM,iBAAiB,YAAY;EACjD,OAAO,EAAE;EACT;;AAGF,SAAgB,eAAe,OAAiB,UAAkB,SAA8C;AAC/G,QAAO,mBAAmB,SAAS,MAAM,aAAa,SAAS,EAAE,QAAQ;;AAG1E,SAAgB,SAAS,SAAwC;AAChE,QAAO,OAAO,WAAW,QAAQ"}
1
+ {"version":3,"file":"suite.mjs","names":[],"sources":["../../src/server/suite.ts"],"sourcesContent":["import { join, relative, resolve } from 'pathe'\nimport type { VisOptions } from '../config/types.ts'\nimport { BASELINE_DIR, DIFF_DIR, RESULT_DIR } from '../shared/constants.ts'\nimport { getProjectName, getProjectRoot } from './project.ts'\nimport { getSnapshotSubpath, resolveSnapshotRootDir } from './snapshot_path.ts'\nimport { resolveSnapshotSubpathWithinLimits } from './snapshot_path_limits.ts'\nimport { getVisOption } from './vis_options.ts'\nimport { deps } from './vis_server_context.deps.ts'\nimport type { ExtendedBrowserCommandContext, VisSuite, VisSuites } from './vis_server_context.types.ts'\n\nconst suites: VisSuites = {}\n\n/**\n * Setup suite is called on each test file's beforeAll hook.\n * Test files include vitest test files and storybook story files.\n * It needs to make sure there is no race condition between the test files.\n */\nexport async function setupSuite(browserContext: ExtendedBrowserCommandContext) {\n\tconst suiteId = getSuiteId(browserContext)\n\tconst visOptions = getVisOption(browserContext)\n\n\tif (!suites[suiteId]) {\n\t\tsuites[suiteId] = createSuite(browserContext, visOptions)\n\t}\n\n\tconst suite = await suites[suiteId]\n\n\tconst { taskSubpath, baselineDir, diffDir, resultDir, tasks } = createModule(\n\t\tsuite,\n\t\tbrowserContext.testPath!,\n\t\tvisOptions,\n\t)\n\tsuite.modules[taskSubpath] = { baselineDir, diffDir, resultDir, tasks }\n\n\tawait Promise.allSettled([deps.rimraf(diffDir), deps.rimraf(resultDir)])\n\treturn {\n\t\tcomparisonMethod: visOptions.comparisonMethod,\n\t\tdiffOptions: visOptions.diffOptions,\n\t\tfailureThreshold: visOptions.failureThreshold,\n\t\tfailureThresholdType: visOptions.failureThresholdType,\n\t\tsnapshotKey: visOptions.snapshotKey,\n\t\tsubject: visOptions.subject,\n\t\ttimeout: visOptions.timeout,\n\t}\n}\n\n/**\n * Suite ID also contains the project name to make it unique\n * across different projects.\n */\nexport function getSuiteId(context: ExtendedBrowserCommandContext) {\n\treturn `${getProjectName(context)}/${context.project.config.name}`\n}\n\nasync function createSuite(\n\tbrowserContext: ExtendedBrowserCommandContext,\n\tvisOptions: Pick<VisOptions, 'snapshotRootDir' | 'subject'>,\n) {\n\t// console.log('visOptions', visOptions)\n\tconst snapshotRootDir = resolveSnapshotRootDir(browserContext, visOptions)\n\tconst projectRoot = getProjectRoot(browserContext)\n\n\tconst state = {\n\t\tprojectRoot,\n\t\ttestTimeout: browserContext.project.config.testTimeout,\n\t\thookTimeout: browserContext.project.config.hookTimeout,\n\t\tsnapshotRootDir,\n\t\tsnapshotBaselineDir: join(snapshotRootDir, BASELINE_DIR),\n\t\tsnapshotResultDir: join(snapshotRootDir, RESULT_DIR),\n\t\tsnapshotDiffDir: join(snapshotRootDir, DIFF_DIR),\n\t\tsnapshotRootPath: join(projectRoot, snapshotRootDir),\n\t\tsubject: visOptions.subject,\n\t\tmodules: {},\n\t}\n\tawait Promise.allSettled([deps.rimraf(join(state.snapshotDiffDir)), deps.rimraf(join(state.snapshotResultDir))])\n\treturn state\n}\n\nexport function createModule(\n\tstate: VisSuite,\n\ttestPath: string,\n\toptions: Pick<VisOptions, 'snapshotSubpath' | 'shortenLongSnapshotPaths'>,\n) {\n\tconst taskSubpath = getTaskSubpath(state, testPath, options)\n\treturn {\n\t\ttaskSubpath,\n\t\tbaselineDir: join(state.snapshotBaselineDir, taskSubpath),\n\t\tresultDir: join(state.snapshotResultDir, taskSubpath),\n\t\tdiffDir: join(state.snapshotDiffDir, taskSubpath),\n\t\ttasks: {},\n\t}\n}\n\nexport function getTaskSubpath(\n\tstate: VisSuite,\n\ttestPath: string,\n\toptions: Pick<VisOptions, 'snapshotSubpath' | 'shortenLongSnapshotPaths'>,\n) {\n\tconst raw = getSnapshotSubpath(relative(state.projectRoot, testPath), options)\n\tconst snapshotBaselineRootAbs = resolve(state.projectRoot, state.snapshotBaselineDir)\n\treturn resolveSnapshotSubpathWithinLimits({\n\t\tsnapshotBaselineRootAbs,\n\t\trawSnapshotSubpath: raw,\n\t\tshortenLongSnapshotPaths: options.shortenLongSnapshotPaths === true,\n\t})\n}\n\nexport function getSuite(context: ExtendedBrowserCommandContext) {\n\treturn suites[getSuiteId(context)]!\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,SAAoB,EAAE;;;;;;AAO5B,eAAsB,WAAW,gBAA+C;CAC/E,MAAM,UAAU,WAAW,eAAe;CAC1C,MAAM,aAAa,aAAa,eAAe;AAE/C,KAAI,CAAC,OAAO,SACX,QAAO,WAAW,YAAY,gBAAgB,WAAW;CAG1D,MAAM,QAAQ,MAAM,OAAO;CAE3B,MAAM,EAAE,aAAa,aAAa,SAAS,WAAW,UAAU,aAC/D,OACA,eAAe,UACf,WACA;AACD,OAAM,QAAQ,eAAe;EAAE;EAAa;EAAS;EAAW;EAAO;AAEvE,OAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,QAAQ,EAAE,KAAK,OAAO,UAAU,CAAC,CAAC;AACxE,QAAO;EACN,kBAAkB,WAAW;EAC7B,aAAa,WAAW;EACxB,kBAAkB,WAAW;EAC7B,sBAAsB,WAAW;EACjC,aAAa,WAAW;EACxB,SAAS,WAAW;EACpB,SAAS,WAAW;EACpB;;;;;;AAOF,SAAgB,WAAW,SAAwC;AAClE,QAAO,GAAG,eAAe,QAAQ,CAAC,GAAG,QAAQ,QAAQ,OAAO;;AAG7D,eAAe,YACd,gBACA,YACC;CAED,MAAM,kBAAkB,uBAAuB,gBAAgB,WAAW;CAC1E,MAAM,cAAc,eAAe,eAAe;CAElD,MAAM,QAAQ;EACb;EACA,aAAa,eAAe,QAAQ,OAAO;EAC3C,aAAa,eAAe,QAAQ,OAAO;EAC3C;EACA,qBAAqB,KAAK,iBAAiB,aAAa;EACxD,mBAAmB,KAAK,iBAAiB,WAAW;EACpD,iBAAiB,KAAK,iBAAiB,SAAS;EAChD,kBAAkB,KAAK,aAAa,gBAAgB;EACpD,SAAS,WAAW;EACpB,SAAS,EAAE;EACX;AACD,OAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,KAAK,MAAM,gBAAgB,CAAC,EAAE,KAAK,OAAO,KAAK,MAAM,kBAAkB,CAAC,CAAC,CAAC;AAChH,QAAO;;AAGR,SAAgB,aACf,OACA,UACA,SACC;CACD,MAAM,cAAc,eAAe,OAAO,UAAU,QAAQ;AAC5D,QAAO;EACN;EACA,aAAa,KAAK,MAAM,qBAAqB,YAAY;EACzD,WAAW,KAAK,MAAM,mBAAmB,YAAY;EACrD,SAAS,KAAK,MAAM,iBAAiB,YAAY;EACjD,OAAO,EAAE;EACT;;AAGF,SAAgB,eACf,OACA,UACA,SACC;CACD,MAAM,MAAM,mBAAmB,SAAS,MAAM,aAAa,SAAS,EAAE,QAAQ;AAE9E,QAAO,mCAAmC;EACzC,yBAF+B,QAAQ,MAAM,aAAa,MAAM,oBAAoB;EAGpF,oBAAoB;EACpB,0BAA0B,QAAQ,6BAA6B;EAC/D,CAAC;;AAGH,SAAgB,SAAS,SAAwC;AAChE,QAAO,OAAO,WAAW,QAAQ"}
@@ -0,0 +1,9 @@
1
+ import { stub } from "type-plus";
2
+ import "@vitest/browser-playwright";
3
+
4
+ //#region src/server/testing/stubBrowserCommandContext.ts
5
+ const stubBrowserCommandContext = stub.build({});
6
+
7
+ //#endregion
8
+ export { stubBrowserCommandContext };
9
+ //# sourceMappingURL=stubBrowserCommandContext.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stubBrowserCommandContext.mjs","names":[],"sources":["../../../src/server/testing/stubBrowserCommandContext.ts"],"sourcesContent":["import '@vitest/browser-playwright'\nimport { stub } from 'type-plus'\nimport type { ExtendedBrowserCommandContext } from '../vis_server_context.types.ts'\n\nexport const stubBrowserCommandContext = stub.build<ExtendedBrowserCommandContext>({})\n\nexport function createStubPartialBrowserCommandContext({ root, testPath }: { root: string; testPath: string }) {\n\treturn stub.build<ExtendedBrowserCommandContext>({\n\t\tproject: {\n\t\t\tconfig: { root },\n\t\t\trunner: { config: { name: 'subject' } },\n\t\t} as any,\n\t\tprovider: {},\n\t\ttestPath,\n\t})\n}\n"],"mappings":";;;;AAIA,MAAa,4BAA4B,KAAK,MAAqC,EAAE,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ExtendedBrowserCommandContext } from "../vis_server_context.types.mjs";
2
+ import { RecursivePartial } from "type-plus";
3
+ import * as vite0 from "vite";
4
+ import { TestUserConfig } from "vitest/node";
5
+
6
+ //#region src/server/testing/stubSuite.d.ts
7
+ declare function stubSuite(partialUserConfig?: RecursivePartial<{
8
+ test?: {
9
+ name?: TestUserConfig['name'];
10
+ };
11
+ }>, partialBrowserCommandContext?: RecursivePartial<ExtendedBrowserCommandContext>): {
12
+ userConfig: vite0.UserConfig;
13
+ browserCommandContext: ExtendedBrowserCommandContext;
14
+ };
15
+ //#endregion
16
+ export { stubSuite };
17
+ //# sourceMappingURL=stubSuite.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stubSuite.d.mts","names":[],"sources":["../../../src/server/testing/stubSuite.ts"],"sourcesContent":[],"mappings":";;;;;;iBAOgB,SAAA,kBACuC,GAAnC;;WAAmC;EADvC,CAAA;CACuC,CAAA,EAAA,4BAAA,CAAA,EACxB,gBADwB,CACP,6BADO,CAAA,CAAA,EAAA;EAAnC,UAAA,EAC2B,KAAA,CAAA,UAD3B;EAC4B,qBAAA,+BAAA;CAAjB"}
@@ -0,0 +1,23 @@
1
+ import { stubBrowserCommandContext } from "./stubBrowserCommandContext.mjs";
2
+ import { stubUserConfig } from "./stubUserConfig.mjs";
3
+ import { resolve } from "pathe";
4
+ import { requiredDeep } from "type-plus";
5
+
6
+ //#region src/server/testing/stubSuite.ts
7
+ function stubSuite(partialUserConfig = {}, partialBrowserCommandContext = {}) {
8
+ const root = resolve(import.meta.dirname, "../..");
9
+ return {
10
+ userConfig: stubUserConfig({
11
+ root,
12
+ ...partialUserConfig
13
+ }),
14
+ browserCommandContext: stubBrowserCommandContext(requiredDeep({ project: {
15
+ config: { root },
16
+ runner: { config: { name: partialUserConfig.test?.name } }
17
+ } }, partialBrowserCommandContext))
18
+ };
19
+ }
20
+
21
+ //#endregion
22
+ export { stubSuite };
23
+ //# sourceMappingURL=stubSuite.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stubSuite.mjs","names":[],"sources":["../../../src/server/testing/stubSuite.ts"],"sourcesContent":["import { resolve } from 'pathe'\nimport { requiredDeep, type RecursivePartial } from 'type-plus'\nimport type { TestUserConfig } from 'vitest/node'\nimport type { ExtendedBrowserCommandContext } from '../vis_server_context.types.ts'\nimport { stubBrowserCommandContext } from './stubBrowserCommandContext.ts'\nimport { stubUserConfig } from './stubUserConfig.ts'\n\nexport function stubSuite(\n\tpartialUserConfig: RecursivePartial<{ test?: { name?: TestUserConfig['name'] } }> = {},\n\tpartialBrowserCommandContext: RecursivePartial<ExtendedBrowserCommandContext> = {},\n) {\n\tconst root = resolve(import.meta.dirname, '../..')\n\tconst userConfig = stubUserConfig({\n\t\troot,\n\t\t...partialUserConfig,\n\t})\n\tconst browserCommandContext = stubBrowserCommandContext(\n\t\trequiredDeep<RecursivePartial<ExtendedBrowserCommandContext>>(\n\t\t\t{\n\t\t\t\tproject: {\n\t\t\t\t\tconfig: { root },\n\t\t\t\t\trunner: {\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tname: partialUserConfig.test?.name as string | undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tpartialBrowserCommandContext,\n\t\t),\n\t)\n\treturn {\n\t\tuserConfig,\n\t\tbrowserCommandContext,\n\t}\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UACf,oBAAoF,EAAE,EACtF,+BAAgF,EAAE,EACjF;CACD,MAAM,OAAO,QAAQ,OAAO,KAAK,SAAS,QAAQ;AAoBlD,QAAO;EACN,YApBkB,eAAe;GACjC;GACA,GAAG;GACH,CAAC;EAkBD,uBAjB6B,0BAC7B,aACC,EACC,SAAS;GACR,QAAQ,EAAE,MAAM;GAChB,QAAQ,EACP,QAAQ,EACP,MAAM,kBAAkB,MAAM,MAC9B,EACD;GACD,EACD,EACD,6BACA,CACD;EAIA"}
@@ -0,0 +1,8 @@
1
+ import { stub } from "type-plus";
2
+
3
+ //#region src/server/testing/stubUserConfig.ts
4
+ const stubUserConfig = stub.build((stub$1) => ({ ...stub$1 }));
5
+
6
+ //#endregion
7
+ export { stubUserConfig };
8
+ //# sourceMappingURL=stubUserConfig.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stubUserConfig.mjs","names":["stub"],"sources":["../../../src/server/testing/stubUserConfig.ts"],"sourcesContent":["import { stub } from 'type-plus'\nimport type { ViteUserConfig } from 'vitest/config'\n\nexport const stubUserConfig = stub.build<ViteUserConfig>((stub) => ({\n\t...stub,\n}))\n"],"mappings":";;;AAGA,MAAa,iBAAiB,KAAK,OAAuB,YAAU,EACnE,GAAGA,QACH,EAAE"}
@@ -0,0 +1,120 @@
1
+ import { PixelDiffOptions } from "../shared/types.mjs";
2
+ import { ExtendedBrowserCommandContext } from "./vis_server_context.types.mjs";
3
+ import "../index.mjs";
4
+ import * as ssim_js0 from "ssim.js";
5
+ import { TestUserConfig } from "vitest/node";
6
+
7
+ //#region src/server/vis_options.d.ts
8
+
9
+ declare function getVisOption(context: ExtendedBrowserCommandContext): {
10
+ comparisonMethod: any;
11
+ diffOptions?: Partial<ssim_js0.Options> | undefined;
12
+ failureThresholdType?: "pixel" | "percent" | undefined;
13
+ failureThreshold?: number | undefined;
14
+ timeout?: number | undefined;
15
+ snapshotKey?: string | undefined;
16
+ subject?: string | undefined;
17
+ preset?: "manual" | "auto" | "custom" | undefined;
18
+ snapshotRootDir?: string | ((context: {
19
+ ci: boolean;
20
+ rootDir: string;
21
+ projectName?: string | undefined;
22
+ browserName?: string | undefined;
23
+ providerName: string;
24
+ platform: string;
25
+ screenshotFailures?: boolean | undefined;
26
+ screenshotDirectory?: string | undefined;
27
+ }) => string) | undefined;
28
+ snapshotSubpath?: ((options: {
29
+ subpath: string;
30
+ }) => string) | undefined;
31
+ shortenLongSnapshotPaths?: boolean | undefined;
32
+ } | {
33
+ comparisonMethod: any;
34
+ diffOptions?: {
35
+ threshold?: number | undefined;
36
+ includeAA?: boolean | undefined;
37
+ alpha?: number | undefined;
38
+ aaColor?: [number, number, number] | undefined;
39
+ diffColor?: [number, number, number] | undefined;
40
+ diffColorAlt?: [number, number, number] | undefined;
41
+ diffMask?: boolean | undefined;
42
+ } | Partial<ssim_js0.Options> | undefined;
43
+ failureThresholdType?: "pixel" | "percent" | undefined;
44
+ failureThreshold?: number | undefined;
45
+ timeout?: number | undefined;
46
+ snapshotKey?: string | undefined;
47
+ subject?: string | undefined;
48
+ preset?: "manual" | "auto" | "custom" | undefined;
49
+ snapshotRootDir?: string | ((context: {
50
+ ci: boolean;
51
+ rootDir: string;
52
+ projectName?: string | undefined;
53
+ browserName?: string | undefined;
54
+ providerName: string;
55
+ platform: string;
56
+ screenshotFailures?: boolean | undefined;
57
+ screenshotDirectory?: string | undefined;
58
+ }) => string) | undefined;
59
+ snapshotSubpath?: ((options: {
60
+ subpath: string;
61
+ }) => string) | undefined;
62
+ shortenLongSnapshotPaths?: boolean | undefined;
63
+ } | {
64
+ comparisonMethod: any;
65
+ diffOptions?: {
66
+ threshold?: number | undefined;
67
+ includeAA?: boolean | undefined;
68
+ alpha?: number | undefined;
69
+ aaColor?: [number, number, number] | undefined;
70
+ diffColor?: [number, number, number] | undefined;
71
+ diffColorAlt?: [number, number, number] | undefined;
72
+ diffMask?: boolean | undefined;
73
+ } | Partial<ssim_js0.Options> | undefined;
74
+ failureThresholdType?: "pixel" | "percent" | undefined;
75
+ failureThreshold?: number | undefined;
76
+ timeout?: number | undefined;
77
+ snapshotKey?: string | undefined;
78
+ subject?: string | undefined;
79
+ preset?: "manual" | "auto" | "custom" | undefined;
80
+ snapshotRootDir?: string | ((context: {
81
+ ci: boolean;
82
+ rootDir: string;
83
+ projectName?: string | undefined;
84
+ browserName?: string | undefined;
85
+ providerName: string;
86
+ platform: string;
87
+ screenshotFailures?: boolean | undefined;
88
+ screenshotDirectory?: string | undefined;
89
+ }) => string) | undefined;
90
+ snapshotSubpath?: ((options: {
91
+ subpath: string;
92
+ }) => string) | undefined;
93
+ shortenLongSnapshotPaths?: boolean | undefined;
94
+ } | {
95
+ comparisonMethod?: any;
96
+ diffOptions?: PixelDiffOptions | undefined;
97
+ failureThresholdType?: "pixel" | "percent" | undefined;
98
+ failureThreshold?: number | undefined;
99
+ timeout?: number | undefined;
100
+ snapshotKey?: string | undefined;
101
+ subject?: string | undefined;
102
+ preset?: "manual" | "auto" | "custom" | undefined;
103
+ snapshotRootDir?: string | ((context: {
104
+ ci: boolean;
105
+ rootDir: string;
106
+ projectName?: string | undefined;
107
+ browserName?: string | undefined;
108
+ providerName: string;
109
+ platform: string;
110
+ screenshotFailures?: boolean | undefined;
111
+ screenshotDirectory?: string | undefined;
112
+ }) => string) | undefined;
113
+ snapshotSubpath?: ((options: {
114
+ subpath: string;
115
+ }) => string) | undefined;
116
+ shortenLongSnapshotPaths?: boolean | undefined;
117
+ };
118
+ //#endregion
119
+ export { getVisOption };
120
+ //# sourceMappingURL=vis_options.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_options.d.mts","names":[],"sources":["../../src/server/vis_options.ts"],"sourcesContent":[],"mappings":";;;;;;;;iBA6BgB,YAAA,UAAsB;;wBAA6B,QAAA,CAAA,OAAA"}
@@ -11,7 +11,13 @@ function setVisOption(userConfig, options) {
11
11
  visOptions[id] = options;
12
12
  }
13
13
  function getVisOption(context) {
14
- return visOptions[getProjectName(context) || DEFAULT_PROJECT_NAME] ?? {};
14
+ const id = getProjectName(context) || DEFAULT_PROJECT_NAME;
15
+ const base = visOptions[DEFAULT_PROJECT_NAME] ?? {};
16
+ const override = visOptions[id] ?? {};
17
+ return {
18
+ ...base,
19
+ ...override
20
+ };
15
21
  }
16
22
 
17
23
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"vis_options.mjs","names":[],"sources":["../../src/server/vis_options.ts"],"sourcesContent":["import type { TestUserConfig } from 'vitest/node'\nimport type { VisOptions } from '../config/types.ts'\nimport { assertSnapshotKeyWithoutDash } from '../shared/asserts.ts'\nimport { getProjectName } from './project.ts'\nimport type { ExtendedBrowserCommandContext } from './vis_server_context.types.ts'\n\nconst DEFAULT_PROJECT_NAME = '__default'\n\nconst visOptions: Record<string, VisOptions<any> | undefined> = {}\n\nexport function setVisOption(\n\tuserConfig: { test?: { name?: TestUserConfig['name'] | undefined } },\n\toptions: VisOptions<any> | undefined,\n) {\n\tassertSnapshotKeyWithoutDash(options?.snapshotKey)\n\n\tconst name = userConfig.test?.name\n\tconst id = typeof name === 'string' ? name : typeof name === 'object' ? name?.label : DEFAULT_PROJECT_NAME\n\n\tvisOptions[id] = options\n}\n\nexport function getVisOption(context: ExtendedBrowserCommandContext) {\n\tconst id = getProjectName(context) || DEFAULT_PROJECT_NAME\n\treturn visOptions[id] ?? {}\n}\n"],"mappings":";;;;AAMA,MAAM,uBAAuB;AAE7B,MAAM,aAA0D,EAAE;AAElE,SAAgB,aACf,YACA,SACC;AACD,8BAA6B,SAAS,YAAY;CAElD,MAAM,OAAO,WAAW,MAAM;CAC9B,MAAM,KAAK,OAAO,SAAS,WAAW,OAAO,OAAO,SAAS,WAAW,MAAM,QAAQ;AAEtF,YAAW,MAAM;;AAGlB,SAAgB,aAAa,SAAwC;AAEpE,QAAO,WADI,eAAe,QAAQ,IAAI,yBACb,EAAE"}
1
+ {"version":3,"file":"vis_options.mjs","names":[],"sources":["../../src/server/vis_options.ts"],"sourcesContent":["import type { TestUserConfig } from 'vitest/node'\nimport type { VisOptions } from '../config/types.ts'\nimport { assertSnapshotKeyWithoutDash } from '../shared/asserts.ts'\nimport { getProjectName } from './project.ts'\nimport type { ExtendedBrowserCommandContext } from './vis_server_context.types.ts'\n\nconst DEFAULT_PROJECT_NAME = '__default'\n\nconst visOptions: Record<string, VisOptions<any> | undefined> = {}\n\n/** Clears stored options (for tests that share this module). */\nexport function clearVisOptionsRegistryForTesting() {\n\tfor (const key of Object.keys(visOptions)) {\n\t\tdelete visOptions[key]\n\t}\n}\n\nexport function setVisOption(\n\tuserConfig: { test?: { name?: TestUserConfig['name'] | undefined } },\n\toptions: VisOptions<any> | undefined,\n) {\n\tassertSnapshotKeyWithoutDash(options?.snapshotKey)\n\n\tconst name = userConfig.test?.name\n\tconst id = typeof name === 'string' ? name : typeof name === 'object' ? name?.label : DEFAULT_PROJECT_NAME\n\n\tvisOptions[id] = options\n}\n\nexport function getVisOption(context: ExtendedBrowserCommandContext) {\n\tconst id = getProjectName(context) || DEFAULT_PROJECT_NAME\n\tconst base = visOptions[DEFAULT_PROJECT_NAME] ?? {}\n\tconst override = visOptions[id] ?? {}\n\treturn { ...base, ...override }\n}\n"],"mappings":";;;;AAMA,MAAM,uBAAuB;AAE7B,MAAM,aAA0D,EAAE;AASlE,SAAgB,aACf,YACA,SACC;AACD,8BAA6B,SAAS,YAAY;CAElD,MAAM,OAAO,WAAW,MAAM;CAC9B,MAAM,KAAK,OAAO,SAAS,WAAW,OAAO,OAAO,SAAS,WAAW,MAAM,QAAQ;AAEtF,YAAW,MAAM;;AAGlB,SAAgB,aAAa,SAAwC;CACpE,MAAM,KAAK,eAAe,QAAQ,IAAI;CACtC,MAAM,OAAO,WAAW,yBAAyB,EAAE;CACnD,MAAM,WAAW,WAAW,OAAO,EAAE;AACrC,QAAO;EAAE,GAAG;EAAM,GAAG;EAAU"}
@@ -1,4 +1,5 @@
1
1
  import { file } from "./externals/file.mjs";
2
+ import { absoluteSnapshotFilePath, getLegacySnapshotFilename, resolveLegacySnapshotFileRelativePath } from "./snapshot_path_limits.mjs";
2
3
  import { getVisOption } from "./vis_options.mjs";
3
4
  import { getSuite, getTaskSubpath } from "./suite.mjs";
4
5
  import { basename, join, resolve } from "pathe";
@@ -9,14 +10,17 @@ function createVisServerContext() {
9
10
  const context = {
10
11
  async getSnapshotResults(browserContext, taskId) {
11
12
  const suiteInfo = await context.getSuiteInfo(browserContext, taskId);
12
- const baselines = await file.glob(join(suiteInfo.projectRoot, suiteInfo.baselineDir, `${suiteInfo.taskId}-*.png`));
13
- const results = await file.glob(join(suiteInfo.projectRoot, suiteInfo.resultDir, `${suiteInfo.taskId}-*.png`));
14
- const diffs = await file.glob(join(suiteInfo.projectRoot, suiteInfo.diffDir, `${suiteInfo.taskId}-*.png`));
13
+ const legacyPattern = join(resolve(suiteInfo.projectRoot, suiteInfo.baselineDir), `${suiteInfo.taskId}-*.png`);
14
+ const baselines = await file.glob(legacyPattern);
15
+ const resultPattern = join(resolve(suiteInfo.projectRoot, suiteInfo.resultDir), `${suiteInfo.taskId}-*.png`);
16
+ const results = await file.glob(resultPattern);
17
+ const diffPattern = join(resolve(suiteInfo.projectRoot, suiteInfo.diffDir), `${suiteInfo.taskId}-*.png`);
18
+ const diffs = await file.glob(diffPattern);
15
19
  const r = [];
16
20
  await Promise.all(baselines.map(async (baselinePath) => {
17
21
  const filename = basename(baselinePath);
18
- const resultPath = results.find((r$1) => r$1.endsWith(filename));
19
- const diffPath = diffs.find((d) => d.endsWith(filename));
22
+ const resultPath = results.find((p) => p.endsWith(filename));
23
+ const diffPath = diffs.find((p) => p.endsWith(filename));
20
24
  const baselineBuffer = await file.tryReadFile(baselinePath);
21
25
  const resultBuffer = await file.tryReadFile(resultPath);
22
26
  const diffBuffer = await file.tryReadFile(diffPath);
@@ -33,7 +37,7 @@ function createVisServerContext() {
33
37
  const suiteInfo = await context.getSuiteInfo(browserContext, taskId);
34
38
  const snapshotFilename = context.getSnapshotFilename(browserContext, suiteInfo, options?.snapshotKey);
35
39
  const { baselineDir, resultDir, diffDir, task } = suiteInfo;
36
- task.count = task.count + 1;
40
+ task.count += 1;
37
41
  const baselinePath = join(baselineDir, snapshotFilename);
38
42
  const resultPath = join(resultDir, snapshotFilename);
39
43
  const diffPath = join(diffDir, snapshotFilename);
@@ -49,13 +53,36 @@ function createVisServerContext() {
49
53
  },
50
54
  async hasImageSnapshot(browserContext, taskId, snapshotKey) {
51
55
  const info = await context.getSuiteInfo(browserContext, taskId);
52
- return file.existFile(resolve(info.projectRoot, info.baselineDir, context.getSnapshotFilename(browserContext, info, snapshotKey)));
56
+ const visOptions = getVisOption(browserContext);
57
+ const legacyFilename = getLegacySnapshotFilename({
58
+ taskId: info.taskId,
59
+ explicitSnapshotKey: snapshotKey,
60
+ defaultSnapshotKey: typeof visOptions.snapshotKey === "string" ? visOptions.snapshotKey : void 0,
61
+ taskCount: info.task.count
62
+ });
63
+ const filename = resolveLegacySnapshotFileRelativePath({
64
+ projectRoot: info.projectRoot,
65
+ baselineDir: info.baselineDir,
66
+ legacySnapshotFilename: legacyFilename,
67
+ shortenLongSnapshotPaths: visOptions.shortenLongSnapshotPaths === true
68
+ });
69
+ const legacyAbs = absoluteSnapshotFilePath(info.projectRoot, info.baselineDir, filename);
70
+ return file.existFile(legacyAbs);
53
71
  },
54
72
  getSnapshotFilename(browserContext, info, snapshotKey) {
55
- if (snapshotKey) return `${info.taskId}-${snapshotKey}.png`;
56
73
  const visOptions = getVisOption(browserContext);
57
- if (typeof visOptions.snapshotKey === "string") return `${info.taskId}-${visOptions.snapshotKey}.png`;
58
- return `${info.taskId}-${info.task.count}.png`;
74
+ const legacyFilename = getLegacySnapshotFilename({
75
+ taskId: info.taskId,
76
+ explicitSnapshotKey: snapshotKey,
77
+ defaultSnapshotKey: typeof visOptions.snapshotKey === "string" ? visOptions.snapshotKey : void 0,
78
+ taskCount: info.task.count
79
+ });
80
+ return resolveLegacySnapshotFileRelativePath({
81
+ projectRoot: info.projectRoot,
82
+ baselineDir: info.baselineDir,
83
+ legacySnapshotFilename: legacyFilename,
84
+ shortenLongSnapshotPaths: visOptions.shortenLongSnapshotPaths === true
85
+ });
59
86
  },
60
87
  async getSuiteInfo(browserContext, taskId) {
61
88
  const projectState = await getSuite(browserContext);
@@ -1 +1 @@
1
- {"version":3,"file":"vis_server_context.logic.mjs","names":["r"],"sources":["../../src/server/vis_server_context.logic.ts"],"sourcesContent":["import { basename, join, resolve } from 'pathe'\nimport { pick } from 'type-plus'\nimport type { ImageSnapshotKeyOptions } from '../client-api.ts'\nimport type { ImageSnapshotResult } from '../shared/commands.types.ts'\nimport { file } from './externals/file.ts'\nimport { getSuite, getTaskSubpath } from './suite.ts'\nimport { getVisOption } from './vis_options.ts'\nimport type { ExtendedBrowserCommandContext } from './vis_server_context.types.ts'\n\nexport function createVisServerContext() {\n\tconst context = {\n\t\tasync getSnapshotResults(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\tconst suiteInfo = await context.getSuiteInfo(browserContext, taskId)\n\t\t\tconst baselines = await file.glob(join(suiteInfo.projectRoot, suiteInfo.baselineDir, `${suiteInfo.taskId}-*.png`))\n\t\t\tconst results = await file.glob(join(suiteInfo.projectRoot, suiteInfo.resultDir, `${suiteInfo.taskId}-*.png`))\n\t\t\tconst diffs = await file.glob(join(suiteInfo.projectRoot, suiteInfo.diffDir, `${suiteInfo.taskId}-*.png`))\n\n\t\t\tconst r: ImageSnapshotResult[] = []\n\t\t\tawait Promise.all(\n\t\t\t\tbaselines.map(async (baselinePath) => {\n\t\t\t\t\tconst filename = basename(baselinePath)\n\t\t\t\t\tconst resultPath = results.find((r) => r.endsWith(filename))\n\t\t\t\t\tconst diffPath = diffs.find((d) => d.endsWith(filename))\n\n\t\t\t\t\tconst baselineBuffer = await file.tryReadFile(baselinePath)\n\t\t\t\t\tconst resultBuffer = await file.tryReadFile(resultPath)\n\t\t\t\t\tconst diffBuffer = await file.tryReadFile(diffPath)\n\t\t\t\t\tr.push({\n\t\t\t\t\t\tfilename,\n\t\t\t\t\t\tbaseline: baselineBuffer?.toString('base64'),\n\t\t\t\t\t\tresult: resultBuffer?.toString('base64'),\n\t\t\t\t\t\tdiff: diffBuffer?.toString('base64'),\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\treturn r\n\t\t},\n\t\tasync getSnapshotInfo(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\ttaskId: string,\n\t\t\toptions?: ImageSnapshotKeyOptions,\n\t\t) {\n\t\t\tconst suiteInfo = await context.getSuiteInfo(browserContext, taskId)\n\t\t\tconst snapshotFilename = context.getSnapshotFilename(browserContext, suiteInfo, options?.snapshotKey)\n\n\t\t\tconst { baselineDir, resultDir, diffDir, task } = suiteInfo\n\n\t\t\ttask.count = task.count + 1\n\t\t\tconst baselinePath = join(baselineDir, snapshotFilename)\n\t\t\tconst resultPath = join(resultDir, snapshotFilename)\n\t\t\tconst diffPath = join(diffDir, snapshotFilename)\n\n\t\t\treturn {\n\t\t\t\t...pick(\n\t\t\t\t\tgetVisOption(browserContext),\n\t\t\t\t\t'comparisonMethod',\n\t\t\t\t\t'diffOptions',\n\t\t\t\t\t'failureThreshold',\n\t\t\t\t\t'failureThresholdType',\n\t\t\t\t\t'timeout',\n\t\t\t\t),\n\t\t\t\tbaselinePath,\n\t\t\t\tresultPath,\n\t\t\t\tdiffPath,\n\t\t\t}\n\t\t},\n\n\t\tasync getTaskCount(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\treturn (await context.getSuiteInfo(browserContext, taskId)).task.count\n\t\t},\n\t\tasync hasImageSnapshot(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\ttaskId: string,\n\t\t\tsnapshotKey: string | undefined,\n\t\t) {\n\t\t\tconst info = await context.getSuiteInfo(browserContext, taskId)\n\n\t\t\treturn file.existFile(\n\t\t\t\tresolve(info.projectRoot, info.baselineDir, context.getSnapshotFilename(browserContext, info, snapshotKey)),\n\t\t\t)\n\t\t},\n\t\tgetSnapshotFilename(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\tinfo: { taskId: string; task: { count: number } },\n\t\t\tsnapshotKey: string | undefined,\n\t\t) {\n\t\t\tif (snapshotKey) return `${info.taskId}-${snapshotKey}.png`\n\t\t\tconst visOptions = getVisOption(browserContext)\n\t\t\tif (typeof visOptions.snapshotKey === 'string') {\n\t\t\t\treturn `${info.taskId}-${visOptions.snapshotKey}.png`\n\t\t\t}\n\t\t\treturn `${info.taskId}-${info.task.count}.png`\n\t\t},\n\t\tasync getSuiteInfo(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\tconst projectState = await getSuite(browserContext)\n\t\t\tconst visOptions = getVisOption(browserContext)\n\t\t\tconst moduleId = getTaskSubpath(projectState, browserContext.testPath, visOptions)\n\t\t\tconst m = projectState.modules[moduleId]!\n\t\t\tconst task = (m.tasks[taskId] = m.tasks[taskId] ?? { count: 1 })\n\t\t\treturn {\n\t\t\t\tprojectRoot: projectState.projectRoot,\n\t\t\t\tsuiteId: moduleId,\n\t\t\t\ttaskId,\n\t\t\t\tbaselineDir: m.baselineDir,\n\t\t\t\tresultDir: m.resultDir,\n\t\t\t\tdiffDir: m.diffDir,\n\t\t\t\ttask,\n\t\t\t}\n\t\t},\n\t}\n\treturn context\n}\n"],"mappings":";;;;;;;AASA,SAAgB,yBAAyB;CACxC,MAAM,UAAU;EACf,MAAM,mBAAmB,gBAA+C,QAAgB;GACvF,MAAM,YAAY,MAAM,QAAQ,aAAa,gBAAgB,OAAO;GACpE,MAAM,YAAY,MAAM,KAAK,KAAK,KAAK,UAAU,aAAa,UAAU,aAAa,GAAG,UAAU,OAAO,QAAQ,CAAC;GAClH,MAAM,UAAU,MAAM,KAAK,KAAK,KAAK,UAAU,aAAa,UAAU,WAAW,GAAG,UAAU,OAAO,QAAQ,CAAC;GAC9G,MAAM,QAAQ,MAAM,KAAK,KAAK,KAAK,UAAU,aAAa,UAAU,SAAS,GAAG,UAAU,OAAO,QAAQ,CAAC;GAE1G,MAAM,IAA2B,EAAE;AACnC,SAAM,QAAQ,IACb,UAAU,IAAI,OAAO,iBAAiB;IACrC,MAAM,WAAW,SAAS,aAAa;IACvC,MAAM,aAAa,QAAQ,MAAM,QAAMA,IAAE,SAAS,SAAS,CAAC;IAC5D,MAAM,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,CAAC;IAExD,MAAM,iBAAiB,MAAM,KAAK,YAAY,aAAa;IAC3D,MAAM,eAAe,MAAM,KAAK,YAAY,WAAW;IACvD,MAAM,aAAa,MAAM,KAAK,YAAY,SAAS;AACnD,MAAE,KAAK;KACN;KACA,UAAU,gBAAgB,SAAS,SAAS;KAC5C,QAAQ,cAAc,SAAS,SAAS;KACxC,MAAM,YAAY,SAAS,SAAS;KACpC,CAAC;KACD,CACF;AACD,UAAO;;EAER,MAAM,gBACL,gBACA,QACA,SACC;GACD,MAAM,YAAY,MAAM,QAAQ,aAAa,gBAAgB,OAAO;GACpE,MAAM,mBAAmB,QAAQ,oBAAoB,gBAAgB,WAAW,SAAS,YAAY;GAErG,MAAM,EAAE,aAAa,WAAW,SAAS,SAAS;AAElD,QAAK,QAAQ,KAAK,QAAQ;GAC1B,MAAM,eAAe,KAAK,aAAa,iBAAiB;GACxD,MAAM,aAAa,KAAK,WAAW,iBAAiB;GACpD,MAAM,WAAW,KAAK,SAAS,iBAAiB;AAEhD,UAAO;IACN,GAAG,KACF,aAAa,eAAe,EAC5B,oBACA,eACA,oBACA,wBACA,UACA;IACD;IACA;IACA;IACA;;EAGF,MAAM,aAAa,gBAA+C,QAAgB;AACjF,WAAQ,MAAM,QAAQ,aAAa,gBAAgB,OAAO,EAAE,KAAK;;EAElE,MAAM,iBACL,gBACA,QACA,aACC;GACD,MAAM,OAAO,MAAM,QAAQ,aAAa,gBAAgB,OAAO;AAE/D,UAAO,KAAK,UACX,QAAQ,KAAK,aAAa,KAAK,aAAa,QAAQ,oBAAoB,gBAAgB,MAAM,YAAY,CAAC,CAC3G;;EAEF,oBACC,gBACA,MACA,aACC;AACD,OAAI,YAAa,QAAO,GAAG,KAAK,OAAO,GAAG,YAAY;GACtD,MAAM,aAAa,aAAa,eAAe;AAC/C,OAAI,OAAO,WAAW,gBAAgB,SACrC,QAAO,GAAG,KAAK,OAAO,GAAG,WAAW,YAAY;AAEjD,UAAO,GAAG,KAAK,OAAO,GAAG,KAAK,KAAK,MAAM;;EAE1C,MAAM,aAAa,gBAA+C,QAAgB;GACjF,MAAM,eAAe,MAAM,SAAS,eAAe;GACnD,MAAM,aAAa,aAAa,eAAe;GAC/C,MAAM,WAAW,eAAe,cAAc,eAAe,UAAU,WAAW;GAClF,MAAM,IAAI,aAAa,QAAQ;GAC/B,MAAM,OAAQ,EAAE,MAAM,UAAU,EAAE,MAAM,WAAW,EAAE,OAAO,GAAG;AAC/D,UAAO;IACN,aAAa,aAAa;IAC1B,SAAS;IACT;IACA,aAAa,EAAE;IACf,WAAW,EAAE;IACb,SAAS,EAAE;IACX;IACA;;EAEF;AACD,QAAO"}
1
+ {"version":3,"file":"vis_server_context.logic.mjs","names":[],"sources":["../../src/server/vis_server_context.logic.ts"],"sourcesContent":["import { basename, join, resolve } from 'pathe'\nimport { pick } from 'type-plus'\nimport type { ImageSnapshotKeyOptions } from '../exports/client-api.ts'\nimport type { ImageSnapshotResult } from '../shared/commands.types.ts'\nimport { file } from './externals/file.ts'\nimport {\n\tabsoluteSnapshotFilePath,\n\tgetLegacySnapshotFilename,\n\tresolveLegacySnapshotFileRelativePath,\n} from './snapshot_path_limits.ts'\nimport { getSuite, getTaskSubpath } from './suite.ts'\nimport { getVisOption } from './vis_options.ts'\nimport type { ExtendedBrowserCommandContext } from './vis_server_context.types.ts'\n\nexport function createVisServerContext() {\n\tconst context = {\n\t\tasync getSnapshotResults(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\tconst suiteInfo = await context.getSuiteInfo(browserContext, taskId)\n\t\t\tconst base = resolve(suiteInfo.projectRoot, suiteInfo.baselineDir)\n\n\t\t\tconst legacyPattern = join(base, `${suiteInfo.taskId}-*.png`)\n\t\t\tconst baselines = await file.glob(legacyPattern)\n\n\t\t\tconst resultPattern = join(resolve(suiteInfo.projectRoot, suiteInfo.resultDir), `${suiteInfo.taskId}-*.png`)\n\t\t\tconst results = await file.glob(resultPattern)\n\n\t\t\tconst diffPattern = join(resolve(suiteInfo.projectRoot, suiteInfo.diffDir), `${suiteInfo.taskId}-*.png`)\n\t\t\tconst diffs = await file.glob(diffPattern)\n\n\t\t\tconst r: ImageSnapshotResult[] = []\n\t\t\tawait Promise.all(\n\t\t\t\tbaselines.map(async (baselinePath) => {\n\t\t\t\t\tconst filename = basename(baselinePath)\n\t\t\t\t\tconst resultPath = results.find((p) => p.endsWith(filename))\n\t\t\t\t\tconst diffPath = diffs.find((p) => p.endsWith(filename))\n\n\t\t\t\t\tconst baselineBuffer = await file.tryReadFile(baselinePath)\n\t\t\t\t\tconst resultBuffer = await file.tryReadFile(resultPath)\n\t\t\t\t\tconst diffBuffer = await file.tryReadFile(diffPath)\n\t\t\t\t\tr.push({\n\t\t\t\t\t\tfilename,\n\t\t\t\t\t\tbaseline: baselineBuffer?.toString('base64'),\n\t\t\t\t\t\tresult: resultBuffer?.toString('base64'),\n\t\t\t\t\t\tdiff: diffBuffer?.toString('base64'),\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\treturn r\n\t\t},\n\t\tasync getSnapshotInfo(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\ttaskId: string,\n\t\t\toptions?: ImageSnapshotKeyOptions,\n\t\t) {\n\t\t\tconst suiteInfo = await context.getSuiteInfo(browserContext, taskId)\n\t\t\tconst snapshotFilename = context.getSnapshotFilename(browserContext, suiteInfo, options?.snapshotKey)\n\n\t\t\tconst { baselineDir, resultDir, diffDir, task } = suiteInfo\n\n\t\t\ttask.count += 1\n\t\t\tconst baselinePath = join(baselineDir, snapshotFilename)\n\t\t\tconst resultPath = join(resultDir, snapshotFilename)\n\t\t\tconst diffPath = join(diffDir, snapshotFilename)\n\n\t\t\treturn {\n\t\t\t\t...pick(\n\t\t\t\t\tgetVisOption(browserContext),\n\t\t\t\t\t'comparisonMethod',\n\t\t\t\t\t'diffOptions',\n\t\t\t\t\t'failureThreshold',\n\t\t\t\t\t'failureThresholdType',\n\t\t\t\t\t'timeout',\n\t\t\t\t),\n\t\t\t\tbaselinePath,\n\t\t\t\tresultPath,\n\t\t\t\tdiffPath,\n\t\t\t}\n\t\t},\n\n\t\tasync getTaskCount(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\treturn (await context.getSuiteInfo(browserContext, taskId)).task.count\n\t\t},\n\t\tasync hasImageSnapshot(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\ttaskId: string,\n\t\t\tsnapshotKey: string | undefined,\n\t\t) {\n\t\t\tconst info = await context.getSuiteInfo(browserContext, taskId)\n\t\t\tconst visOptions = getVisOption(browserContext)\n\t\t\tconst legacyFilename = getLegacySnapshotFilename({\n\t\t\t\ttaskId: info.taskId,\n\t\t\t\texplicitSnapshotKey: snapshotKey,\n\t\t\t\tdefaultSnapshotKey: typeof visOptions.snapshotKey === 'string' ? visOptions.snapshotKey : undefined,\n\t\t\t\ttaskCount: info.task.count,\n\t\t\t})\n\t\t\tconst filename = resolveLegacySnapshotFileRelativePath({\n\t\t\t\tprojectRoot: info.projectRoot,\n\t\t\t\tbaselineDir: info.baselineDir,\n\t\t\t\tlegacySnapshotFilename: legacyFilename,\n\t\t\t\tshortenLongSnapshotPaths: visOptions.shortenLongSnapshotPaths === true,\n\t\t\t})\n\t\t\tconst legacyAbs = absoluteSnapshotFilePath(info.projectRoot, info.baselineDir, filename)\n\t\t\treturn file.existFile(legacyAbs)\n\t\t},\n\t\tgetSnapshotFilename(\n\t\t\tbrowserContext: ExtendedBrowserCommandContext,\n\t\t\tinfo: { taskId: string; task: { count: number }; suiteId: string; baselineDir: string; projectRoot: string },\n\t\t\tsnapshotKey: string | undefined,\n\t\t) {\n\t\t\tconst visOptions = getVisOption(browserContext)\n\t\t\tconst legacyFilename = getLegacySnapshotFilename({\n\t\t\t\ttaskId: info.taskId,\n\t\t\t\texplicitSnapshotKey: snapshotKey,\n\t\t\t\tdefaultSnapshotKey: typeof visOptions.snapshotKey === 'string' ? visOptions.snapshotKey : undefined,\n\t\t\t\ttaskCount: info.task.count,\n\t\t\t})\n\t\t\treturn resolveLegacySnapshotFileRelativePath({\n\t\t\t\tprojectRoot: info.projectRoot,\n\t\t\t\tbaselineDir: info.baselineDir,\n\t\t\t\tlegacySnapshotFilename: legacyFilename,\n\t\t\t\tshortenLongSnapshotPaths: visOptions.shortenLongSnapshotPaths === true,\n\t\t\t})\n\t\t},\n\t\tasync getSuiteInfo(browserContext: ExtendedBrowserCommandContext, taskId: string) {\n\t\t\tconst projectState = await getSuite(browserContext)\n\t\t\tconst visOptions = getVisOption(browserContext)\n\t\t\tconst moduleId = getTaskSubpath(projectState, browserContext.testPath, visOptions)\n\t\t\tconst m = projectState.modules[moduleId]!\n\t\t\tconst task = (m.tasks[taskId] = m.tasks[taskId] ?? { count: 1 })\n\t\t\treturn {\n\t\t\t\tprojectRoot: projectState.projectRoot,\n\t\t\t\tsuiteId: moduleId,\n\t\t\t\ttaskId,\n\t\t\t\tbaselineDir: m.baselineDir,\n\t\t\t\tresultDir: m.resultDir,\n\t\t\t\tdiffDir: m.diffDir,\n\t\t\t\ttask,\n\t\t\t}\n\t\t},\n\t}\n\treturn context\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,yBAAyB;CACxC,MAAM,UAAU;EACf,MAAM,mBAAmB,gBAA+C,QAAgB;GACvF,MAAM,YAAY,MAAM,QAAQ,aAAa,gBAAgB,OAAO;GAGpE,MAAM,gBAAgB,KAFT,QAAQ,UAAU,aAAa,UAAU,YAAY,EAEjC,GAAG,UAAU,OAAO,QAAQ;GAC7D,MAAM,YAAY,MAAM,KAAK,KAAK,cAAc;GAEhD,MAAM,gBAAgB,KAAK,QAAQ,UAAU,aAAa,UAAU,UAAU,EAAE,GAAG,UAAU,OAAO,QAAQ;GAC5G,MAAM,UAAU,MAAM,KAAK,KAAK,cAAc;GAE9C,MAAM,cAAc,KAAK,QAAQ,UAAU,aAAa,UAAU,QAAQ,EAAE,GAAG,UAAU,OAAO,QAAQ;GACxG,MAAM,QAAQ,MAAM,KAAK,KAAK,YAAY;GAE1C,MAAM,IAA2B,EAAE;AACnC,SAAM,QAAQ,IACb,UAAU,IAAI,OAAO,iBAAiB;IACrC,MAAM,WAAW,SAAS,aAAa;IACvC,MAAM,aAAa,QAAQ,MAAM,MAAM,EAAE,SAAS,SAAS,CAAC;IAC5D,MAAM,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,CAAC;IAExD,MAAM,iBAAiB,MAAM,KAAK,YAAY,aAAa;IAC3D,MAAM,eAAe,MAAM,KAAK,YAAY,WAAW;IACvD,MAAM,aAAa,MAAM,KAAK,YAAY,SAAS;AACnD,MAAE,KAAK;KACN;KACA,UAAU,gBAAgB,SAAS,SAAS;KAC5C,QAAQ,cAAc,SAAS,SAAS;KACxC,MAAM,YAAY,SAAS,SAAS;KACpC,CAAC;KACD,CACF;AACD,UAAO;;EAER,MAAM,gBACL,gBACA,QACA,SACC;GACD,MAAM,YAAY,MAAM,QAAQ,aAAa,gBAAgB,OAAO;GACpE,MAAM,mBAAmB,QAAQ,oBAAoB,gBAAgB,WAAW,SAAS,YAAY;GAErG,MAAM,EAAE,aAAa,WAAW,SAAS,SAAS;AAElD,QAAK,SAAS;GACd,MAAM,eAAe,KAAK,aAAa,iBAAiB;GACxD,MAAM,aAAa,KAAK,WAAW,iBAAiB;GACpD,MAAM,WAAW,KAAK,SAAS,iBAAiB;AAEhD,UAAO;IACN,GAAG,KACF,aAAa,eAAe,EAC5B,oBACA,eACA,oBACA,wBACA,UACA;IACD;IACA;IACA;IACA;;EAGF,MAAM,aAAa,gBAA+C,QAAgB;AACjF,WAAQ,MAAM,QAAQ,aAAa,gBAAgB,OAAO,EAAE,KAAK;;EAElE,MAAM,iBACL,gBACA,QACA,aACC;GACD,MAAM,OAAO,MAAM,QAAQ,aAAa,gBAAgB,OAAO;GAC/D,MAAM,aAAa,aAAa,eAAe;GAC/C,MAAM,iBAAiB,0BAA0B;IAChD,QAAQ,KAAK;IACb,qBAAqB;IACrB,oBAAoB,OAAO,WAAW,gBAAgB,WAAW,WAAW,cAAc;IAC1F,WAAW,KAAK,KAAK;IACrB,CAAC;GACF,MAAM,WAAW,sCAAsC;IACtD,aAAa,KAAK;IAClB,aAAa,KAAK;IAClB,wBAAwB;IACxB,0BAA0B,WAAW,6BAA6B;IAClE,CAAC;GACF,MAAM,YAAY,yBAAyB,KAAK,aAAa,KAAK,aAAa,SAAS;AACxF,UAAO,KAAK,UAAU,UAAU;;EAEjC,oBACC,gBACA,MACA,aACC;GACD,MAAM,aAAa,aAAa,eAAe;GAC/C,MAAM,iBAAiB,0BAA0B;IAChD,QAAQ,KAAK;IACb,qBAAqB;IACrB,oBAAoB,OAAO,WAAW,gBAAgB,WAAW,WAAW,cAAc;IAC1F,WAAW,KAAK,KAAK;IACrB,CAAC;AACF,UAAO,sCAAsC;IAC5C,aAAa,KAAK;IAClB,aAAa,KAAK;IAClB,wBAAwB;IACxB,0BAA0B,WAAW,6BAA6B;IAClE,CAAC;;EAEH,MAAM,aAAa,gBAA+C,QAAgB;GACjF,MAAM,eAAe,MAAM,SAAS,eAAe;GACnD,MAAM,aAAa,aAAa,eAAe;GAC/C,MAAM,WAAW,eAAe,cAAc,eAAe,UAAU,WAAW;GAClF,MAAM,IAAI,aAAa,QAAQ;GAC/B,MAAM,OAAQ,EAAE,MAAM,UAAU,EAAE,MAAM,WAAW,EAAE,OAAO,GAAG;AAC/D,UAAO;IACN,aAAa,aAAa;IAC1B,SAAS;IACT;IACA,aAAa,EAAE;IACf,WAAW,EAAE;IACb,SAAS,EAAE;IACX;IACA;;EAEF;AACD,QAAO"}
@@ -1,2 +1,32 @@
1
- import "../shared/types.mjs";
2
- import "type-plus";
1
+ import { Merge } from "type-plus";
2
+ import { BrowserCommandContext } from "vitest/node";
3
+
4
+ //#region src/server/vis_server_context.types.d.ts
5
+
6
+ type ExtendedBrowserCommandContext = {
7
+ page: BrowserCommandContext['page'];
8
+ browser: BrowserCommandContext['browser'];
9
+ iframe: BrowserCommandContext['iframe'];
10
+ testPath: NonNullable<BrowserCommandContext['testPath']>;
11
+ provider: BrowserCommandContext['provider'];
12
+ project: Merge<BrowserCommandContext['project'], {
13
+ browser: {
14
+ config: {
15
+ browser: {
16
+ name: string;
17
+ screenshotFailures: boolean;
18
+ screenshotDirectory: string;
19
+ };
20
+ };
21
+ };
22
+ config: BrowserCommandContext['project']['config'];
23
+ runner: {
24
+ config: {
25
+ name: string;
26
+ };
27
+ };
28
+ }>;
29
+ };
30
+ //#endregion
31
+ export { ExtendedBrowserCommandContext };
32
+ //# sourceMappingURL=vis_server_context.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_server_context.types.d.mts","names":[],"sources":["../../src/server/vis_server_context.types.ts"],"sourcesContent":[],"mappings":";;;;;KAuCY,6BAAA;QACL;WACG;UACD;YACE,YAAY;YACZ;WAED,MACR;;;;;;;;;;YAWS"}
@@ -1,5 +1,4 @@
1
- import { SnapshotMeta } from "../auto_snapshots/snapshot_meta.mjs";
2
- import { ComparisonMethod, SetupVisOptions } from "../shared/types.mjs";
1
+ import { SetupVisOptions } from "../shared/types.mjs";
3
2
  import { SetupVisSuiteCommand } from "../shared/commands.types.mjs";
4
3
 
5
4
  //#region src/setup/create_vis.d.ts
@@ -37,70 +36,6 @@ type VisClientConfigurator<GM extends Record<string, any> | unknown = unknown> =
37
36
  * ```
38
37
  */
39
38
  setup(options?: SetupVisOptions<GM>): void;
40
- /**
41
- * @deprecated Use `vis.setup()` instead.
42
- */
43
- presets: {
44
- /**
45
- * @deprecated Use `vis.setup()` instead.
46
- *
47
- * Enable visual testing.
48
- *
49
- * auto snapshot is turned off by default.
50
- * You can specify the test to take a snapshot during `afterEach()` hook with `setAutoSnapshotOptions()`.
51
- */
52
- enable(): void;
53
- /**
54
- * @deprecated Use `vis.setup()` instead.
55
- *
56
- * Enable visual testing.
57
- *
58
- * `setAutoSnapshotOptions` will have no effect in this preset.
59
- */
60
- manual(): void;
61
- /**
62
- * @deprecated Use `vis.setup()` instead.
63
- *
64
- * Enable automatic visual testing.
65
- *
66
- * This will take a snapshot after each test.
67
- */
68
- auto(): void;
69
- /**
70
- * @deprecated Use `vis.setup()` instead.
71
- *
72
- * Enable automatic visual testing with multiple themes.
73
- *
74
- * This will take a snapshot after each test for each theme.
75
- *
76
- * @param themes A record of theme names and their setup functions.
77
- *
78
- * @example
79
- * ```ts
80
- * vis().presets.theme({
81
- * light() { document.body.classList.add('light') },
82
- * dark() { document.body.classList.add('dark') },
83
- * })
84
- * ```
85
- */
86
- theme<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(themes: Record<string, boolean | ((options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)>): void;
87
- };
88
- beforeAll: {
89
- /**
90
- * @deprecated No known use case.
91
- */
92
- setup(): Promise<void>;
93
- };
94
- afterEach: {
95
- /**
96
- * @deprecated No known use case.
97
- */
98
- matchImageSnapshot(): Promise<void>;
99
- /**
100
- * @deprecated No known use case.
101
- */
102
- matchPerTheme<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(themes: Record<string, boolean | ((options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)>): () => Promise<void>;
103
- };
104
39
  };
105
40
  declare function createVis<GM extends Record<string, any> | unknown = unknown>(commands: SetupVisSuiteCommand): VisClientConfigurator<GM>;
106
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"create_vis.d.mts","names":[],"sources":["../../src/setup/create_vis.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUA;AAA6C,KAAjC,qBAAiC,CAAA,WAAA,MAAA,CAAA,MAAA,EAAA,GAAA,CAAA,GAAA,OAAA,GAAA,OAAA,CAAA,GAAA;EA6BZ;;;;;;;;;;;;;;;;;;;;;;;;AA6EjC;;;;EAA4G,KAAA,CAAA,OAAA,CAAA,EA7E3F,eA6E2F,CA7E3E,EA6E2E,CAAA,CAAA,EAAA,IAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA9B1F,4BAA4B,iDACnC,oCAEc,aAAa,KAAK,IAAI,OAAO,mBAAmB;;;;;;aAQ9D;;;;;;0BAMa;;;;4BAIE,4BAA4B,iDAC3C,oCAEc,aAAa,KAAK,IAAI,OAAO,mBAAmB,yCAE9D;;;iBAIK,qBAAqB,mDAAmD,uBAAoB,sBAAA"}
1
+ {"version":3,"file":"create_vis.d.mts","names":[],"sources":["../../src/setup/create_vis.ts"],"sourcesContent":[],"mappings":";;;;;;;AASA;AAA6C,KAAjC,qBAAiC,CAAA,WAAA,MAAA,CAAA,MAAA,EAAA,GAAA,CAAA,GAAA,OAAA,GAAA,OAAA,CAAA,GAAA;EA6BZ;;;AAGjC;;;;;;;;;;;;;;;;;;;;;;;;;kBAHiB,gBAAgB;;iBAGjB,qBAAqB,mDAAmD,uBAAoB,sBAAA"}
@@ -5,52 +5,16 @@ import { afterEach, beforeAll, expect } from "vitest";
5
5
  //#region src/setup/create_vis.ts
6
6
  function createVis(commands) {
7
7
  const matcher = autoSnapshotMatcher(commands, expect);
8
- return {
9
- setup(options) {
10
- if (!options || options.auto === false) beforeAll(matcher.setup);
11
- else beforeAll(async () => {
12
- await matcher.setup();
13
- setAutoSnapshotOptions(true);
14
- });
15
- if (typeof options?.auto === "function") afterEach(matcher.createMatcher({ auto: options.auto }));
16
- else if (typeof options?.auto === "object") afterEach(matcher.createMatcher(options.auto));
17
- else afterEach(matcher.createMatcher({ async auto() {} }));
18
- },
19
- presets: {
20
- enable() {
21
- beforeAll(matcher.setup);
22
- afterEach(matcher.createMatcher({ async auto() {} }));
23
- },
24
- manual() {
25
- beforeAll(matcher.setup);
26
- },
27
- auto() {
28
- beforeAll(async () => {
29
- await matcher.setup();
30
- setAutoSnapshotOptions(true);
31
- });
32
- afterEach(matcher.createMatcher({ async auto() {} }));
33
- },
34
- theme(themes) {
35
- beforeAll(async () => {
36
- await matcher.setup();
37
- setAutoSnapshotOptions(true);
38
- });
39
- afterEach(matcher.createMatcher(themes));
40
- }
41
- },
42
- beforeAll: { async setup() {
8
+ return { setup(options) {
9
+ const suiteDefaults = options?.createMissingBaseline !== void 0 ? { createMissingBaseline: options.createMissingBaseline } : void 0;
10
+ beforeAll(async () => {
43
11
  await matcher.setup();
44
- } },
45
- afterEach: {
46
- async matchImageSnapshot() {
47
- return matcher.createMatcher({ async auto() {} })();
48
- },
49
- matchPerTheme(themes) {
50
- return matcher.createMatcher(themes);
51
- }
52
- }
53
- };
12
+ setAutoSnapshotOptions(!!options?.auto);
13
+ });
14
+ if (typeof options?.auto === "function") afterEach(matcher.createMatcher({ auto: options.auto }, suiteDefaults));
15
+ else if (typeof options?.auto === "object") afterEach(matcher.createMatcher(options.auto, suiteDefaults));
16
+ else afterEach(matcher.createMatcher({ async auto() {} }, suiteDefaults));
17
+ } };
54
18
  }
55
19
 
56
20
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"create_vis.mjs","names":[],"sources":["../../src/setup/create_vis.ts"],"sourcesContent":["import { afterEach, beforeAll, expect } from 'vitest'\nimport { setAutoSnapshotOptions } from '../auto_snapshots/auto_snapshot_options.ts'\nimport type { SnapshotMeta } from '../auto_snapshots/snapshot_meta.ts'\nimport { autoSnapshotMatcher } from '../client/suite/auto_snapshot_matcher.ts'\nimport type { SetupVisSuiteCommand } from '../shared/commands.types.ts'\nimport type { ComparisonMethod, SetupVisOptions } from '../shared/types.ts'\n\n/**\n * Visual test configuration on the client side.\n */\nexport type VisClientConfigurator<GM extends Record<string, any> | unknown = unknown> = {\n\t/**\n\t * Setup the visual test configuration.\n\t *\n\t * @example\n\t * ```ts\n\t * // Setup with auto snapshot enabled\n\t * vis().setup({ auto: true })\n\t *\n\t * // Setup with auto snapshot disabled\n\t * vis().setup({ auto: false })\n\t *\n\t * // Same as `vis.setup({ auto: false })`\n\t * vis.setup()\n\t *\n\t * // Setup with auto snapshot determined by the test meta\n\t * vis.setup({\n\t * \tauto: async ({ meta }) => meta['darkOnly'],\n\t * })\n\t *\n\t * // Setup with multiple auto snapshots\n\t * vis.setup({\n\t * auto: {\n\t * async light() { document.body.classList.remove('dark') },\n\t * async dark() { document.body.classList.add('dark') },\n\t * }\n\t * })\n\t * ```\n\t */\n\tsetup(options?: SetupVisOptions<GM>): void\n\t/**\n\t * @deprecated Use `vis.setup()` instead.\n\t */\n\tpresets: {\n\t\t/**\n\t\t * @deprecated Use `vis.setup()` instead.\n\t\t *\n\t\t * Enable visual testing.\n\t\t *\n\t\t * auto snapshot is turned off by default.\n\t\t * You can specify the test to take a snapshot during `afterEach()` hook with `setAutoSnapshotOptions()`.\n\t\t */\n\t\tenable(): void\n\t\t/**\n\t\t * @deprecated Use `vis.setup()` instead.\n\t\t *\n\t\t * Enable visual testing.\n\t\t *\n\t\t * `setAutoSnapshotOptions` will have no effect in this preset.\n\t\t */\n\t\tmanual(): void\n\t\t/**\n\t\t * @deprecated Use `vis.setup()` instead.\n\t\t *\n\t\t * Enable automatic visual testing.\n\t\t *\n\t\t * This will take a snapshot after each test.\n\t\t */\n\t\tauto(): void\n\t\t/**\n\t\t * @deprecated Use `vis.setup()` instead.\n\t\t *\n\t\t * Enable automatic visual testing with multiple themes.\n\t\t *\n\t\t * This will take a snapshot after each test for each theme.\n\t\t *\n\t\t * @param themes A record of theme names and their setup functions.\n\t\t *\n\t\t * @example\n\t\t * ```ts\n\t\t * vis().presets.theme({\n\t\t * light() { document.body.classList.add('light') },\n\t\t * dark() { document.body.classList.add('dark') },\n\t\t * })\n\t\t * ```\n\t\t */\n\t\ttheme<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(\n\t\t\tthemes: Record<\n\t\t\t\tstring,\n\t\t\t\tboolean | ((options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)\n\t\t\t>,\n\t\t): void\n\t}\n\tbeforeAll: {\n\t\t/**\n\t\t * @deprecated No known use case.\n\t\t */\n\t\tsetup(): Promise<void>\n\t}\n\tafterEach: {\n\t\t/**\n\t\t * @deprecated No known use case.\n\t\t */\n\t\tmatchImageSnapshot(): Promise<void>\n\t\t/**\n\t\t * @deprecated No known use case.\n\t\t */\n\t\tmatchPerTheme<C extends ComparisonMethod, M extends Record<string, any> | unknown = unknown>(\n\t\t\tthemes: Record<\n\t\t\t\tstring,\n\t\t\t\tboolean | ((options: SnapshotMeta<C> & M & GM) => Promise<boolean> | Promise<void> | boolean | void)\n\t\t\t>,\n\t\t): () => Promise<void>\n\t}\n}\n\nexport function createVis<GM extends Record<string, any> | unknown = unknown>(commands: SetupVisSuiteCommand) {\n\tconst matcher = autoSnapshotMatcher(commands, expect)\n\n\tconst vis: VisClientConfigurator<GM> = {\n\t\tsetup(options) {\n\t\t\tif (!options || options.auto === false) {\n\t\t\t\tbeforeAll(matcher.setup)\n\t\t\t} else {\n\t\t\t\tbeforeAll(async () => {\n\t\t\t\t\tawait matcher.setup()\n\t\t\t\t\tsetAutoSnapshotOptions(true)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tafterEach(matcher.createMatcher({ auto: options.auto }))\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tafterEach(matcher.createMatcher(options.auto))\n\t\t\t} else {\n\t\t\t\tafterEach(matcher.createMatcher({ async auto() {} }))\n\t\t\t}\n\t\t},\n\t\tpresets: {\n\t\t\tenable() {\n\t\t\t\tbeforeAll(matcher.setup)\n\t\t\t\tafterEach(matcher.createMatcher({ async auto() {} }))\n\t\t\t},\n\t\t\tmanual() {\n\t\t\t\tbeforeAll(matcher.setup)\n\t\t\t},\n\t\t\tauto() {\n\t\t\t\tbeforeAll(async () => {\n\t\t\t\t\tawait matcher.setup()\n\t\t\t\t\tsetAutoSnapshotOptions(true)\n\t\t\t\t})\n\t\t\t\tafterEach(matcher.createMatcher({ async auto() {} }))\n\t\t\t},\n\t\t\ttheme(themes) {\n\t\t\t\tbeforeAll(async () => {\n\t\t\t\t\tawait matcher.setup()\n\t\t\t\t\tsetAutoSnapshotOptions(true)\n\t\t\t\t})\n\t\t\t\tafterEach(matcher.createMatcher(themes))\n\t\t\t},\n\t\t},\n\t\tbeforeAll: {\n\t\t\tasync setup() {\n\t\t\t\tawait matcher.setup()\n\t\t\t},\n\t\t},\n\t\tafterEach: {\n\t\t\tasync matchImageSnapshot() {\n\t\t\t\treturn matcher.createMatcher({ async auto() {} })()\n\t\t\t},\n\t\t\tmatchPerTheme(themes) {\n\t\t\t\treturn matcher.createMatcher(themes)\n\t\t\t},\n\t\t},\n\t}\n\treturn vis\n}\n"],"mappings":";;;;;AAoHA,SAAgB,UAA8D,UAAgC;CAC7G,MAAM,UAAU,oBAAoB,UAAU,OAAO;AA0DrD,QAxDuC;EACtC,MAAM,SAAS;AACd,OAAI,CAAC,WAAW,QAAQ,SAAS,MAChC,WAAU,QAAQ,MAAM;OAExB,WAAU,YAAY;AACrB,UAAM,QAAQ,OAAO;AACrB,2BAAuB,KAAK;KAC3B;AAGH,OAAI,OAAO,SAAS,SAAS,WAC5B,WAAU,QAAQ,cAAc,EAAE,MAAM,QAAQ,MAAM,CAAC,CAAC;YAC9C,OAAO,SAAS,SAAS,SACnC,WAAU,QAAQ,cAAc,QAAQ,KAAK,CAAC;OAE9C,WAAU,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,CAAC,CAAC;;EAGvD,SAAS;GACR,SAAS;AACR,cAAU,QAAQ,MAAM;AACxB,cAAU,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,CAAC,CAAC;;GAEtD,SAAS;AACR,cAAU,QAAQ,MAAM;;GAEzB,OAAO;AACN,cAAU,YAAY;AACrB,WAAM,QAAQ,OAAO;AACrB,4BAAuB,KAAK;MAC3B;AACF,cAAU,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,CAAC,CAAC;;GAEtD,MAAM,QAAQ;AACb,cAAU,YAAY;AACrB,WAAM,QAAQ,OAAO;AACrB,4BAAuB,KAAK;MAC3B;AACF,cAAU,QAAQ,cAAc,OAAO,CAAC;;GAEzC;EACD,WAAW,EACV,MAAM,QAAQ;AACb,SAAM,QAAQ,OAAO;KAEtB;EACD,WAAW;GACV,MAAM,qBAAqB;AAC1B,WAAO,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,CAAC,EAAE;;GAEpD,cAAc,QAAQ;AACrB,WAAO,QAAQ,cAAc,OAAO;;GAErC;EACD"}
1
+ {"version":3,"file":"create_vis.mjs","names":[],"sources":["../../src/setup/create_vis.ts"],"sourcesContent":["import { afterEach, beforeAll, expect } from 'vitest'\nimport { setAutoSnapshotOptions } from '../auto_snapshots/auto_snapshot_options.ts'\nimport { autoSnapshotMatcher } from '../client/suite/auto_snapshot_matcher.ts'\nimport type { SetupVisSuiteCommand } from '../shared/commands.types.ts'\nimport type { SetupVisOptions } from '../shared/types.ts'\n\n/**\n * Visual test configuration on the client side.\n */\nexport type VisClientConfigurator<GM extends Record<string, any> | unknown = unknown> = {\n\t/**\n\t * Setup the visual test configuration.\n\t *\n\t * @example\n\t * ```ts\n\t * // Setup with auto snapshot enabled\n\t * vis().setup({ auto: true })\n\t *\n\t * // Setup with auto snapshot disabled\n\t * vis().setup({ auto: false })\n\t *\n\t * // Same as `vis.setup({ auto: false })`\n\t * vis.setup()\n\t *\n\t * // Setup with auto snapshot determined by the test meta\n\t * vis.setup({\n\t * \tauto: async ({ meta }) => meta['darkOnly'],\n\t * })\n\t *\n\t * // Setup with multiple auto snapshots\n\t * vis.setup({\n\t * auto: {\n\t * async light() { document.body.classList.remove('dark') },\n\t * async dark() { document.body.classList.add('dark') },\n\t * }\n\t * })\n\t * ```\n\t */\n\tsetup(options?: SetupVisOptions<GM>): void\n}\n\nexport function createVis<GM extends Record<string, any> | unknown = unknown>(commands: SetupVisSuiteCommand) {\n\tconst matcher = autoSnapshotMatcher(commands, expect)\n\n\tconst vis: VisClientConfigurator<GM> = {\n\t\tsetup(options) {\n\t\t\tconst suiteDefaults =\n\t\t\t\toptions?.createMissingBaseline !== undefined\n\t\t\t\t\t? { createMissingBaseline: options.createMissingBaseline }\n\t\t\t\t\t: undefined\n\n\t\t\tbeforeAll(async () => {\n\t\t\t\tawait matcher.setup()\n\t\t\t\tsetAutoSnapshotOptions(!!options?.auto)\n\t\t\t})\n\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tafterEach(matcher.createMatcher({ auto: options.auto }, suiteDefaults))\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tafterEach(matcher.createMatcher(options.auto, suiteDefaults))\n\t\t\t} else {\n\t\t\t\tafterEach(matcher.createMatcher({ async auto() {} }, suiteDefaults))\n\t\t\t}\n\t\t},\n\t}\n\treturn vis\n}\n"],"mappings":";;;;;AAyCA,SAAgB,UAA8D,UAAgC;CAC7G,MAAM,UAAU,oBAAoB,UAAU,OAAO;AAuBrD,QArBuC,EACtC,MAAM,SAAS;EACd,MAAM,gBACL,SAAS,0BAA0B,SAChC,EAAE,uBAAuB,QAAQ,uBAAuB,GACxD;AAEJ,YAAU,YAAY;AACrB,SAAM,QAAQ,OAAO;AACrB,0BAAuB,CAAC,CAAC,SAAS,KAAK;IACtC;AAEF,MAAI,OAAO,SAAS,SAAS,WAC5B,WAAU,QAAQ,cAAc,EAAE,MAAM,QAAQ,MAAM,EAAE,cAAc,CAAC;WAC7D,OAAO,SAAS,SAAS,SACnC,WAAU,QAAQ,cAAc,QAAQ,MAAM,cAAc,CAAC;MAE7D,WAAU,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,EAAE,cAAc,CAAC;IAGtE"}