@crvy/rprtr 0.0.4 → 0.0.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAI/C,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAChC,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClD,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3D;AA0KD,wBAAsB,eAAe,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CAgCrF"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAI/C,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClD,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3D;AA+KD,wBAAsB,eAAe,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CA4CrF"}
@@ -0,0 +1,9 @@
1
+ export declare function createDebouncedRefresh(reload: () => Promise<void>, delayMs?: number): () => void;
2
+ interface ReportWatchOptions {
3
+ offlineReportDir: string;
4
+ screenshotDir: string;
5
+ scheduleRefresh: () => void;
6
+ }
7
+ export declare function watchReportArtifacts(options: ReportWatchOptions): Promise<() => void>;
8
+ export {};
9
+ //# sourceMappingURL=report-watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-watch.d.ts","sourceRoot":"","sources":["../../src/server/report-watch.ts"],"names":[],"mappings":"AAOA,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,SAAK,GAAG,MAAM,IAAI,CAa5F;AAED,UAAU,kBAAkB;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,IAAI,CAAA;CAC5B;AAsFD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAgC3F"}
package/dist/server.cjs CHANGED
@@ -35,7 +35,7 @@ __export(server_exports, {
35
35
  module.exports = __toCommonJS(server_exports);
36
36
 
37
37
  // src/server/app.ts
38
- var import_path4 = require("path");
38
+ var import_path5 = require("path");
39
39
  var import_url = require("url");
40
40
  var import_p_limit = __toESM(require("p-limit"), 1);
41
41
 
@@ -47,6 +47,30 @@ var import_path = require("path");
47
47
  function normalizeScreenshotsBaseUrl(baseUrl) {
48
48
  return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
49
49
  }
50
+ function classifyImage(image) {
51
+ if (image.actual !== void 0 || image.diff !== void 0) {
52
+ return "comparison";
53
+ }
54
+ if (image.expect !== void 0) {
55
+ return "baseline-only";
56
+ }
57
+ return "declared-only";
58
+ }
59
+ function withImageSource(image) {
60
+ return {
61
+ ...image,
62
+ source: classifyImage(image)
63
+ };
64
+ }
65
+ function mergeDeclaredImages(images, visualNames) {
66
+ const names = /* @__PURE__ */ new Set([...Object.keys(images), ...visualNames]);
67
+ return Object.fromEntries(
68
+ Array.from(names, (name) => {
69
+ const current = images[name] ?? {};
70
+ return [name, withImageSource(current)];
71
+ })
72
+ );
73
+ }
50
74
  function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/") {
51
75
  const images = {};
52
76
  const baseUrl = normalizeScreenshotsBaseUrl(screenshotsBaseUrl);
@@ -57,7 +81,7 @@ function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/")
57
81
  const baseName = match[1];
58
82
  const role = match[2];
59
83
  if (baseName === null || baseName === void 0 || role === null || role === void 0) continue;
60
- images[baseName] ??= { actual: "" };
84
+ images[baseName] ??= {};
61
85
  const url = `${baseUrl}${attachment.path}`;
62
86
  const img = images[baseName];
63
87
  if (img !== null && img !== void 0) {
@@ -68,10 +92,11 @@ function attachmentsToImages(attachments, screenshotsBaseUrl = "/screenshots/")
68
92
  }
69
93
  for (const key of Object.keys(images)) {
70
94
  const img = images[key];
71
- if (img?.actual !== null && img?.actual !== void 0 && img?.expect !== null && img?.expect !== void 0 && img?.diff === void 0)
95
+ if (img?.actual !== void 0 && img?.expect !== void 0 && img?.diff === void 0) {
72
96
  delete img.expect;
97
+ }
73
98
  }
74
- return images;
99
+ return mergeDeclaredImages(images, []);
75
100
  }
76
101
  function mapStatus(status) {
77
102
  switch (status) {
@@ -87,17 +112,39 @@ function mapStatus(status) {
87
112
  }
88
113
 
89
114
  // src/report-state.ts
90
- function hasReviewablePassingImages(images) {
91
- return Object.values(images).some(
92
- (img) => img !== null && img !== void 0 && img.actual !== null && img.actual !== void 0 && img.diff === void 0
93
- );
115
+ function isCurrentArtifact(image) {
116
+ return image?.actual !== void 0 || image?.expect !== void 0 || image?.diff !== void 0;
117
+ }
118
+ function isReusablePassingImage(image) {
119
+ const source = image.source ?? classifyImage(image);
120
+ if (source === "comparison") {
121
+ return image.actual !== void 0 && image.diff === void 0;
122
+ }
123
+ return source === "baseline-only";
124
+ }
125
+ function hasReusablePassingImages(images) {
126
+ return Object.values(images).some((img) => img !== null && img !== void 0 && isReusablePassingImage(img));
94
127
  }
95
128
  function preservePreviousPassingImages(test, status, images) {
96
- if (status !== "passed" || Object.keys(images).length > 0) {
129
+ if (status !== "passed") {
97
130
  return images;
98
131
  }
99
132
  const previousImages = test.results?.[0]?.images ?? {};
100
- return hasReviewablePassingImages(previousImages) ? previousImages : images;
133
+ if (!hasReusablePassingImages(previousImages)) {
134
+ return images;
135
+ }
136
+ return Object.entries(previousImages).reduce((currentImages, [name, previousImage]) => {
137
+ if (!Object.hasOwn(currentImages, name) || previousImage === void 0 || !isReusablePassingImage(previousImage) || isCurrentArtifact(currentImages[name])) {
138
+ return currentImages;
139
+ }
140
+ return {
141
+ ...currentImages,
142
+ [name]: {
143
+ ...previousImage,
144
+ source: previousImage.source ?? classifyImage(previousImage)
145
+ }
146
+ };
147
+ }, images);
101
148
  }
102
149
  function countDiffImages(images) {
103
150
  return Object.values(images).filter((img) => img?.diff !== null && img?.diff !== void 0).length;
@@ -133,10 +180,11 @@ function applyTestEndEvent(state, data, options = {}) {
133
180
  return null;
134
181
  }
135
182
  test.status = mapStatus(data.status);
183
+ const resultStatus = data.status === "passed" ? "success" : data.status === "failed" ? "failed" : "pending";
136
184
  const images = preservePreviousPassingImages(
137
185
  test,
138
186
  data.status,
139
- attachmentsToImages(data.attachments, options.screenshotsBaseUrl)
187
+ mergeDeclaredImages(attachmentsToImages(data.attachments, options.screenshotsBaseUrl), data.visualNames)
140
188
  );
141
189
  const diffCount = countDiffImages(images);
142
190
  const hasDiffs = diffCount > 0;
@@ -145,7 +193,7 @@ function applyTestEndEvent(state, data, options = {}) {
145
193
  }
146
194
  test.results = [
147
195
  {
148
- status: data.status === "passed" ? "success" : "failed",
196
+ status: resultStatus,
149
197
  retries: 0,
150
198
  images,
151
199
  error: data.error,
@@ -177,11 +225,13 @@ var LocationSchema = import_zod.z.object({
177
225
  file: import_zod.z.string(),
178
226
  line: import_zod.z.number()
179
227
  });
228
+ var VisualSourceSchema = import_zod.z.enum(["comparison", "baseline-only", "declared-only"]);
180
229
  var ImagesSchema = import_zod.z.object({
181
- actual: import_zod.z.string(),
230
+ actual: import_zod.z.string().optional(),
182
231
  expect: import_zod.z.string().optional(),
183
232
  diff: import_zod.z.string().optional(),
184
- error: import_zod.z.string().optional()
233
+ error: import_zod.z.string().optional(),
234
+ source: VisualSourceSchema.optional()
185
235
  });
186
236
  var AttachmentSchema = import_zod.z.object({
187
237
  name: import_zod.z.string(),
@@ -189,10 +239,10 @@ var AttachmentSchema = import_zod.z.object({
189
239
  contentType: import_zod.z.string()
190
240
  });
191
241
  var TestStatusSchema = import_zod.z.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
242
+ var TestResultStatusSchema = import_zod.z.enum(["failed", "success", "pending"]);
192
243
  var TestResultSchema = import_zod.z.object({
193
- status: import_zod.z.enum(["failed", "success"]),
244
+ status: TestResultStatusSchema,
194
245
  retries: import_zod.z.number(),
195
- // eslint-disable-next-line typescript/no-unsafe-type-assertion
196
246
  images: import_zod.z.record(import_zod.z.string(), ImagesSchema).optional(),
197
247
  error: import_zod.z.string().optional(),
198
248
  duration: import_zod.z.number().optional()
@@ -221,7 +271,6 @@ var CrvyRprtrSuiteSchema = import_zod.z.lazy(
221
271
  opened: import_zod.z.boolean(),
222
272
  checked: import_zod.z.boolean(),
223
273
  indeterminate: import_zod.z.boolean(),
224
- // eslint-disable-next-line typescript/no-unsafe-type-assertion
225
274
  children: import_zod.z.record(import_zod.z.string(), import_zod.z.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
226
275
  })
227
276
  );
@@ -240,6 +289,7 @@ var TestEndDataSchema = import_zod.z.object({
240
289
  id: import_zod.z.string(),
241
290
  status: import_zod.z.enum(["passed", "failed", "skipped"]),
242
291
  attachments: import_zod.z.array(AttachmentSchema),
292
+ visualNames: import_zod.z.array(import_zod.z.string()).default([]),
243
293
  error: import_zod.z.string().optional(),
244
294
  duration: import_zod.z.number().optional()
245
295
  });
@@ -480,14 +530,122 @@ function handleSync(ctx) {
480
530
  broadcastToBrowsers(ctx.wsClients, { type: "sync", data: ctx.reportData });
481
531
  }
482
532
 
483
- // src/server/routes.ts
533
+ // src/server/report-watch.ts
534
+ var import_promises3 = require("fs/promises");
484
535
  var import_path3 = require("path");
536
+ var OFFLINE_REPORT_FILE_PATTERN2 = /^crvy-rprtr(?:-\d+)?\.json$/;
537
+ function createDebouncedRefresh(reload, delayMs = 50) {
538
+ let timer = null;
539
+ return () => {
540
+ if (timer !== null) {
541
+ clearTimeout(timer);
542
+ }
543
+ timer = setTimeout(() => {
544
+ timer = null;
545
+ void reload();
546
+ }, delayMs);
547
+ };
548
+ }
549
+ function isFileNotFound2(error) {
550
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
551
+ }
552
+ async function describeFile(filePath, label) {
553
+ try {
554
+ const fileStats = await (0, import_promises3.stat)(filePath);
555
+ return `${label}:${fileStats.size}:${fileStats.mtimeMs}`;
556
+ } catch (error) {
557
+ if (isFileNotFound2(error)) {
558
+ return null;
559
+ }
560
+ throw error;
561
+ }
562
+ }
563
+ async function createOfflineFingerprint(offlineReportDir) {
564
+ if (!await isDirectory(offlineReportDir)) {
565
+ return "offline:missing";
566
+ }
567
+ try {
568
+ const entries = await (0, import_promises3.readdir)(offlineReportDir, { withFileTypes: true });
569
+ const relevantEntries = entries.filter(
570
+ (entry) => entry.isFile() && (entry.name === "report.json" || OFFLINE_REPORT_FILE_PATTERN2.test(entry.name))
571
+ ).sort((left, right) => left.name.localeCompare(right.name));
572
+ const parts = await Promise.all(
573
+ relevantEntries.map((entry) => describeFile((0, import_path3.join)(offlineReportDir, entry.name), entry.name))
574
+ );
575
+ return `offline:${parts.filter((part) => part !== null).join("|")}`;
576
+ } catch (error) {
577
+ const errorMsg = error instanceof Error ? error.message : String(error);
578
+ console.warn(`[Server] Unable to scan ${offlineReportDir}: ${errorMsg}`);
579
+ return "offline:error";
580
+ }
581
+ }
582
+ async function createScreenshotFingerprint(screenshotDir, relativePath = "") {
583
+ const directoryPath = relativePath === "" ? screenshotDir : (0, import_path3.join)(screenshotDir, relativePath);
584
+ if (!await isDirectory(directoryPath)) {
585
+ return relativePath === "" ? ["screenshots:missing"] : [];
586
+ }
587
+ try {
588
+ const entries = await (0, import_promises3.readdir)(directoryPath, { withFileTypes: true });
589
+ const parts = await Promise.all(
590
+ entries.sort((left, right) => left.name.localeCompare(right.name)).map((entry) => {
591
+ const entryRelativePath = relativePath === "" ? entry.name : (0, import_path3.join)(relativePath, entry.name);
592
+ if (entry.isDirectory()) {
593
+ return createScreenshotFingerprint(screenshotDir, entryRelativePath);
594
+ }
595
+ return describeFile((0, import_path3.join)(screenshotDir, entryRelativePath), entryRelativePath);
596
+ })
597
+ );
598
+ return parts.flat().filter((part) => part !== null);
599
+ } catch (error) {
600
+ if (isFileNotFound2(error)) {
601
+ return relativePath === "" ? ["screenshots:missing"] : [];
602
+ }
603
+ const errorMsg = error instanceof Error ? error.message : String(error);
604
+ console.warn(`[Server] Unable to scan ${directoryPath}: ${errorMsg}`);
605
+ return relativePath === "" ? ["screenshots:error"] : [];
606
+ }
607
+ }
608
+ async function createArtifactsFingerprint(options) {
609
+ const [offlineFingerprint, screenshotFingerprint] = await Promise.all([
610
+ createOfflineFingerprint(options.offlineReportDir),
611
+ createScreenshotFingerprint(options.screenshotDir)
612
+ ]);
613
+ return `${offlineFingerprint}::${screenshotFingerprint.join("|")}`;
614
+ }
615
+ async function watchReportArtifacts(options) {
616
+ let fingerprint = await createArtifactsFingerprint(options);
617
+ let isPolling = false;
618
+ const interval = setInterval(() => {
619
+ if (isPolling) {
620
+ return;
621
+ }
622
+ isPolling = true;
623
+ void createArtifactsFingerprint(options).then((nextFingerprint) => {
624
+ if (nextFingerprint === fingerprint) {
625
+ return;
626
+ }
627
+ fingerprint = nextFingerprint;
628
+ options.scheduleRefresh();
629
+ }).catch((error) => {
630
+ const errorMsg = error instanceof Error ? error.message : String(error);
631
+ console.warn(`[Server] Artifact refresh poll failed: ${errorMsg}`);
632
+ }).finally(() => {
633
+ isPolling = false;
634
+ });
635
+ }, 100);
636
+ return () => {
637
+ clearInterval(interval);
638
+ };
639
+ }
640
+
641
+ // src/server/routes.ts
642
+ var import_path4 = require("path");
485
643
  var LIVE_UPDATES_WEBSOCKET_PATH = "/";
486
644
  function isWebSocketUpgradeRequest(req) {
487
645
  return new URL(req.url).pathname === LIVE_UPDATES_WEBSOCKET_PATH && req.headers.get("upgrade")?.toLowerCase() === "websocket";
488
646
  }
489
647
  async function handleRoot(ctx) {
490
- const html = await respondWithFile((0, import_path3.join)(ctx.staticDir, "index.html"), "text/html");
648
+ const html = await respondWithFile((0, import_path4.join)(ctx.staticDir, "index.html"), "text/html");
491
649
  return html ?? new Response("Not Found", { status: 404 });
492
650
  }
493
651
  async function handleAppCss() {
@@ -584,7 +742,7 @@ async function handleScreenshots(ctx, req) {
584
742
  }
585
743
  async function handleDist(ctx, req) {
586
744
  const path = new URL(req.url).pathname.slice("/dist/".length);
587
- const filePath = (0, import_path3.join)(ctx.staticDir, path);
745
+ const filePath = (0, import_path4.join)(ctx.staticDir, path);
588
746
  const contentType = filePath.endsWith(".css") ? "text/css" : filePath.endsWith(".js") ? "application/javascript" : filePath.endsWith(".svelte") ? "text/plain" : "application/octet-stream";
589
747
  const file = await respondWithFile(filePath, contentType);
590
748
  return file ?? new Response("Not Found", { status: 404 });
@@ -688,6 +846,10 @@ async function loadOfflineReports(offlineReportDir, reportData) {
688
846
  screenshotsBaseUrl: "/screenshots/"
689
847
  });
690
848
  }
849
+ function resetReloadableReportData(reportData) {
850
+ reportData.tests = {};
851
+ reportData.isUpdateMode = false;
852
+ }
691
853
  async function handleParsedWebSocketMessage(ctx, msg) {
692
854
  switch (msg.type) {
693
855
  case "test-begin": {
@@ -736,19 +898,19 @@ function createWebSocketMessageHandler(getHandlerContext) {
736
898
  };
737
899
  }
738
900
  async function resolveStaticDir(staticDir) {
739
- const currentDir = (0, import_path4.dirname)((0, import_url.fileURLToPath)(import_meta.url));
901
+ const currentDir = (0, import_path5.dirname)((0, import_url.fileURLToPath)(import_meta.url));
740
902
  const candidates = staticDir === void 0 ? [
741
903
  currentDir,
742
- (0, import_path4.join)(currentDir, "dist"),
743
- (0, import_path4.join)(currentDir, "..", "dist"),
744
- (0, import_path4.join)(currentDir, "..", "..", "dist"),
745
- (0, import_path4.join)(currentDir, ".."),
746
- (0, import_path4.join)(currentDir, "..", "..")
747
- ] : [staticDir, (0, import_path4.join)(staticDir, "dist")];
904
+ (0, import_path5.join)(currentDir, "dist"),
905
+ (0, import_path5.join)(currentDir, "..", "dist"),
906
+ (0, import_path5.join)(currentDir, "..", "..", "dist"),
907
+ (0, import_path5.join)(currentDir, ".."),
908
+ (0, import_path5.join)(currentDir, "..", "..")
909
+ ] : [staticDir, (0, import_path5.join)(staticDir, "dist")];
748
910
  const resolvedCandidates = await Promise.all(
749
911
  candidates.map(async (candidate) => ({
750
912
  candidate,
751
- exists: await fileExists((0, import_path4.join)(candidate, "index.html"))
913
+ exists: await fileExists((0, import_path5.join)(candidate, "index.html"))
752
914
  }))
753
915
  );
754
916
  const resolved = resolvedCandidates.find(({ exists }) => exists);
@@ -759,9 +921,9 @@ async function resolveStaticDir(staticDir) {
759
921
  }
760
922
  async function resolveReportPath(reportPath) {
761
923
  if (await isDirectory(reportPath)) {
762
- return { reportFile: (0, import_path4.join)(reportPath, "report.json"), offlineReportDir: reportPath };
924
+ return { reportFile: (0, import_path5.join)(reportPath, "report.json"), offlineReportDir: reportPath };
763
925
  }
764
- return { reportFile: reportPath, offlineReportDir: (0, import_path4.dirname)(reportPath) };
926
+ return { reportFile: reportPath, offlineReportDir: (0, import_path5.dirname)(reportPath) };
765
927
  }
766
928
  async function createServerApp(options = {}) {
767
929
  const port = options.port ?? 3e3;
@@ -782,11 +944,22 @@ async function createServerApp(options = {}) {
782
944
  const getHandlerContext = () => createHandlerContext(reportData, wsClients, currentRunIds, saveReport);
783
945
  const handleRequest = (req) => handleHttpRequest(routesContext, req);
784
946
  const handleWebSocketMessage = createWebSocketMessageHandler(getHandlerContext);
785
- await loadReport(reportFile, reportData);
786
- await loadOfflineReports(offlineReportDir, reportData);
947
+ const reloadFromDisk = async () => {
948
+ resetReloadableReportData(reportData);
949
+ await loadReport(reportFile, reportData);
950
+ await loadOfflineReports(offlineReportDir, reportData);
951
+ broadcastToBrowsers(wsClients, { type: "sync", data: reportData });
952
+ };
953
+ await reloadFromDisk();
954
+ const close = await watchReportArtifacts({
955
+ offlineReportDir,
956
+ screenshotDir: reportData.screenshotDir,
957
+ scheduleRefresh: createDebouncedRefresh(reloadFromDisk)
958
+ });
787
959
  return {
788
960
  port,
789
961
  wsClients,
962
+ close,
790
963
  handleRequest,
791
964
  handleWebSocketMessage
792
965
  };
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startServer
3
- } from "./chunk-BRFA7JCQ.js";
4
- import "./chunk-IEYNAB6M.js";
3
+ } from "./chunk-IH44LYNM.js";
4
+ import "./chunk-MWLM3HWS.js";
5
5
  export {
6
6
  startServer
7
7
  };
package/dist/types.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ export type VisualSource = 'comparison' | 'baseline-only' | 'declared-only';
1
2
  export interface Images {
2
- actual: string;
3
+ actual?: string;
3
4
  expect?: string;
4
5
  diff?: string;
5
6
  error?: string;
7
+ source?: VisualSource;
6
8
  }
7
9
  export interface Attachment {
8
10
  name: string;
@@ -14,8 +16,9 @@ export interface Location {
14
16
  line: number;
15
17
  }
16
18
  export type TestStatus = 'unknown' | 'pending' | 'running' | 'failed' | 'approved' | 'success' | 'retrying';
19
+ export type TestResultStatus = 'failed' | 'success' | 'pending';
17
20
  export interface TestResult {
18
- status: 'failed' | 'success';
21
+ status: TestResultStatus;
19
22
  retries: number;
20
23
  images?: Partial<Record<string, Images>>;
21
24
  error?: string;
@@ -67,6 +70,7 @@ export interface TestEndMessage {
67
70
  id: string;
68
71
  status: 'passed' | 'failed' | 'skipped';
69
72
  attachments: Attachment[];
73
+ visualNames: string[];
70
74
  error?: string;
71
75
  duration?: number;
72
76
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvy/rprtr",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Playwright reporter with visual regression UI for comparing and approving screenshot tests",
5
5
  "keywords": [
6
6
  "crvy",