@crvy/rprtr 0.0.9 → 0.1.1

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/dist/reporter.js CHANGED
@@ -7,8 +7,9 @@ import {
7
7
  createMutableReportState,
8
8
  finalizeRunEvent,
9
9
  resolveBaselineTargets,
10
- safeParse
11
- } from "./chunk-EJRLZZ22.js";
10
+ safeParse,
11
+ withResolvedVisualNames
12
+ } from "./chunk-43JLQN36.js";
12
13
 
13
14
  // src/reporter.ts
14
15
  import { existsSync } from "fs";
@@ -16,6 +17,12 @@ import { mkdir as mkdir3 } from "fs/promises";
16
17
  import { dirname as dirname3, join as join2 } from "path";
17
18
  import pLimit2 from "p-limit";
18
19
 
20
+ // src/ci.ts
21
+ function isCI(env = process.env) {
22
+ const ci = env.CI;
23
+ return ci !== void 0 && ci !== "" && ci !== "false" && ci !== "0";
24
+ }
25
+
19
26
  // src/debug-log.ts
20
27
  var isDebug = () => process.env.DEBUG !== void 0 && process.env.DEBUG !== "";
21
28
  var log = (...args) => {
@@ -313,6 +320,15 @@ function extractScreenshotDeclarations(steps) {
313
320
  }
314
321
 
315
322
  // 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
+ }
316
332
  var CrvyRprtr = class {
317
333
  ws = null;
318
334
  serverUrl;
@@ -327,8 +343,9 @@ var CrvyRprtr = class {
327
343
  playwrightSnapshotPathTemplate;
328
344
  playwrightToHaveScreenshotPathTemplate;
329
345
  isOfflineMode = false;
330
- hadOfflineMode = false;
331
346
  runEvents = [];
347
+ ci;
348
+ pendingArtifacts = [];
332
349
  constructor(options = {}) {
333
350
  this.serverUrl = options.serverUrl ?? "ws://localhost:3000";
334
351
  this.screenshotDir = options.screenshotDir ?? "./screenshots";
@@ -338,12 +355,18 @@ var CrvyRprtr = class {
338
355
  this.playwrightSnapshotDir = options.playwrightSnapshotDir;
339
356
  this.playwrightSnapshotPathTemplate = options.playwrightSnapshotPathTemplate;
340
357
  this.playwrightToHaveScreenshotPathTemplate = options.playwrightToHaveScreenshotPathTemplate;
358
+ this.ci = options.ci ?? isCI();
359
+ if (this.ci) {
360
+ this.isOfflineMode = true;
361
+ }
341
362
  }
342
363
  async onBegin(config, suite) {
343
364
  this.configDir = config.configFile === void 0 ? config.rootDir : dirname3(config.configFile);
344
365
  log(`[CrvyRprtr] Starting run with ${suite.allTests().length} tests`);
345
366
  await mkdir3(this.screenshotDir, { recursive: true });
346
- this.connect();
367
+ if (!this.ci) {
368
+ this.connect();
369
+ }
347
370
  }
348
371
  connect() {
349
372
  const WebSocketConstructor = globalThis.WebSocket;
@@ -375,7 +398,7 @@ var CrvyRprtr = class {
375
398
  }
376
399
  enableOfflineMode() {
377
400
  if (this.isOfflineMode) return;
378
- this.isOfflineMode = this.hadOfflineMode = true;
401
+ this.isOfflineMode = true;
379
402
  log("[CrvyRprtr] Offline mode enabled - events will be queued to file");
380
403
  }
381
404
  describeTitlePath(test) {
@@ -400,24 +423,36 @@ var CrvyRprtr = class {
400
423
  }
401
424
  });
402
425
  }
403
- async onTestEnd(test, result) {
404
- const screenshotDeclarations = extractScreenshotDeclarations(result.steps);
405
- const savedAttachments = await saveAttachments(this.screenshotDir, test.id, result);
426
+ onTestEnd(test, result) {
427
+ const reporterTitlePath = this.testMetadata.get(test.id)?.reporterTitlePath ?? this.reporterTitlePath(test);
428
+ const screenshotDeclarations = withResolvedVisualNames(
429
+ extractScreenshotDeclarations(result.steps),
430
+ reporterTitlePath
431
+ );
432
+ const nativeAttachments = collectNativeImageAttachments(result);
433
+ const data = {
434
+ id: test.id,
435
+ title: test.title,
436
+ status: result.status,
437
+ attachments: nativeAttachments,
438
+ visualNames: screenshotDeclarations.map(({ visualName }) => visualName),
439
+ visualDeclarations: screenshotDeclarations,
440
+ error: result.errors.length > 0 ? result.errors[0]?.message : void 0,
441
+ duration: result.duration
442
+ };
406
443
  try {
407
- await this.copySnapshotBaselines(test, result.status, screenshotDeclarations, savedAttachments);
408
- this.send({
409
- type: "test-end",
410
- data: {
411
- id: test.id,
412
- title: test.title,
444
+ if (this.ci) {
445
+ const baselineInput = result.status === "passed" ? this.baselineInput(test, screenshotDeclarations) : null;
446
+ const resolvedTargets = baselineInput === null ? [] : resolveBaselineTargets(baselineInput);
447
+ this.pendingArtifacts.push({
448
+ testId: test.id,
413
449
  status: result.status,
414
- attachments: savedAttachments,
415
- visualNames: screenshotDeclarations.map(({ visualName }) => visualName),
416
- visualDeclarations: screenshotDeclarations,
417
- error: result.errors.length > 0 ? result.errors[0]?.message : void 0,
418
- duration: result.duration
419
- }
420
- });
450
+ resolvedTargets,
451
+ nativeAttachments,
452
+ eventData: data
453
+ });
454
+ }
455
+ this.send({ type: "test-end", data });
421
456
  } finally {
422
457
  this.testMetadata.delete(test.id);
423
458
  }
@@ -442,25 +477,40 @@ var CrvyRprtr = class {
442
477
  snapshotPathExists: existsSync
443
478
  };
444
479
  }
445
- async copySnapshotBaselines(test, status, screenshotDeclarations, savedAttachments) {
446
- if (status !== "passed" || screenshotDeclarations.length === 0) return;
447
- const input = this.baselineInput(test, screenshotDeclarations);
448
- if (input === null) return;
449
- const targets = resolveBaselineTargets(input);
450
- if (targets.length === 0) return;
451
- const safeTestId = sanitizeId(test.id);
480
+ async copyBaselinesForTargets(testId, status, resolvedTargets, savedAttachments) {
481
+ if (status !== "passed" || resolvedTargets.length === 0) return;
482
+ const safeTestId = sanitizeId(testId);
452
483
  const testScreenshotDir = join2(this.screenshotDir, safeTestId);
453
484
  const limit = pLimit2(5);
454
485
  await Promise.all(
455
- targets.map(
486
+ resolvedTargets.map(
456
487
  (target) => limit(() => copyResolvedBaseline(safeTestId, testScreenshotDir, target, savedAttachments))
457
488
  )
458
489
  );
459
490
  }
460
491
  async onEnd(result) {
461
492
  this.send({ type: "run-end", data: { status: result.status } });
462
- await writeStaticArtifact(this.runEvents, this.screenshotDir, this.reportHtmlPath);
463
- if (this.hadOfflineMode) await writeOfflineReport(this.runEvents, this.offlineReportPath, this.workerIndex);
493
+ if (this.ci) {
494
+ const limit = pLimit2(10);
495
+ await Promise.all(
496
+ this.pendingArtifacts.map(
497
+ (pending) => limit(async () => {
498
+ const savedAttachments = await saveAttachments(this.screenshotDir, pending.testId, {
499
+ attachments: pending.nativeAttachments
500
+ });
501
+ await this.copyBaselinesForTargets(
502
+ pending.testId,
503
+ pending.status,
504
+ pending.resolvedTargets,
505
+ savedAttachments
506
+ );
507
+ pending.eventData.attachments = savedAttachments;
508
+ })
509
+ )
510
+ );
511
+ await writeStaticArtifact(this.runEvents, this.screenshotDir, this.reportHtmlPath);
512
+ await writeOfflineReport(this.runEvents, this.offlineReportPath, this.workerIndex);
513
+ }
464
514
  await new Promise((resolve2) => {
465
515
  if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
466
516
  resolve2();
package/dist/schemas.d.ts CHANGED
@@ -220,7 +220,7 @@ export interface CrvyRprtrSuite {
220
220
  children?: Partial<Record<string, CrvyRprtrSuite | CrvyRprtrTest>>;
221
221
  }
222
222
  export declare const CrvyRprtrSuiteSchema: z.ZodType<CrvyRprtrSuite>;
223
- export declare const WebSocketMessageSchema: z.ZodObject<{
223
+ export declare const IncomingWebSocketMessageSchema: z.ZodObject<{
224
224
  type: z.ZodEnum<{
225
225
  "test-begin": "test-begin";
226
226
  "test-end": "test-end";
@@ -230,6 +230,207 @@ export declare const WebSocketMessageSchema: z.ZodObject<{
230
230
  }>;
231
231
  data: z.ZodUnknown;
232
232
  }, z.core.$strip>;
233
+ export type IncomingWebSocketMessage = z.infer<typeof IncomingWebSocketMessageSchema>;
234
+ export declare const WebSocketMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
235
+ type: z.ZodLiteral<"test-begin">;
236
+ data: z.ZodObject<{
237
+ id: z.ZodString;
238
+ titlePath: z.ZodArray<z.ZodString>;
239
+ browser: z.ZodString;
240
+ title: z.ZodString;
241
+ skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
242
+ retries: z.ZodOptional<z.ZodNumber>;
243
+ status: z.ZodOptional<z.ZodEnum<{
244
+ unknown: "unknown";
245
+ success: "success";
246
+ pending: "pending";
247
+ running: "running";
248
+ failed: "failed";
249
+ approved: "approved";
250
+ retrying: "retrying";
251
+ }>>;
252
+ results: z.ZodOptional<z.ZodArray<z.ZodObject<{
253
+ status: z.ZodEnum<{
254
+ success: "success";
255
+ pending: "pending";
256
+ failed: "failed";
257
+ }>;
258
+ retries: z.ZodNumber;
259
+ images: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
260
+ actual: z.ZodOptional<z.ZodString>;
261
+ expect: z.ZodOptional<z.ZodString>;
262
+ diff: z.ZodOptional<z.ZodString>;
263
+ error: z.ZodOptional<z.ZodString>;
264
+ source: z.ZodOptional<z.ZodEnum<{
265
+ comparison: "comparison";
266
+ "baseline-only": "baseline-only";
267
+ "declared-only": "declared-only";
268
+ }>>;
269
+ }, z.core.$strip>>>;
270
+ visualDeclarations: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
271
+ visualName: z.ZodString;
272
+ kind: z.ZodLiteral<"named">;
273
+ declaredName: z.ZodString;
274
+ snapshotBaseName: z.ZodString;
275
+ occurrenceIndex: z.ZodNumber;
276
+ }, z.core.$strip>, z.ZodObject<{
277
+ visualName: z.ZodString;
278
+ kind: z.ZodLiteral<"unnamed">;
279
+ occurrenceIndex: z.ZodNumber;
280
+ }, z.core.$strip>], "kind">>>;
281
+ error: z.ZodOptional<z.ZodString>;
282
+ duration: z.ZodOptional<z.ZodNumber>;
283
+ }, z.core.$strip>>>;
284
+ approved: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodNumber>>>;
285
+ attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
286
+ name: z.ZodString;
287
+ path: z.ZodString;
288
+ contentType: z.ZodString;
289
+ }, z.core.$strip>>>;
290
+ location: z.ZodOptional<z.ZodObject<{
291
+ file: z.ZodString;
292
+ line: z.ZodNumber;
293
+ }, z.core.$strip>>;
294
+ }, z.core.$strip>;
295
+ }, z.core.$strip>, z.ZodObject<{
296
+ type: z.ZodLiteral<"test-update">;
297
+ data: z.ZodObject<{
298
+ id: z.ZodString;
299
+ titlePath: z.ZodArray<z.ZodString>;
300
+ browser: z.ZodString;
301
+ title: z.ZodString;
302
+ skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
303
+ retries: z.ZodOptional<z.ZodNumber>;
304
+ status: z.ZodOptional<z.ZodEnum<{
305
+ unknown: "unknown";
306
+ success: "success";
307
+ pending: "pending";
308
+ running: "running";
309
+ failed: "failed";
310
+ approved: "approved";
311
+ retrying: "retrying";
312
+ }>>;
313
+ results: z.ZodOptional<z.ZodArray<z.ZodObject<{
314
+ status: z.ZodEnum<{
315
+ success: "success";
316
+ pending: "pending";
317
+ failed: "failed";
318
+ }>;
319
+ retries: z.ZodNumber;
320
+ images: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
321
+ actual: z.ZodOptional<z.ZodString>;
322
+ expect: z.ZodOptional<z.ZodString>;
323
+ diff: z.ZodOptional<z.ZodString>;
324
+ error: z.ZodOptional<z.ZodString>;
325
+ source: z.ZodOptional<z.ZodEnum<{
326
+ comparison: "comparison";
327
+ "baseline-only": "baseline-only";
328
+ "declared-only": "declared-only";
329
+ }>>;
330
+ }, z.core.$strip>>>;
331
+ visualDeclarations: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
332
+ visualName: z.ZodString;
333
+ kind: z.ZodLiteral<"named">;
334
+ declaredName: z.ZodString;
335
+ snapshotBaseName: z.ZodString;
336
+ occurrenceIndex: z.ZodNumber;
337
+ }, z.core.$strip>, z.ZodObject<{
338
+ visualName: z.ZodString;
339
+ kind: z.ZodLiteral<"unnamed">;
340
+ occurrenceIndex: z.ZodNumber;
341
+ }, z.core.$strip>], "kind">>>;
342
+ error: z.ZodOptional<z.ZodString>;
343
+ duration: z.ZodOptional<z.ZodNumber>;
344
+ }, z.core.$strip>>>;
345
+ approved: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodNumber>>>;
346
+ attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
347
+ name: z.ZodString;
348
+ path: z.ZodString;
349
+ contentType: z.ZodString;
350
+ }, z.core.$strip>>>;
351
+ location: z.ZodOptional<z.ZodObject<{
352
+ file: z.ZodString;
353
+ line: z.ZodNumber;
354
+ }, z.core.$strip>>;
355
+ }, z.core.$strip>;
356
+ }, z.core.$strip>, z.ZodObject<{
357
+ type: z.ZodLiteral<"run-end">;
358
+ data: z.ZodObject<{
359
+ status: z.ZodEnum<{
360
+ failed: "failed";
361
+ passed: "passed";
362
+ skipped: "skipped";
363
+ }>;
364
+ removedTestIds: z.ZodArray<z.ZodString>;
365
+ }, z.core.$strip>;
366
+ }, z.core.$strip>, z.ZodObject<{
367
+ type: z.ZodLiteral<"sync">;
368
+ data: z.ZodObject<{
369
+ tests: z.ZodRecord<z.ZodString, z.ZodObject<{
370
+ id: z.ZodString;
371
+ titlePath: z.ZodArray<z.ZodString>;
372
+ browser: z.ZodString;
373
+ title: z.ZodString;
374
+ skip: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
375
+ retries: z.ZodOptional<z.ZodNumber>;
376
+ status: z.ZodOptional<z.ZodEnum<{
377
+ unknown: "unknown";
378
+ success: "success";
379
+ pending: "pending";
380
+ running: "running";
381
+ failed: "failed";
382
+ approved: "approved";
383
+ retrying: "retrying";
384
+ }>>;
385
+ results: z.ZodOptional<z.ZodArray<z.ZodObject<{
386
+ status: z.ZodEnum<{
387
+ success: "success";
388
+ pending: "pending";
389
+ failed: "failed";
390
+ }>;
391
+ retries: z.ZodNumber;
392
+ images: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
393
+ actual: z.ZodOptional<z.ZodString>;
394
+ expect: z.ZodOptional<z.ZodString>;
395
+ diff: z.ZodOptional<z.ZodString>;
396
+ error: z.ZodOptional<z.ZodString>;
397
+ source: z.ZodOptional<z.ZodEnum<{
398
+ comparison: "comparison";
399
+ "baseline-only": "baseline-only";
400
+ "declared-only": "declared-only";
401
+ }>>;
402
+ }, z.core.$strip>>>;
403
+ visualDeclarations: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
404
+ visualName: z.ZodString;
405
+ kind: z.ZodLiteral<"named">;
406
+ declaredName: z.ZodString;
407
+ snapshotBaseName: z.ZodString;
408
+ occurrenceIndex: z.ZodNumber;
409
+ }, z.core.$strip>, z.ZodObject<{
410
+ visualName: z.ZodString;
411
+ kind: z.ZodLiteral<"unnamed">;
412
+ occurrenceIndex: z.ZodNumber;
413
+ }, z.core.$strip>], "kind">>>;
414
+ error: z.ZodOptional<z.ZodString>;
415
+ duration: z.ZodOptional<z.ZodNumber>;
416
+ }, z.core.$strip>>>;
417
+ approved: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodNumber>>>;
418
+ attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
419
+ name: z.ZodString;
420
+ path: z.ZodString;
421
+ contentType: z.ZodString;
422
+ }, z.core.$strip>>>;
423
+ location: z.ZodOptional<z.ZodObject<{
424
+ file: z.ZodString;
425
+ line: z.ZodNumber;
426
+ }, z.core.$strip>>;
427
+ }, z.core.$strip>>;
428
+ isUpdateMode: z.ZodOptional<z.ZodBoolean>;
429
+ }, z.core.$strip>;
430
+ }, z.core.$strip>, z.ZodObject<{
431
+ type: z.ZodLiteral<"approve">;
432
+ data: z.ZodUnknown;
433
+ }, z.core.$strip>], "type">;
233
434
  export type WebSocketMessage = z.infer<typeof WebSocketMessageSchema>;
