@crvy/rprtr 0.1.4 → 0.2.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 +61 -0
- package/README.md +8 -7
- package/dist/{chunk-WRMHUY5A.js → chunk-HAFWYUNO.js} +181 -130
- package/dist/{chunk-KLGJSEKV.js → chunk-RFZGJSL3.js} +439 -127
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -4
- package/dist/index.css +26 -0
- package/dist/index.js +297 -76
- package/dist/offline-reports.d.ts +4 -0
- package/dist/offline-reports.d.ts.map +1 -1
- package/dist/report-state.d.ts +3 -1
- package/dist/report-state.d.ts.map +1 -1
- package/dist/reporter-utils.d.ts +0 -1
- package/dist/reporter-utils.d.ts.map +1 -1
- package/dist/reporter.cjs +186 -134
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +8 -6
- package/dist/schemas/http.d.ts +44 -0
- package/dist/schemas/http.d.ts.map +1 -0
- package/dist/schemas.d.ts +25 -6
- package/dist/schemas.d.ts.map +1 -1
- package/dist/server/app.d.ts +6 -0
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/handlers.d.ts +3 -0
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/playwright-config.d.ts +2 -0
- package/dist/server/playwright-config.d.ts.map +1 -0
- package/dist/server/routes-context.d.ts +13 -0
- package/dist/server/routes-context.d.ts.map +1 -0
- package/dist/server/routes.d.ts +6 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/run-controller.d.ts +85 -0
- package/dist/server/run-controller.d.ts.map +1 -0
- package/dist/server/run-routes.d.ts +3 -0
- package/dist/server/run-routes.d.ts.map +1 -0
- package/dist/server.cjs +633 -273
- package/dist/server.js +2 -2
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,67 @@ 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.2.2] - 2026-07-03
|
|
9
|
+
|
|
10
|
+
### Miscellaneous
|
|
11
|
+
|
|
12
|
+
- Update repository URLs to creevey/rprtr
|
|
13
|
+
## [0.2.1] - 2026-07-03
|
|
14
|
+
## [0.2.0] - 2026-07-03
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **types:** Add run-status variant to ClientWebSocketMessage
|
|
19
|
+
- **reporter:** Include configFile and cwd in register message
|
|
20
|
+
- **server:** Add RunController for spawning playwright test
|
|
21
|
+
- **server:** Persist register payload configFile and cwd as runContext
|
|
22
|
+
- **server:** Instantiate RunController in createServerApp and dispose on close
|
|
23
|
+
- **server:** Add POST /api/run and /api/stop, surface runEnabled in /api/report
|
|
24
|
+
- **client:** Wire Start/Stop buttons to /api/run and /api/stop
|
|
25
|
+
- **client:** Add per-test and per-suite run buttons to sidebar tree
|
|
26
|
+
- **run-controller:** Resolve playwright via project package manager
|
|
27
|
+
- **run-controller:** Descriptor-based filter with positional translation
|
|
28
|
+
- **run-controller:** --test-list for suites with version fallback
|
|
29
|
+
- **client:** Descriptor filters, no-location feedback, isRunning guard
|
|
30
|
+
- **client:** Add captureTestStatuses/restoreTestStatuses helpers
|
|
31
|
+
- **client:** Revert orphaned pending on no-event run
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **schemas:** Extract HTTP request schemas to schemas/http.ts
|
|
36
|
+
- **schemas:** Use discriminatedUnion for Run/Stop responses
|
|
37
|
+
- **run-controller:** Document cwd param and test launch fallback
|
|
38
|
+
- **reporter:** Make onBegin synchronous and defer screenshotDir creation
|
|
39
|
+
- **client:** Reset runEventIds on rejected-start path
|
|
40
|
+
|
|
41
|
+
### Documentation
|
|
42
|
+
|
|
43
|
+
- **spec:** Run tests from UI design
|
|
44
|
+
- **plan:** Run tests from UI implementation plan
|
|
45
|
+
- **spec:** Run-from-UI robustness design
|
|
46
|
+
- **plan:** Run-from-UI robustness implementation plan
|
|
47
|
+
- **spec:** Stuck-pending run recovery design
|
|
48
|
+
- **plan:** Stuck-pending run recovery implementation plan
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- **run-controller:** Guard against duplicate exit/error cleanup
|
|
53
|
+
- **reporter:** Honor CRVY_RPRTR_SERVER_URL env as fallback serverUrl
|
|
54
|
+
- **run-controller:** Override reporters and strip CI env for UI-triggered runs
|
|
55
|
+
- **run-from-ui:** Row height, re-run status, filtered-run scope, startup config
|
|
56
|
+
- **run-from-ui:** Mark tests pending on start, use file:line:column for precise re-runs
|
|
57
|
+
- **run-controller:** Resolve @crvy/rprtr from project cwd then server module
|
|
58
|
+
- **run-controller:** Clean up test-list temp file on spawn throw
|
|
59
|
+
- **knip:** Enable production-mode analysis in strict checks
|
|
60
|
+
|
|
61
|
+
### Styling
|
|
62
|
+
|
|
63
|
+
- **client:** Match semicolon convention and destructure location
|
|
64
|
+
- **docs:** Reformat CLI options table
|
|
65
|
+
|
|
66
|
+
### Testing
|
|
67
|
+
|
|
68
|
+
- **client:** Cover undefined-restore and empty/bare-root edge cases
|
|
8
69
|
## [0.1.4] - 2026-06-19
|
|
9
70
|
|
|
10
71
|
### Added
|
package/README.md
CHANGED
|
@@ -74,13 +74,14 @@ If `artifact-dir` is provided, the CLI treats it as the directory containing:
|
|
|
74
74
|
|
|
75
75
|
Explicit flags override the paths derived from `artifact-dir`.
|
|
76
76
|
|
|
77
|
-
| Option | Short | Default | Description
|
|
78
|
-
| ------------------ | ----- | --------------- |
|
|
79
|
-
| `--port` | `-p` | `3000` | Server port
|
|
80
|
-
| `--screenshot-dir` | `-s` | `./screenshots` | Screenshot directory path
|
|
81
|
-
| `--report-path` | `-r` | `./report.json` | Report JSON file path or directory containing `report.json` and `crvy-rprtr-*.json` files
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
| Option | Short | Default | Description |
|
|
78
|
+
| ------------------ | ----- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `--port` | `-p` | `3000` | Server port |
|
|
80
|
+
| `--screenshot-dir` | `-s` | `./screenshots` | Screenshot directory path |
|
|
81
|
+
| `--report-path` | `-r` | `./report.json` | Report JSON file path or directory containing `report.json` and `crvy-rprtr-*.json` files |
|
|
82
|
+
| `--config` | `-c` | auto-detect | Playwright config path used to enable the run buttons at startup. When omitted, the server discovers `playwright.config.*` in the working directory. A registering reporter always overrides this. |
|
|
83
|
+
|
|
84
|
+
When the server can resolve a Playwright config (via `--config` or auto-discovery, or once a reporter registers), the sidebar shows Start/Stop and per-test run buttons that trigger `playwright test` without leaving the browser. Approval-routing resolver overrides are available through the programmatic server API, not additional CLI flags.
|
|
84
85
|
|
|
85
86
|
## How It Works
|
|
86
87
|
|
|
@@ -170,169 +170,211 @@ function resolveBaselineTargets(input) {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// src/schemas.ts
|
|
173
|
+
import { z as z2 } from "zod";
|
|
174
|
+
|
|
175
|
+
// src/schemas/http.ts
|
|
173
176
|
import { z } from "zod";
|
|
174
|
-
var
|
|
177
|
+
var ApproveRequestBodySchema = z.object({
|
|
178
|
+
id: z.string(),
|
|
179
|
+
retry: z.number(),
|
|
180
|
+
image: z.string()
|
|
181
|
+
});
|
|
182
|
+
var RunTestDescriptorSchema = z.object({
|
|
175
183
|
file: z.string(),
|
|
176
|
-
line: z.number()
|
|
184
|
+
line: z.number(),
|
|
185
|
+
column: z.number().optional(),
|
|
186
|
+
projectName: z.string().optional(),
|
|
187
|
+
titlePath: z.array(z.string())
|
|
177
188
|
});
|
|
178
|
-
var
|
|
179
|
-
|
|
180
|
-
actual: z.string().optional(),
|
|
181
|
-
expect: z.string().optional(),
|
|
182
|
-
diff: z.string().optional(),
|
|
183
|
-
error: z.string().optional(),
|
|
184
|
-
source: VisualSourceSchema.optional()
|
|
189
|
+
var RunRequestBodySchema = z.object({
|
|
190
|
+
tests: z.array(RunTestDescriptorSchema).optional()
|
|
185
191
|
});
|
|
186
|
-
var
|
|
192
|
+
var RunResponseSchema = z.discriminatedUnion("ok", [
|
|
193
|
+
z.object({ ok: z.literal(true) }),
|
|
187
194
|
z.object({
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}),
|
|
195
|
+
ok: z.literal(false),
|
|
196
|
+
reason: z.enum(["no-config", "already-running", "no-tests"])
|
|
197
|
+
})
|
|
198
|
+
]);
|
|
199
|
+
var StopResponseSchema = z.discriminatedUnion("ok", [
|
|
200
|
+
z.object({ ok: z.literal(true) }),
|
|
194
201
|
z.object({
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
ok: z.literal(false),
|
|
203
|
+
reason: z.literal("not-running")
|
|
204
|
+
})
|
|
205
|
+
]);
|
|
206
|
+
|
|
207
|
+
// src/schemas.ts
|
|
208
|
+
var LocationSchema = z2.object({
|
|
209
|
+
file: z2.string(),
|
|
210
|
+
line: z2.number(),
|
|
211
|
+
column: z2.number().optional()
|
|
212
|
+
});
|
|
213
|
+
var VisualSourceSchema = z2.enum(["comparison", "baseline-only", "declared-only"]);
|
|
214
|
+
var ImagesSchema = z2.object({
|
|
215
|
+
actual: z2.string().optional(),
|
|
216
|
+
expect: z2.string().optional(),
|
|
217
|
+
diff: z2.string().optional(),
|
|
218
|
+
error: z2.string().optional(),
|
|
219
|
+
source: VisualSourceSchema.optional()
|
|
220
|
+
});
|
|
221
|
+
var ScreenshotDeclarationSchema = z2.discriminatedUnion("kind", [
|
|
222
|
+
z2.object({
|
|
223
|
+
visualName: z2.string(),
|
|
224
|
+
kind: z2.literal("named"),
|
|
225
|
+
declaredName: z2.string(),
|
|
226
|
+
snapshotBaseName: z2.string(),
|
|
227
|
+
occurrenceIndex: z2.number()
|
|
228
|
+
}),
|
|
229
|
+
z2.object({
|
|
230
|
+
visualName: z2.string(),
|
|
231
|
+
kind: z2.literal("unnamed"),
|
|
232
|
+
occurrenceIndex: z2.number()
|
|
198
233
|
})
|
|
199
234
|
]);
|
|
200
|
-
var AttachmentSchema =
|
|
201
|
-
name:
|
|
202
|
-
path:
|
|
203
|
-
contentType:
|
|
235
|
+
var AttachmentSchema = z2.object({
|
|
236
|
+
name: z2.string(),
|
|
237
|
+
path: z2.string(),
|
|
238
|
+
contentType: z2.string()
|
|
204
239
|
});
|
|
205
|
-
var TestStatusSchema =
|
|
206
|
-
var TestResultStatusSchema =
|
|
207
|
-
var TestResultSchema =
|
|
240
|
+
var TestStatusSchema = z2.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
|
|
241
|
+
var TestResultStatusSchema = z2.enum(["failed", "success", "pending"]);
|
|
242
|
+
var TestResultSchema = z2.object({
|
|
208
243
|
status: TestResultStatusSchema,
|
|
209
|
-
retries:
|
|
210
|
-
images:
|
|
211
|
-
visualDeclarations:
|
|
212
|
-
error:
|
|
213
|
-
duration:
|
|
244
|
+
retries: z2.number(),
|
|
245
|
+
images: z2.record(z2.string(), ImagesSchema).optional(),
|
|
246
|
+
visualDeclarations: z2.array(ScreenshotDeclarationSchema).optional(),
|
|
247
|
+
error: z2.string().optional(),
|
|
248
|
+
duration: z2.number().optional()
|
|
214
249
|
});
|
|
215
|
-
var TestDataSchema =
|
|
216
|
-
id:
|
|
217
|
-
titlePath:
|
|
218
|
-
browser:
|
|
219
|
-
projectName:
|
|
220
|
-
title:
|
|
221
|
-
skip:
|
|
222
|
-
retries:
|
|
250
|
+
var TestDataSchema = z2.object({
|
|
251
|
+
id: z2.string(),
|
|
252
|
+
titlePath: z2.array(z2.string()),
|
|
253
|
+
browser: z2.string(),
|
|
254
|
+
projectName: z2.string().optional(),
|
|
255
|
+
title: z2.string(),
|
|
256
|
+
skip: z2.union([z2.boolean(), z2.string()]).optional(),
|
|
257
|
+
retries: z2.number().optional(),
|
|
223
258
|
status: TestStatusSchema.optional(),
|
|
224
|
-
results:
|
|
225
|
-
approved:
|
|
226
|
-
attachments:
|
|
259
|
+
results: z2.array(TestResultSchema).optional(),
|
|
260
|
+
approved: z2.record(z2.string(), z2.number()).nullable().optional(),
|
|
261
|
+
attachments: z2.array(AttachmentSchema).optional(),
|
|
227
262
|
location: LocationSchema.optional()
|
|
228
263
|
});
|
|
229
264
|
var CrvyRprtrTestSchema = TestDataSchema.extend({
|
|
230
|
-
checked:
|
|
265
|
+
checked: z2.boolean()
|
|
231
266
|
});
|
|
232
|
-
var CrvyRprtrSuiteSchema =
|
|
233
|
-
() =>
|
|
234
|
-
path:
|
|
235
|
-
skip:
|
|
267
|
+
var CrvyRprtrSuiteSchema = z2.lazy(
|
|
268
|
+
() => z2.object({
|
|
269
|
+
path: z2.array(z2.string()),
|
|
270
|
+
skip: z2.boolean(),
|
|
236
271
|
status: TestStatusSchema.optional(),
|
|
237
|
-
opened:
|
|
238
|
-
checked:
|
|
239
|
-
indeterminate:
|
|
240
|
-
children:
|
|
272
|
+
opened: z2.boolean(),
|
|
273
|
+
checked: z2.boolean(),
|
|
274
|
+
indeterminate: z2.boolean(),
|
|
275
|
+
children: z2.record(z2.string(), z2.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
|
|
241
276
|
})
|
|
242
277
|
);
|
|
243
|
-
var IncomingWebSocketMessageSchema =
|
|
244
|
-
type:
|
|
245
|
-
data:
|
|
278
|
+
var IncomingWebSocketMessageSchema = z2.object({
|
|
279
|
+
type: z2.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
|
|
280
|
+
data: z2.unknown()
|
|
246
281
|
});
|
|
247
|
-
var WebSocketMessageSchema =
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
type:
|
|
252
|
-
data:
|
|
253
|
-
status:
|
|
254
|
-
removedTestIds:
|
|
282
|
+
var WebSocketMessageSchema = z2.discriminatedUnion("type", [
|
|
283
|
+
z2.object({ type: z2.literal("test-begin"), data: TestDataSchema }),
|
|
284
|
+
z2.object({ type: z2.literal("test-update"), data: TestDataSchema }),
|
|
285
|
+
z2.object({
|
|
286
|
+
type: z2.literal("run-end"),
|
|
287
|
+
data: z2.object({
|
|
288
|
+
status: z2.enum(["passed", "failed", "skipped"]),
|
|
289
|
+
removedTestIds: z2.array(z2.string())
|
|
255
290
|
})
|
|
256
291
|
}),
|
|
257
|
-
|
|
258
|
-
type:
|
|
259
|
-
data:
|
|
260
|
-
tests:
|
|
261
|
-
isUpdateMode:
|
|
292
|
+
z2.object({
|
|
293
|
+
type: z2.literal("sync"),
|
|
294
|
+
data: z2.object({
|
|
295
|
+
tests: z2.record(z2.string(), TestDataSchema),
|
|
296
|
+
isUpdateMode: z2.boolean().optional()
|
|
262
297
|
})
|
|
263
298
|
}),
|
|
264
|
-
|
|
299
|
+
z2.object({ type: z2.literal("approve"), data: z2.unknown() }),
|
|
300
|
+
z2.object({
|
|
301
|
+
type: z2.literal("run-status"),
|
|
302
|
+
data: z2.object({
|
|
303
|
+
running: z2.boolean()
|
|
304
|
+
})
|
|
305
|
+
})
|
|
265
306
|
]);
|
|
266
|
-
var TestBeginDataSchema =
|
|
267
|
-
id:
|
|
268
|
-
title:
|
|
269
|
-
titlePath:
|
|
270
|
-
browser:
|
|
271
|
-
projectName:
|
|
307
|
+
var TestBeginDataSchema = z2.object({
|
|
308
|
+
id: z2.string(),
|
|
309
|
+
title: z2.string(),
|
|
310
|
+
titlePath: z2.array(z2.string()),
|
|
311
|
+
browser: z2.string(),
|
|
312
|
+
projectName: z2.string().optional(),
|
|
272
313
|
location: LocationSchema
|
|
273
314
|
});
|
|
274
|
-
var TestEndDataSchema =
|
|
275
|
-
id:
|
|
276
|
-
status:
|
|
277
|
-
attachments:
|
|
278
|
-
visualNames:
|
|
279
|
-
visualDeclarations:
|
|
315
|
+
var TestEndDataSchema = z2.object({
|
|
316
|
+
id: z2.string(),
|
|
317
|
+
status: z2.enum(["passed", "failed", "skipped"]),
|
|
318
|
+
attachments: z2.array(AttachmentSchema),
|
|
319
|
+
visualNames: z2.array(z2.string()).default([]),
|
|
320
|
+
visualDeclarations: z2.preprocess(
|
|
280
321
|
(value) => value === null ? void 0 : value,
|
|
281
|
-
|
|
322
|
+
z2.array(ScreenshotDeclarationSchema).optional()
|
|
282
323
|
),
|
|
283
|
-
error:
|
|
284
|
-
duration:
|
|
324
|
+
error: z2.string().optional(),
|
|
325
|
+
duration: z2.number().optional()
|
|
285
326
|
});
|
|
286
|
-
var RunEndDataSchema =
|
|
287
|
-
status:
|
|
327
|
+
var RunEndDataSchema = z2.object({
|
|
328
|
+
status: z2.enum(["passed", "failed", "skipped"])
|
|
288
329
|
});
|
|
289
|
-
var RegisterDataSchema =
|
|
290
|
-
playwrightSnapshotDir:
|
|
291
|
-
playwrightTestDir:
|
|
292
|
-
playwrightSnapshotPathTemplate:
|
|
293
|
-
playwrightToHaveScreenshotPathTemplate:
|
|
330
|
+
var RegisterDataSchema = z2.object({
|
|
331
|
+
playwrightSnapshotDir: z2.string().optional(),
|
|
332
|
+
playwrightTestDir: z2.string().optional(),
|
|
333
|
+
playwrightSnapshotPathTemplate: z2.string().optional(),
|
|
334
|
+
playwrightToHaveScreenshotPathTemplate: z2.string().optional(),
|
|
335
|
+
configFile: z2.string().optional(),
|
|
336
|
+
cwd: z2.string().optional()
|
|
294
337
|
});
|
|
295
|
-
var ReportDataSchema =
|
|
296
|
-
isRunning:
|
|
297
|
-
tests:
|
|
298
|
-
browsers:
|
|
299
|
-
isUpdateMode:
|
|
300
|
-
screenshotDir:
|
|
338
|
+
var ReportDataSchema = z2.object({
|
|
339
|
+
isRunning: z2.boolean(),
|
|
340
|
+
tests: z2.record(z2.string(), TestDataSchema),
|
|
341
|
+
browsers: z2.array(z2.string()),
|
|
342
|
+
isUpdateMode: z2.boolean(),
|
|
343
|
+
screenshotDir: z2.string()
|
|
301
344
|
});
|
|
302
|
-
var LoadedReportDataSchema =
|
|
303
|
-
tests:
|
|
304
|
-
isUpdateMode:
|
|
345
|
+
var LoadedReportDataSchema = z2.object({
|
|
346
|
+
tests: z2.record(z2.string(), TestDataSchema).optional(),
|
|
347
|
+
isUpdateMode: z2.boolean().optional()
|
|
305
348
|
});
|
|
306
|
-
var OfflineEventSchema =
|
|
307
|
-
type:
|
|
308
|
-
data:
|
|
309
|
-
timestamp:
|
|
310
|
-
workerIndex:
|
|
349
|
+
var OfflineEventSchema = z2.object({
|
|
350
|
+
type: z2.enum(["test-begin", "test-end", "run-end"]),
|
|
351
|
+
data: z2.unknown(),
|
|
352
|
+
timestamp: z2.number(),
|
|
353
|
+
workerIndex: z2.number()
|
|
311
354
|
});
|
|
312
|
-
var OfflineReportSchema =
|
|
313
|
-
version:
|
|
314
|
-
generatedAt:
|
|
315
|
-
workers:
|
|
316
|
-
events:
|
|
355
|
+
var OfflineReportSchema = z2.object({
|
|
356
|
+
version: z2.number(),
|
|
357
|
+
generatedAt: z2.string(),
|
|
358
|
+
workers: z2.number(),
|
|
359
|
+
events: z2.array(OfflineEventSchema)
|
|
317
360
|
});
|
|
318
|
-
var
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
361
|
+
var ReportApiResponseSchema = z2.object({
|
|
362
|
+
tests: z2.record(z2.string(), TestDataSchema),
|
|
363
|
+
isUpdateMode: z2.boolean().optional(),
|
|
364
|
+
isRunning: z2.boolean().optional(),
|
|
365
|
+
runEnabled: z2.boolean().optional()
|
|
322
366
|
});
|
|
323
|
-
var
|
|
324
|
-
tests: z.record(z.string(), TestDataSchema),
|
|
325
|
-
isUpdateMode: z.boolean().optional()
|
|
326
|
-
});
|
|
327
|
-
var ClientBootstrapDataSchema = z.object({
|
|
367
|
+
var ClientBootstrapDataSchema = z2.object({
|
|
328
368
|
report: ReportApiResponseSchema.extend({
|
|
329
|
-
isUpdateMode:
|
|
369
|
+
isUpdateMode: z2.boolean()
|
|
330
370
|
}),
|
|
331
|
-
liveUpdates:
|
|
332
|
-
approvalEnabled:
|
|
333
|
-
approvalMessage:
|
|
371
|
+
liveUpdates: z2.boolean(),
|
|
372
|
+
approvalEnabled: z2.boolean(),
|
|
373
|
+
approvalMessage: z2.string().optional(),
|
|
374
|
+
runEnabled: z2.boolean().optional(),
|
|
375
|
+
isRunning: z2.boolean().optional()
|
|
334
376
|
});
|
|
335
|
-
var ImagesViewModeSchema =
|
|
377
|
+
var ImagesViewModeSchema = z2.enum(["side-by-side", "swap", "slide", "blend"]);
|
|
336
378
|
function safeParse(schema, data) {
|
|
337
379
|
const result = schema.safeParse(data);
|
|
338
380
|
if (result.success) {
|
|
@@ -484,7 +526,12 @@ function createMutableReportState(screenshotDir = "./screenshots") {
|
|
|
484
526
|
function applyTestBeginEvent(state, data) {
|
|
485
527
|
const { id, title, titlePath, browser, projectName, location } = data;
|
|
486
528
|
state.currentRunIds.add(id);
|
|
487
|
-
state.reportData.tests[id]
|
|
529
|
+
const existing = state.reportData.tests[id];
|
|
530
|
+
if (existing !== void 0) {
|
|
531
|
+
existing.status = "running";
|
|
532
|
+
return existing;
|
|
533
|
+
}
|
|
534
|
+
const created = {
|
|
488
535
|
id,
|
|
489
536
|
titlePath: titlePath ?? [],
|
|
490
537
|
browser: browser ?? "",
|
|
@@ -496,7 +543,8 @@ function applyTestBeginEvent(state, data) {
|
|
|
496
543
|
location,
|
|
497
544
|
status: "running"
|
|
498
545
|
};
|
|
499
|
-
|
|
546
|
+
state.reportData.tests[id] = created;
|
|
547
|
+
return created;
|
|
500
548
|
}
|
|
501
549
|
function applyTestEndEvent(state, data, options = {}) {
|
|
502
550
|
const test = state.reportData.tests[data.id];
|
|
@@ -534,11 +582,13 @@ function applyTestEndEvent(state, data, options = {}) {
|
|
|
534
582
|
diffCount
|
|
535
583
|
};
|
|
536
584
|
}
|
|
537
|
-
function finalizeRunEvent(state) {
|
|
585
|
+
function finalizeRunEvent(state, options = {}) {
|
|
538
586
|
state.reportData.isRunning = false;
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
587
|
+
if (options.preserveNonCurrent !== true) {
|
|
588
|
+
state.reportData.tests = Object.fromEntries(
|
|
589
|
+
Object.entries(state.reportData.tests).filter(([id]) => state.currentRunIds.has(id))
|
|
590
|
+
);
|
|
591
|
+
}
|
|
542
592
|
state.currentRunIds.clear();
|
|
543
593
|
const runTests = Object.values(state.reportData.tests).filter((test) => test !== void 0);
|
|
544
594
|
return {
|
|
@@ -554,6 +604,8 @@ export {
|
|
|
554
604
|
applyTestBeginEvent,
|
|
555
605
|
applyTestEndEvent,
|
|
556
606
|
finalizeRunEvent,
|
|
607
|
+
ApproveRequestBodySchema,
|
|
608
|
+
RunRequestBodySchema,
|
|
557
609
|
IncomingWebSocketMessageSchema,
|
|
558
610
|
TestBeginDataSchema,
|
|
559
611
|
TestEndDataSchema,
|
|
@@ -561,7 +613,6 @@ export {
|
|
|
561
613
|
RegisterDataSchema,
|
|
562
614
|
LoadedReportDataSchema,
|
|
563
615
|
OfflineReportSchema,
|
|
564
|
-
ApproveRequestBodySchema,
|
|
565
616
|
ClientBootstrapDataSchema,
|
|
566
617
|
safeParse,
|
|
567
618
|
withResolvedVisualNames,
|