@crvy/rprtr 0.1.0 → 0.1.2

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2026-06-08
9
+
10
+ ### Added
11
+
12
+ - Reporter sends register message with Playwright config to server
13
+ - Reporter sends register message with Playwright config to server
14
+
15
+ ### Fixed
16
+
17
+ - **check:** Run publint after other checks to avoid race condition with build
18
+
19
+ ### Styling
20
+
21
+ - Reformat long lines
22
+ - Reformat long lines
23
+ ## [0.1.1] - 2026-06-08
24
+
25
+ ### Fixed
26
+
27
+ - Preserve all tests when applying single WebSocket update
8
28
  ## [0.1.0] - 2026-06-08
9
29
 
10
30
  ### Added
@@ -240,7 +240,7 @@ var CrvyRprtrSuiteSchema = z.lazy(
240
240
  })
241
241
  );
242
242
  var IncomingWebSocketMessageSchema = z.object({
243
- type: z.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
243
+ type: z.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
244
244
  data: z.unknown()
245
245
  });
246
246
  var WebSocketMessageSchema = z.discriminatedUnion("type", [
@@ -284,6 +284,12 @@ var TestEndDataSchema = z.object({
284
284
  var RunEndDataSchema = z.object({
285
285
  status: z.enum(["passed", "failed", "skipped"])
286
286
  });
287
+ var RegisterDataSchema = z.object({
288
+ playwrightSnapshotDir: z.string().optional(),
289
+ playwrightTestDir: z.string().optional(),
290
+ playwrightSnapshotPathTemplate: z.string().optional(),
291
+ playwrightToHaveScreenshotPathTemplate: z.string().optional()
292
+ });
287
293
  var ReportDataSchema = z.object({
288
294
  isRunning: z.boolean(),
289
295
  tests: z.record(z.string(), TestDataSchema),
@@ -530,6 +536,7 @@ export {
530
536
  TestBeginDataSchema,
531
537
  TestEndDataSchema,
532
538
  RunEndDataSchema,
539
+ RegisterDataSchema,
533
540
  LoadedReportDataSchema,
534
541
  OfflineReportSchema,
535
542
  ApproveRequestBodySchema,
@@ -3,6 +3,7 @@ import {
3
3
  IncomingWebSocketMessageSchema,
4
4
  LoadedReportDataSchema,
5
5
  OfflineReportSchema,
6
+ RegisterDataSchema,
6
7
  RunEndDataSchema,
7
8
  TestBeginDataSchema,
8
9
  TestEndDataSchema,
@@ -12,7 +13,7 @@ import {
12
13
  finalizeRunEvent,
13
14
  resolveBaselineTargets,
14
15
  safeParse
15
- } from "./chunk-43JLQN36.js";
16
+ } from "./chunk-KFXC7QDV.js";
16
17
 
17
18
  // src/server/app.ts
18
19
  import { dirname as dirname3, join as join3 } from "path";
@@ -372,6 +373,40 @@ function handleSync(ctx) {
372
373
  };
373
374
  broadcastToBrowsers(ctx.wsClients, message);
374
375
  }
376
+ function handleRegister(ctx, data) {
377
+ const roots = [];
378
+ if (data.playwrightSnapshotDir !== void 0 && data.playwrightSnapshotDir !== "") {
379
+ roots.push(data.playwrightSnapshotDir);
380
+ }
381
+ if (data.playwrightTestDir !== void 0 && data.playwrightTestDir !== "") {
382
+ roots.push(data.playwrightTestDir);
383
+ }
384
+ const existing = ctx.routesContext.artifactRoots ?? [];
385
+ for (const root of roots) {
386
+ if (!existing.includes(root)) {
387
+ existing.push(root);
388
+ }
389
+ }
390
+ ctx.routesContext.artifactRoots = existing;
391
+ if (ctx.routesContext.approvalRouting !== void 0) {
392
+ if (data.playwrightSnapshotDir !== void 0) {
393
+ ctx.routesContext.approvalRouting.playwrightSnapshotDir = data.playwrightSnapshotDir;
394
+ }
395
+ if (data.playwrightTestDir !== void 0) {
396
+ ctx.routesContext.approvalRouting.playwrightTestDir = data.playwrightTestDir;
397
+ }
398
+ if (data.playwrightSnapshotPathTemplate !== void 0) {
399
+ ctx.routesContext.approvalRouting.playwrightSnapshotPathTemplate = data.playwrightSnapshotPathTemplate;
400
+ }
401
+ if (data.playwrightToHaveScreenshotPathTemplate !== void 0) {
402
+ ctx.routesContext.approvalRouting.playwrightToHaveScreenshotPathTemplate = data.playwrightToHaveScreenshotPathTemplate;
403
+ }
404
+ }
405
+ console.log("[Server] Reporter registered with config:", {
406
+ playwrightSnapshotDir: data.playwrightSnapshotDir,
407
+ playwrightTestDir: data.playwrightTestDir
408
+ });
409
+ }
375
410
 
376
411
  // src/server/routes.ts
377
412
  import { join as join2 } from "path";
@@ -570,15 +605,6 @@ function createReportData(options) {
570
605
  screenshotDir: options.screenshotDir ?? "./screenshots"
571
606
  };
572
607
  }
573
- function createHandlerContext(reportData, wsClients, currentRunIds, saveReport, approvalRouting) {
574
- return {
575
- reportData,
576
- wsClients,
577
- currentRunIds,
578
- saveReport,
579
- approvalRouting
580
- };
581
- }
582
608
  async function loadReport(reportPath, reportData) {
583
609
  try {
584
610
  const raw = await readJsonFile(reportPath);
@@ -661,6 +687,15 @@ async function handleParsedWebSocketMessage(ctx, msg) {
661
687
  case "sync":
662
688
  handleSync(ctx);
663
689
  break;
690
+ case "register": {
691
+ const parsed = safeParse(RegisterDataSchema, msg.data);
692
+ if (parsed === null) {
693
+ console.error("Invalid register message data", msg.data);
694
+ break;
695
+ }
696
+ handleRegister(ctx, parsed);
697
+ break;
698
+ }
664
699
  }
665
700
  }
666
701
  function createWebSocketMessageHandler(getHandlerContext) {
@@ -737,7 +772,14 @@ async function createServerApp(options = {}) {
737
772
  await writeJsonFile(reportFile, reportData);
738
773
  }
739
774
  const routesContext = createRoutesContext(reportData, staticDir, saveReport, options);
740
- const getHandlerContext = () => createHandlerContext(reportData, wsClients, currentRunIds, saveReport, routesContext.approvalRouting);
775
+ const getHandlerContext = () => ({
776
+ reportData,
777
+ wsClients,
778
+ currentRunIds,
779
+ saveReport,
780
+ approvalRouting: routesContext.approvalRouting,
781
+ routesContext
782
+ });
741
783
  const handleRequest = (req) => handleHttpRequest(routesContext, req);
742
784
  const handleWebSocketMessage = createWebSocketMessageHandler(getHandlerContext);
743
785
  await loadReport(reportFile, reportData);
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "./chunk-35CZLYSW.js";
5
- import "./chunk-43JLQN36.js";
4
+ } from "./chunk-RJEAJDMQ.js";
5
+ import "./chunk-KFXC7QDV.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { join } from "path";
package/dist/index.js CHANGED
@@ -19392,7 +19392,7 @@ var CrvyRprtrSuiteSchema = external_exports.lazy(
19392
19392
  })
19393
19393
  );
19394
19394
  var IncomingWebSocketMessageSchema = external_exports.object({
19395
- type: external_exports.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
19395
+ type: external_exports.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
19396
19396
  data: external_exports.unknown()
19397
19397
  });
19398
19398
  var WebSocketMessageSchema = external_exports.discriminatedUnion("type", [
@@ -19436,6 +19436,12 @@ var TestEndDataSchema = external_exports.object({
19436
19436
  var RunEndDataSchema = external_exports.object({
19437
19437
  status: external_exports.enum(["passed", "failed", "skipped"])
19438
19438
  });
19439
+ var RegisterDataSchema = external_exports.object({
19440
+ playwrightSnapshotDir: external_exports.string().optional(),
19441
+ playwrightTestDir: external_exports.string().optional(),
19442
+ playwrightSnapshotPathTemplate: external_exports.string().optional(),
19443
+ playwrightToHaveScreenshotPathTemplate: external_exports.string().optional()
19444
+ });
19439
19445
  var ReportDataSchema = external_exports.object({
19440
19446
  isRunning: external_exports.boolean(),
19441
19447
  tests: external_exports.record(external_exports.string(), TestDataSchema),
@@ -21305,7 +21311,9 @@ function App($$anchor, $$props) {
21305
21311
  switch (msg.type) {
21306
21312
  case "test-begin":
21307
21313
  case "test-update": {
21308
- syncTreeState(tests, { [msg.data.id]: msg.data });
21314
+ const current = collectTestsById(tests);
21315
+ current[msg.data.id] = msg.data;
21316
+ syncTreeState(tests, current);
21309
21317
  break;
21310
21318
  }
21311
21319
  case "run-end": {
@@ -0,0 +1,24 @@
1
+ import type { TestResult } from '@playwright/test/reporter';
2
+ import type { AttachmentData } from './reporter-utils.ts';
3
+ import type { ResolvedBaselineTarget } from './snapshot-path-resolver.ts';
4
+ export interface CrvyRprtrOptions {
5
+ serverUrl?: string;
6
+ screenshotDir?: string;
7
+ offlineReportPath?: string;
8
+ reportHtmlPath?: string;
9
+ playwrightSnapshotDir?: string;
10
+ playwrightSnapshotPathTemplate?: string;
11
+ playwrightToHaveScreenshotPathTemplate?: string;
12
+ ci?: boolean;
13
+ }
14
+ export interface PendingPortableArtifact {
15
+ testId: string;
16
+ status: TestResult['status'];
17
+ resolvedTargets: ResolvedBaselineTarget[];
18
+ nativeAttachments: AttachmentData[];
19
+ eventData: {
20
+ attachments: AttachmentData[];
21
+ };
22
+ }
23
+ export declare function collectNativeImageAttachments(result: TestResult): AttachmentData[];
24
+ //# sourceMappingURL=reporter-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter-helpers.d.ts","sourceRoot":"","sources":["../src/reporter-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;IAC/C,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC5B,eAAe,EAAE,sBAAsB,EAAE,CAAA;IACzC,iBAAiB,EAAE,cAAc,EAAE,CAAA;IACnC,SAAS,EAAE;QAAE,WAAW,EAAE,cAAc,EAAE,CAAA;KAAE,CAAA;CAC7C;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,EAAE,CAWlF"}
package/dist/reporter.cjs CHANGED
@@ -323,7 +323,7 @@ var CrvyRprtrSuiteSchema = import_zod.z.lazy(
323
323
  })
324
324
  );
325
325
  var IncomingWebSocketMessageSchema = import_zod.z.object({
326
- type: import_zod.z.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
326
+ type: import_zod.z.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
327
327
  data: import_zod.z.unknown()
328
328
  });
329
329
  var WebSocketMessageSchema = import_zod.z.discriminatedUnion("type", [
@@ -367,6 +367,12 @@ var TestEndDataSchema = import_zod.z.object({
367
367
  var RunEndDataSchema = import_zod.z.object({
368
368
  status: import_zod.z.enum(["passed", "failed", "skipped"])
369
369
  });
370
+ var RegisterDataSchema = import_zod.z.object({
371
+ playwrightSnapshotDir: import_zod.z.string().optional(),
372
+ playwrightTestDir: import_zod.z.string().optional(),
373
+ playwrightSnapshotPathTemplate: import_zod.z.string().optional(),
374
+ playwrightToHaveScreenshotPathTemplate: import_zod.z.string().optional()
375
+ });
370
376
  var ReportDataSchema = import_zod.z.object({
371
377
  isRunning: import_zod.z.boolean(),
372
378
  tests: import_zod.z.record(import_zod.z.string(), TestDataSchema),
@@ -627,6 +633,17 @@ async function writeStaticArtifact(runEvents, screenshotDir, reportHtmlPath) {
627
633
  }
628
634
  }
629
635
 
636
+ // src/reporter-helpers.ts
637
+ function collectNativeImageAttachments(result) {
638
+ return result.attachments.filter(
639
+ (attachment) => attachment.contentType === "image/png" && attachment.path !== void 0
640
+ ).map((attachment) => ({
641
+ name: attachment.name,
642
+ path: attachment.path,
643
+ contentType: attachment.contentType
644
+ }));
645
+ }
646
+
630
647
  // src/reporter-utils.ts
631
648
  var NAMED_SCREENSHOT_STEP_TITLE = /toHaveScreenshot\((.+?)\)/;
632
649
  var UNNAMED_SCREENSHOT_STEP_TITLE = /^Expect "toHaveScreenshot"(?:\s|$)/;
@@ -868,15 +885,6 @@ function resolveBaselineTargets(input) {
868
885
  }
869
886
 
870
887
  // src/reporter.ts
871
- function collectNativeImageAttachments(result) {
872
- return result.attachments.filter(
873
- (attachment) => attachment.contentType === "image/png" && attachment.path !== void 0
874
- ).map((attachment) => ({
875
- name: attachment.name,
876
- path: attachment.path,
877
- contentType: attachment.contentType
878
- }));
879
- }
880
888
  var CrvyRprtr = class {
881
889
  ws = null;
882
890
  serverUrl;
@@ -904,9 +912,7 @@ var CrvyRprtr = class {
904
912
  this.playwrightSnapshotPathTemplate = options.playwrightSnapshotPathTemplate;
905
913
  this.playwrightToHaveScreenshotPathTemplate = options.playwrightToHaveScreenshotPathTemplate;
906
914
  this.ci = options.ci ?? isCI();
907
- if (this.ci) {
908
- this.isOfflineMode = true;
909
- }
915
+ if (this.ci) this.isOfflineMode = true;
910
916
  }
911
917
  async onBegin(config, suite) {
912
918
  this.configDir = config.configFile === void 0 ? config.rootDir : (0, import_path5.dirname)(config.configFile);
@@ -914,6 +920,7 @@ var CrvyRprtr = class {
914
920
  await (0, import_promises3.mkdir)(this.screenshotDir, { recursive: true });
915
921
  if (!this.ci) {
916
922
  this.connect();
923
+ this.sendRegister(config);
917
924
  }
918
925
  }
919
926
  connect() {
@@ -949,6 +956,19 @@ var CrvyRprtr = class {
949
956
  this.isOfflineMode = true;
950
957
  log("[CrvyRprtr] Offline mode enabled - events will be queued to file");
951
958
  }
959
+ sendRegister(config) {
960
+ const snapshotDir = this.playwrightSnapshotDir ?? config.projects[0]?.snapshotDir;
961
+ const testDir = this.playwrightSnapshotDir === void 0 ? config.projects[0]?.testDir : void 0;
962
+ this.send({
963
+ type: "register",
964
+ data: {
965
+ playwrightSnapshotDir: typeof snapshotDir === "string" ? snapshotDir : void 0,
966
+ playwrightTestDir: typeof testDir === "string" ? testDir : void 0,
967
+ playwrightSnapshotPathTemplate: this.playwrightSnapshotPathTemplate,
968
+ playwrightToHaveScreenshotPathTemplate: this.playwrightToHaveScreenshotPathTemplate
969
+ }
970
+ });
971
+ }
952
972
  describeTitlePath(test) {
953
973
  const titlePath = [];
954
974
  for (let suite = test.parent; suite?.type === "describe"; suite = suite.parent)
@@ -959,7 +979,9 @@ var CrvyRprtr = class {
959
979
  return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "chromium", test.location.file, ...this.describeTitlePath(test), test.title];
960
980
  }
961
981
  onTestBegin(test) {
962
- this.testMetadata.set(test.id, { reporterTitlePath: this.reporterTitlePath(test) });
982
+ this.testMetadata.set(test.id, {
983
+ reporterTitlePath: this.reporterTitlePath(test)
984
+ });
963
985
  this.send({
964
986
  type: "test-begin",
965
987
  data: {
@@ -1,14 +1,6 @@
1
1
  import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult } from '@playwright/test/reporter';
2
- export interface CrvyRprtrOptions {
3
- serverUrl?: string;
4
- screenshotDir?: string;
5
- offlineReportPath?: string;
6
- reportHtmlPath?: string;
7
- playwrightSnapshotDir?: string;
8
- playwrightSnapshotPathTemplate?: string;
9
- playwrightToHaveScreenshotPathTemplate?: string;
10
- ci?: boolean;
11
- }
2
+ import { type CrvyRprtrOptions } from './reporter-helpers.ts';
3
+ export type { CrvyRprtrOptions };
12
4
  export declare class CrvyRprtr implements Reporter {
13
5
  private ws;
14
6
  private serverUrl;
@@ -30,6 +22,7 @@ export declare class CrvyRprtr implements Reporter {
30
22
  onBegin(config: FullConfig, suite: Suite): Promise<void>;
31
23
  private connect;
32
24
  private enableOfflineMode;
25
+ private sendRegister;
33
26
  private describeTitlePath;
34
27
  private reporterTitlePath;
35
28
  onTestBegin(test: TestCase): void;
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAqB9G,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;IAC/C,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAuBD,qBAAa,SAAU,YAAW,QAAQ;IACxC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,YAAY,CAAqD;IACzE,OAAO,CAAC,qBAAqB,CAAC,CAAQ;IACtC,OAAO,CAAC,8BAA8B,CAAC,CAAQ;IAC/C,OAAO,CAAC,sCAAsC,CAAC,CAAQ;IACvD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAgC;gBAE5C,OAAO,GAAE,gBAAqB;IAepC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9D,OAAO,CAAC,OAAO;IA6Bf,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAMzB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAcjC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAmCnD,OAAO,CAAC,aAAa;YAqBP,uBAAuB;IAiB/B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAyC9C,OAAO,CAAC,IAAI;CAUb;AAED,eAAe,SAAS,CAAA"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAa9G,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,uBAAuB,CAAA;AAS9B,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,qBAAa,SAAU,YAAW,QAAQ;IACxC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,YAAY,CAAqD;IACzE,OAAO,CAAC,qBAAqB,CAAC,CAAQ;IACtC,OAAO,CAAC,8BAA8B,CAAC,CAAQ;IAC/C,OAAO,CAAC,sCAAsC,CAAC,CAAQ;IACvD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAgC;gBAE5C,OAAO,GAAE,gBAAqB;IAapC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,OAAO,CAAC,OAAO;IA6Bf,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAMzB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAgBjC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAmCnD,OAAO,CAAC,aAAa;YAqBP,uBAAuB;IAgB/B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC9C,OAAO,CAAC,IAAI;CAUb;AAED,eAAe,SAAS,CAAA"}
package/dist/reporter.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveBaselineTargets,
10
10
  safeParse,
11
11
  withResolvedVisualNames
12
- } from "./chunk-43JLQN36.js";
12
+ } from "./chunk-KFXC7QDV.js";
13
13
 
14
14
  // src/reporter.ts
15
15
  import { existsSync } from "fs";
@@ -250,6 +250,17 @@ async function writeStaticArtifact(runEvents, screenshotDir, reportHtmlPath) {
250
250
  }
251
251
  }
252
252
 
253
+ // src/reporter-helpers.ts
254
+ function collectNativeImageAttachments(result) {
255
+ return result.attachments.filter(
256
+ (attachment) => attachment.contentType === "image/png" && attachment.path !== void 0
257
+ ).map((attachment) => ({
258
+ name: attachment.name,
259
+ path: attachment.path,
260
+ contentType: attachment.contentType
261
+ }));
262
+ }
263
+
253
264
  // src/reporter-utils.ts
254
265
  var NAMED_SCREENSHOT_STEP_TITLE = /toHaveScreenshot\((.+?)\)/;
255
266
  var UNNAMED_SCREENSHOT_STEP_TITLE = /^Expect "toHaveScreenshot"(?:\s|$)/;
@@ -320,15 +331,6 @@ function extractScreenshotDeclarations(steps) {
320
331
  }
321
332
 
322
333
  // src/reporter.ts
323
- function collectNativeImageAttachments(result) {
324
- return result.attachments.filter(
325
- (attachment) => attachment.contentType === "image/png" && attachment.path !== void 0
326
- ).map((attachment) => ({
327
- name: attachment.name,
328
- path: attachment.path,
329
- contentType: attachment.contentType
330
- }));
331
- }
332
334
  var CrvyRprtr = class {
333
335
  ws = null;
334
336
  serverUrl;
@@ -356,9 +358,7 @@ var CrvyRprtr = class {
356
358
  this.playwrightSnapshotPathTemplate = options.playwrightSnapshotPathTemplate;
357
359
  this.playwrightToHaveScreenshotPathTemplate = options.playwrightToHaveScreenshotPathTemplate;
358
360
  this.ci = options.ci ?? isCI();
359
- if (this.ci) {
360
- this.isOfflineMode = true;
361
- }
361
+ if (this.ci) this.isOfflineMode = true;
362
362
  }
363
363
  async onBegin(config, suite) {
364
364
  this.configDir = config.configFile === void 0 ? config.rootDir : dirname3(config.configFile);
@@ -366,6 +366,7 @@ var CrvyRprtr = class {
366
366
  await mkdir3(this.screenshotDir, { recursive: true });
367
367
  if (!this.ci) {
368
368
  this.connect();
369
+ this.sendRegister(config);
369
370
  }
370
371
  }
371
372
  connect() {
@@ -401,6 +402,19 @@ var CrvyRprtr = class {
401
402
  this.isOfflineMode = true;
402
403
  log("[CrvyRprtr] Offline mode enabled - events will be queued to file");
403
404
  }
405
+ sendRegister(config) {
406
+ const snapshotDir = this.playwrightSnapshotDir ?? config.projects[0]?.snapshotDir;
407
+ const testDir = this.playwrightSnapshotDir === void 0 ? config.projects[0]?.testDir : void 0;
408
+ this.send({
409
+ type: "register",
410
+ data: {
411
+ playwrightSnapshotDir: typeof snapshotDir === "string" ? snapshotDir : void 0,
412
+ playwrightTestDir: typeof testDir === "string" ? testDir : void 0,
413
+ playwrightSnapshotPathTemplate: this.playwrightSnapshotPathTemplate,
414
+ playwrightToHaveScreenshotPathTemplate: this.playwrightToHaveScreenshotPathTemplate
415
+ }
416
+ });
417
+ }
404
418
  describeTitlePath(test) {
405
419
  const titlePath = [];
406
420
  for (let suite = test.parent; suite?.type === "describe"; suite = suite.parent)
@@ -411,7 +425,9 @@ var CrvyRprtr = class {
411
425
  return typeof test.titlePath === "function" ? test.titlePath() : ["", test.parent.project()?.name ?? "chromium", test.location.file, ...this.describeTitlePath(test), test.title];
412
426
  }
413
427
  onTestBegin(test) {
414
- this.testMetadata.set(test.id, { reporterTitlePath: this.reporterTitlePath(test) });
428
+ this.testMetadata.set(test.id, {
429
+ reporterTitlePath: this.reporterTitlePath(test)
430
+ });
415
431
  this.send({
416
432
  type: "test-begin",
417
433
  data: {
package/dist/schemas.d.ts CHANGED
@@ -227,6 +227,7 @@ export declare const IncomingWebSocketMessageSchema: z.ZodObject<{
227
227
  "run-end": "run-end";
228
228
  approve: "approve";
229
229
  sync: "sync";
230
+ register: "register";
230
231
  }>;
231
232
  data: z.ZodUnknown;
232
233
  }, z.core.$strip>;
@@ -479,6 +480,13 @@ export declare const RunEndDataSchema: z.ZodObject<{
479
480
  }>;
480
481
  }, z.core.$strip>;
481
482
  export type RunEndData = z.infer<typeof RunEndDataSchema>;
483
+ export declare const RegisterDataSchema: z.ZodObject<{
484
+ playwrightSnapshotDir: z.ZodOptional<z.ZodString>;
485
+ playwrightTestDir: z.ZodOptional<z.ZodString>;
486
+ playwrightSnapshotPathTemplate: z.ZodOptional<z.ZodString>;
487
+ playwrightToHaveScreenshotPathTemplate: z.ZodOptional<z.ZodString>;
488
+ }, z.core.$strip>;
489
+ export type RegisterData = z.infer<typeof RegisterDataSchema>;
482
490
  export declare const ReportDataSchema: z.ZodObject<{
483
491
  isRunning: z.ZodBoolean;
484
492
  tests: z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
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;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;CAChD;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;AA6MD,wBAAsB,eAAe,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CA8BrF"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AA6BA,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;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;CAChD;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;AAsMD,wBAAsB,eAAe,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CAmCrF"}
@@ -1,6 +1,7 @@
1
- import type { TestBeginData, TestEndData } from '../schemas.ts';
1
+ import type { RegisterData, TestBeginData, TestEndData } from '../schemas.ts';
2
2
  import type { TestData } from '../types.ts';
3
3
  import { type ApprovalRouting } from './artifact-routes.ts';
4
+ import type { RoutesContext } from './routes.ts';
4
5
  import type { RuntimeWebSocket } from './ws.ts';
5
6
  export interface HandlerContext {
6
7
  reportData: {
@@ -14,6 +15,7 @@ export interface HandlerContext {
14
15
  currentRunIds: Set<string>;
15
16
  saveReport: () => Promise<void>;
16
17
  approvalRouting?: ApprovalRouting;
18
+ routesContext: RoutesContext;
17
19
  }
18
20
  export declare function handleTestBegin(ctx: HandlerContext, data: TestBeginData): void;
19
21
  export declare function handleTestEnd(ctx: HandlerContext, data: TestEndData): void;
@@ -22,4 +24,5 @@ export declare function handleRunEnd(ctx: HandlerContext, data: {
22
24
  }): Promise<void>;
23
25
  export declare function handleApprove(): void;
24
26
  export declare function handleSync(ctx: HandlerContext): void;
27
+ export declare function handleRegister(ctx: HandlerContext, data: RegisterData): void;
25
28
  //# sourceMappingURL=handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,KAAK,EAA0B,QAAQ,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EAA+B,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAExF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE;QACV,SAAS,EAAE,OAAO,CAAA;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,YAAY,EAAE,OAAO,CAAA;QACrB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAChC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAM9E;AAwBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAiB1E;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE;IAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAWpD"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC7E,OAAO,KAAK,EAA0B,QAAQ,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EAA+B,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE;QACV,SAAS,EAAE,OAAO,CAAA;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,YAAY,EAAE,OAAO,CAAA;QACrB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAChC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,aAAa,EAAE,aAAa,CAAA;CAC7B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAM9E;AAwBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAiB1E;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE;IAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAWpD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAqC5E"}
@@ -9,7 +9,7 @@ export interface RoutesContext {
9
9
  };
10
10
  staticDir: string;
11
11
  saveReport: () => Promise<void>;
12
- artifactRoots?: readonly string[];
12
+ artifactRoots?: string[];
13
13
  approvalRouting?: {
14
14
  configDir: string;
15
15
  playwrightTestDir?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE;QACV,SAAS,EAAE,OAAO,CAAA;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,YAAY,EAAE,OAAO,CAAA;QACrB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,eAAe,CAAC,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;QAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;QACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;KAChD,CAAA;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAqMtG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6CrF"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE;QACV,SAAS,EAAE,OAAO,CAAA;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,YAAY,EAAE,OAAO,CAAA;QACrB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,eAAe,CAAC,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;QAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;QACvC,sCAAsC,CAAC,EAAE,MAAM,CAAA;KAChD,CAAA;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAqMtG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6CrF"}
package/dist/server.cjs CHANGED
@@ -302,7 +302,7 @@ var CrvyRprtrSuiteSchema = import_zod.z.lazy(
302
302
  })
303
303
  );
304
304
  var IncomingWebSocketMessageSchema = import_zod.z.object({
305
- type: import_zod.z.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
305
+ type: import_zod.z.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
306
306
  data: import_zod.z.unknown()
307
307
  });
308
308
  var WebSocketMessageSchema = import_zod.z.discriminatedUnion("type", [
@@ -346,6 +346,12 @@ var TestEndDataSchema = import_zod.z.object({
346
346
  var RunEndDataSchema = import_zod.z.object({
347
347
  status: import_zod.z.enum(["passed", "failed", "skipped"])
348
348
  });
349
+ var RegisterDataSchema = import_zod.z.object({
350
+ playwrightSnapshotDir: import_zod.z.string().optional(),
351
+ playwrightTestDir: import_zod.z.string().optional(),
352
+ playwrightSnapshotPathTemplate: import_zod.z.string().optional(),
353
+ playwrightToHaveScreenshotPathTemplate: import_zod.z.string().optional()
354
+ });
349
355
  var ReportDataSchema = import_zod.z.object({
350
356
  isRunning: import_zod.z.boolean(),
351
357
  tests: import_zod.z.record(import_zod.z.string(), TestDataSchema),
@@ -904,6 +910,40 @@ function handleSync(ctx) {
904
910
  };
905
911
  broadcastToBrowsers(ctx.wsClients, message);
906
912
  }
913
+ function handleRegister(ctx, data) {
914
+ const roots = [];
915
+ if (data.playwrightSnapshotDir !== void 0 && data.playwrightSnapshotDir !== "") {
916
+ roots.push(data.playwrightSnapshotDir);
917
+ }
918
+ if (data.playwrightTestDir !== void 0 && data.playwrightTestDir !== "") {
919
+ roots.push(data.playwrightTestDir);
920
+ }
921
+ const existing = ctx.routesContext.artifactRoots ?? [];
922
+ for (const root of roots) {
923
+ if (!existing.includes(root)) {
924
+ existing.push(root);
925
+ }
926
+ }
927
+ ctx.routesContext.artifactRoots = existing;
928
+ if (ctx.routesContext.approvalRouting !== void 0) {
929
+ if (data.playwrightSnapshotDir !== void 0) {
930
+ ctx.routesContext.approvalRouting.playwrightSnapshotDir = data.playwrightSnapshotDir;
931
+ }
932
+ if (data.playwrightTestDir !== void 0) {
933
+ ctx.routesContext.approvalRouting.playwrightTestDir = data.playwrightTestDir;
934
+ }
935
+ if (data.playwrightSnapshotPathTemplate !== void 0) {
936
+ ctx.routesContext.approvalRouting.playwrightSnapshotPathTemplate = data.playwrightSnapshotPathTemplate;
937
+ }
938
+ if (data.playwrightToHaveScreenshotPathTemplate !== void 0) {
939
+ ctx.routesContext.approvalRouting.playwrightToHaveScreenshotPathTemplate = data.playwrightToHaveScreenshotPathTemplate;
940
+ }
941
+ }
942
+ console.log("[Server] Reporter registered with config:", {
943
+ playwrightSnapshotDir: data.playwrightSnapshotDir,
944
+ playwrightTestDir: data.playwrightTestDir
945
+ });
946
+ }
907
947
 
908
948
  // src/server/routes.ts
909
949
  var import_path7 = require("path");
@@ -1103,15 +1143,6 @@ function createReportData(options) {
1103
1143
  screenshotDir: options.screenshotDir ?? "./screenshots"
1104
1144
  };
1105
1145
  }
1106
- function createHandlerContext(reportData, wsClients, currentRunIds, saveReport, approvalRouting) {
1107
- return {
1108
- reportData,
1109
- wsClients,
1110
- currentRunIds,
1111
- saveReport,
1112
- approvalRouting
1113
- };
1114
- }
1115
1146
  async function loadReport(reportPath, reportData) {
1116
1147
  try {
1117
1148
  const raw = await readJsonFile(reportPath);
@@ -1194,6 +1225,15 @@ async function handleParsedWebSocketMessage(ctx, msg) {
1194
1225
  case "sync":
1195
1226
  handleSync(ctx);
1196
1227
  break;
1228
+ case "register": {
1229
+ const parsed = safeParse(RegisterDataSchema, msg.data);
1230
+ if (parsed === null) {
1231
+ console.error("Invalid register message data", msg.data);
1232
+ break;
1233
+ }
1234
+ handleRegister(ctx, parsed);
1235
+ break;
1236
+ }
1197
1237
  }
1198
1238
  }
1199
1239
  function createWebSocketMessageHandler(getHandlerContext) {
@@ -1270,7 +1310,14 @@ async function createServerApp(options = {}) {
1270
1310
  await writeJsonFile(reportFile, reportData);
1271
1311
  }
1272
1312
  const routesContext = createRoutesContext(reportData, staticDir, saveReport, options);
1273
- const getHandlerContext = () => createHandlerContext(reportData, wsClients, currentRunIds, saveReport, routesContext.approvalRouting);
1313
+ const getHandlerContext = () => ({
1314
+ reportData,
1315
+ wsClients,
1316
+ currentRunIds,
1317
+ saveReport,
1318
+ approvalRouting: routesContext.approvalRouting,
1319
+ routesContext
1320
+ });
1274
1321
  const handleRequest = (req) => handleHttpRequest(routesContext, req);
1275
1322
  const handleWebSocketMessage = createWebSocketMessageHandler(getHandlerContext);
1276
1323
  await loadReport(reportFile, reportData);
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startServer
3
- } from "./chunk-35CZLYSW.js";
4
- import "./chunk-43JLQN36.js";
3
+ } from "./chunk-RJEAJDMQ.js";
4
+ import "./chunk-KFXC7QDV.js";
5
5
  export {
6
6
  startServer
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvy/rprtr",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Playwright reporter with visual regression UI for comparing and approving screenshot tests",
5
5
  "keywords": [
6
6
  "crvy",