234
435
  export declare const TestBeginDataSchema: z.ZodObject<{
235
436
  id: z.ZodString;
@@ -270,6 +471,14 @@ export declare const TestEndDataSchema: z.ZodObject<{
270
471
  duration: z.ZodOptional<z.ZodNumber>;
271
472
  }, z.core.$strip>;
272
473
  export type TestEndData = z.infer<typeof TestEndDataSchema>;
474
+ export declare const RunEndDataSchema: z.ZodObject<{
475
+ status: z.ZodEnum<{
476
+ failed: "failed";
477
+ passed: "passed";
478
+ skipped: "skipped";
479
+ }>;
480
+ }, z.core.$strip>;
481
+ export type RunEndData = z.infer<typeof RunEndDataSchema>;
273
482
  export declare const ReportDataSchema: z.ZodObject<{
274
483
  isRunning: z.ZodBoolean;
275
484
  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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"}
@@ -6,6 +6,12 @@ export interface ServerOptions {
6
6
  /** Absolute path to the built web UI assets directory, or its parent directory */
7
7
  staticDir?: string;
8
8
  configDir?: string;
9
+ /**
10
+ * Playwright's outputDir (test-results), where failure artifacts are written. Used as a root in
11
+ * the `/file` serving allowlist. Relative paths are resolved against the server's working
12
+ * directory, so start the server from the same directory the tests ran in.
13
+ */
14
+ outputDir?: string;
9
15
  playwrightTestDir?: string;
10
16
  playwrightSnapshotDir?: string;
11
17
  playwrightSnapshotPathTemplate?: string;
@@ -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;IAClB,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;AA8LD,wBAAsB,eAAe,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CA6BrF"}
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"}
@@ -0,0 +1,8 @@
1
+ import type { TestData } from '../types.ts';
2
+ import type { RoutesContext } from './routes.ts';
3
+ export declare function handleFile(ctx: RoutesContext, req: Request): Promise<Response>;
4
+ export type ApprovalRouting = RoutesContext['approvalRouting'];
5
+ export declare function resolveBaselineSnapshotPath(routing: ApprovalRouting, test: TestData, retry: number, imageName: string): string | null;
6
+ export declare function handleBaseline(ctx: RoutesContext, req: Request): Promise<Response>;
7
+ export declare function handleArtifactRoute(ctx: RoutesContext, req: Request, pathname: string): Promise<Response> | null;
8
+ //# sourceMappingURL=artifact-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-routes.d.ts","sourceRoot":"","sources":["../../src/server/artifact-routes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAWhD,wBAAsB,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgCpF;AAOD,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAA;AAE9D,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAyBf;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmCxF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAQhH"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/server/file-utils.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnE;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWpE;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAerE;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjG;AA8BD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAatG"}
1
+ {"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/server/file-utils.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnE;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWpE;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAerE;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjG;AA8BD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAgBtG"}
@@ -1,5 +1,6 @@
1
1
  import type { TestBeginData, TestEndData } from '../schemas.ts';
2
- import type { TestData, WebSocketMessage } from '../types.ts';
2
+ import type { TestData } from '../types.ts';
3
+ import { type ApprovalRouting } from './artifact-routes.ts';
3
4
  import type { RuntimeWebSocket } from './ws.ts';
4
5
  export interface HandlerContext {
5
6
  reportData: {
@@ -12,10 +13,13 @@ export interface HandlerContext {
12
13
  wsClients: Set<RuntimeWebSocket>;
13
14
  currentRunIds: Set<string>;
14
15
  saveReport: () => Promise<void>;
16
+ approvalRouting?: ApprovalRouting;
15
17
  }
16
18
  export declare function handleTestBegin(ctx: HandlerContext, data: TestBeginData): void;
17
19
  export declare function handleTestEnd(ctx: HandlerContext, data: TestEndData): void;
18
- export declare function handleRunEnd(ctx: HandlerContext, data: WebSocketMessage['data']): Promise<void>;
20
+ export declare function handleRunEnd(ctx: HandlerContext, data: {
21
+ status: 'passed' | 'failed' | 'skipped';
22
+ }): Promise<void>;
19
23
  export declare function handleApprove(): void;
20
24
  export declare function handleSync(ctx: HandlerContext): void;
21
25
  //# sourceMappingURL=handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE7D,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;CAChC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAK9E;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAW1E;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrG;AAED,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAIpD"}
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"}
@@ -9,6 +9,7 @@ export interface RoutesContext {
9
9
  };
10
10
  staticDir: string;
11
11
  saveReport: () => Promise<void>;
12
+ artifactRoots?: readonly string[];
12
13
  approvalRouting?: {
13
14
  configDir: string;
14
15
  playwrightTestDir?: string;
@@ -17,7 +18,6 @@ export interface RoutesContext {
17
18
  playwrightToHaveScreenshotPathTemplate?: string;
18
19
  };
19
20
  }
20
- export declare const LIVE_UPDATES_WEBSOCKET_PATH = "/";
21
- export declare function isWebSocketUpgradeRequest(req: Request): boolean;
21
+ export { isPathWithinRoots, isWebSocketUpgradeRequest, LIVE_UPDATES_WEBSOCKET_PATH } from './utils.ts';
22
22
  export declare function handleHttpRequest(ctx: RoutesContext, req: Request): Promise<Response>;
23
23
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C,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,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,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK/D;AAiOD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwCrF"}
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,3 +1,6 @@
1
1
  import type { RuntimeWebSocket } from './ws.ts';
2
+ export declare const LIVE_UPDATES_WEBSOCKET_PATH = "/";
2
3
  export declare function broadcastToBrowsers(wsClients: Set<RuntimeWebSocket>, msg: object): void;
4
+ export declare function isWebSocketUpgradeRequest(req: Request): boolean;
5
+ export declare function isPathWithinRoots(target: string, roots: readonly string[]): boolean;
3
6
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/server/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAKvF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/server/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAKvF;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK/D;AAID,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAMnF"}