@crvy/rprtr 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +33 -0
  3. package/dist/{chunk-HAFWYUNO.js → chunk-4YJL655E.js} +16 -4
  4. package/dist/{chunk-473CWZ4V.js → chunk-IFHYWPXG.js} +710 -281
  5. package/dist/cli.d.ts +5 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +24 -4
  8. package/dist/index.css +7 -0
  9. package/dist/index.js +152 -105
  10. package/dist/reporter-artifact-ops.d.ts +0 -2
  11. package/dist/reporter-artifact-ops.d.ts.map +1 -1
  12. package/dist/reporter.cjs +32 -38
  13. package/dist/reporter.d.ts +2 -1
  14. package/dist/reporter.d.ts.map +1 -1
  15. package/dist/reporter.js +27 -43
  16. package/dist/schemas/http.d.ts +2 -0
  17. package/dist/schemas/http.d.ts.map +1 -1
  18. package/dist/schemas.d.ts +14 -0
  19. package/dist/schemas.d.ts.map +1 -1
  20. package/dist/server/app.d.ts +6 -0
  21. package/dist/server/app.d.ts.map +1 -1
  22. package/dist/server/artifact-routes.d.ts.map +1 -1
  23. package/dist/server/docker-launcher.d.ts +27 -0
  24. package/dist/server/docker-launcher.d.ts.map +1 -0
  25. package/dist/server/docker-support.d.ts +66 -0
  26. package/dist/server/docker-support.d.ts.map +1 -0
  27. package/dist/server/handlers.d.ts +1 -1
  28. package/dist/server/handlers.d.ts.map +1 -1
  29. package/dist/server/launcher-resolver.d.ts +23 -0
  30. package/dist/server/launcher-resolver.d.ts.map +1 -0
  31. package/dist/server/playwright-config.d.ts +6 -0
  32. package/dist/server/playwright-config.d.ts.map +1 -1
  33. package/dist/server/routes-context.d.ts +6 -1
  34. package/dist/server/routes-context.d.ts.map +1 -1
  35. package/dist/server/routes.d.ts +7 -0
  36. package/dist/server/routes.d.ts.map +1 -1
  37. package/dist/server/run-controller.d.ts +19 -19
  38. package/dist/server/run-controller.d.ts.map +1 -1
  39. package/dist/server/run-launcher.d.ts +45 -0
  40. package/dist/server/run-launcher.d.ts.map +1 -0
  41. package/dist/server/run-mode.d.ts +15 -0
  42. package/dist/server/run-mode.d.ts.map +1 -0
  43. package/dist/server/server-factories.d.ts +21 -0
  44. package/dist/server/server-factories.d.ts.map +1 -0
  45. package/dist/server.cjs +885 -446
  46. package/dist/server.js +2 -2
  47. package/dist/types.d.ts +2 -0
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,42 @@ 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.3.0] - 2026-08-24
9
+
10
+ ### Added
11
+
12
+ - **reporter:** Portable artifacts mode via CRVY_RPRTR_PORTABLE_ARTIFACTS
13
+ - **server:** --update-snapshots run flag and docker-unavailable run reason
14
+ - **server:** Carry run mode and phase in run-status broadcasts
15
+ - **server:** Docker CLI helpers and container command resolution
16
+ - **server:** DockerLauncher spawning playwright runs in containers
17
+ - **server:** Run-mode resolution, docker launcher wiring, and docker CLI flags
18
+ - **ui:** Run mode badge, update-baselines action, and image-pull state
19
+
20
+ ### Changed
21
+
22
+ - **run-controller:** Extract RunLauncher strategy with LocalLauncher
23
+
24
+ ### Documentation
25
+
26
+ - **spec:** Docker browser execution design
27
+ - **plan:** Docker browser execution implementation plan
28
+ - Docker mode usage and options
29
+ - Docker rendering determinism findings; correct baseline arch guidance
30
+
31
+ ### Fixed
32
+
33
+ - **run-controller:** Make UI re-run work on Playwright 1.59+
34
+ - **server:** Surface auto-mode docker fallback warning
35
+ - **server:** Rewrite container paths in reporter register payloads
36
+ - **server:** Rewrite host paths in docker container command args
37
+ - **server:** Warn when --config path is unreachable inside container
38
+ - **reporter:** Content-addressed artifact names for static-host portability
39
+ - **server:** Route docker runs via rootDir-keyed --test-list with host paths
40
+
41
+ ### Testing
42
+
43
+ - CI-gated docker smoke test for containerized runs
8
44
  ## [0.2.4] - 2026-07-06
9
45
 
10
46
  ### Added
package/README.md CHANGED
@@ -122,6 +122,39 @@ If you generate a report on one operating system and then open it on another (fo
122
122
 
123
123
  For fully portable artifact loading across operating systems, run the reporter in CI mode (`ci: true`) and ship the `screenshots/` directory alongside the report JSON.
124
124
 
125
+ ## Docker Mode
126
+
127
+ Run Playwright browsers inside a pinned Docker container so screenshot baselines are reproducible across machines — no local browser or system-dependency installation required.
128
+
129
+ ```bash
130
+ npx crvy-rprtr --run-mode docker
131
+ ```
132
+
133
+ The server still runs on your host; only `playwright test` executes in the container, against the official `mcr.microsoft.com/playwright:v<your @playwright/test version>-noble` image with your project bind-mounted. Reporters stream results back live, and approve/update flows work unchanged.
134
+
135
+ | Mode | Behavior |
136
+ | ---------------- | ------------------------------------------------------------------------------- |
137
+ | `auto` (default) | Docker when a daemon is reachable, local on CI, warned local fallback otherwise |
138
+ | `docker` | Always Docker; runs fail fast with `docker-unavailable` when the daemon is down |
139
+ | `local` | Never Docker |
140
+
141
+ | Option | Description |
142
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143
+ | `--run-mode <mode>` | `local`, `docker`, or `auto` (default: `auto`) |
144
+ | `--docker-image <image>` | Custom image. With a custom image, the container-side package manager is auto-detected from your lockfile (`npx` / `pnpm exec` / `yarn` / `bunx`); the image must contain it |
145
+ | `--docker-platform <platform>` | `linux/amd64` or `linux/arm64` (default: host architecture) |
146
+
147
+ Programmatic equivalents: `startServer({ runMode: 'docker', docker: { image, platform, command, extraArgs } })`. `docker.command` overrides the container-side invocation verbatim (e.g. `['pnpm', 'exec', 'playwright']`); `docker.extraArgs` appends raw `docker run` flags.
148
+
149
+ Notes:
150
+
151
+ > **Important — baselines are image-specific, not architecture-specific.** Text rendering follows the image's fontconfig: Ubuntu-based images (including the default `mcr.microsoft.com/playwright:*-noble`) render text with subpixel (LCD) antialiasing and slight hinting, while Debian-based images (e.g. `node:24` + `playwright install --with-deps`) render grayscale with full hinting — different pixels _and_ slightly different text widths. Generate and verify baselines in the **same image** everywhere (CI and local), and regenerate baselines once after switching image flavor. See [docs/docker-screenshot-determinism.md](docs/docker-screenshot-determinism.md) for the full investigation.
152
+
153
+ - Baselines are **not** architecture-specific for typical DOM/text pages: amd64 and arm64 variants of the same image render bit-identically in practice (verified: 100/103 tests byte-identical between an amd64 CI runner and Apple Silicon). Use the native architecture on every host — do **not** pin `--docker-platform` to force amd64 emulation on Apple Silicon (Rosetta/QEMU is slower and less stable, and buys nothing). Residual risk: canvas 2D / complex SVG / WebGL content can show tiny cross-arch anti-aliasing diffs; handle per-test with `maxDiffPixels`.
154
+ - If your `playwright.config.ts` uses `webServer`, that server now starts inside the container: it must bind `0.0.0.0`, and hosts it references must resolve inside the container.
155
+ - Timezone and locale are pinned (`TZ=UTC`, `LANG=C.UTF-8`, `LC_ALL=C.UTF-8`) so date/number rendering in screenshots is stable; override via `docker.extraArgs` if you need a different locale under test.
156
+ - The "Run & update baselines" button (▶↻) regenerates baselines inside the container, keeping generation and verification in the same image.
157
+
125
158
  ## Programmatic API
126
159
 
127
160
  ```ts
@@ -1,3 +1,9 @@
1
+ // src/ci.ts
2
+ function isCI(env = process.env) {
3
+ const ci = env.CI;
4
+ return ci !== void 0 && ci !== "" && ci !== "false" && ci !== "0";
5
+ }
6
+
1
7
  // src/snapshot-path-resolver.ts
2
8
  import { createHash } from "crypto";
3
9
  import { basename, dirname, extname, join, parse, relative, resolve } from "path";
@@ -187,13 +193,14 @@ var RunTestDescriptorSchema = z.object({
187
193
  titlePath: z.array(z.string())
188
194
  });
189
195
  var RunRequestBodySchema = z.object({
190
- tests: z.array(RunTestDescriptorSchema).optional()
196
+ tests: z.array(RunTestDescriptorSchema).optional(),
197
+ update: z.boolean().optional()
191
198
  });
192
199
  var RunResponseSchema = z.discriminatedUnion("ok", [
193
200
  z.object({ ok: z.literal(true) }),
194
201
  z.object({
195
202
  ok: z.literal(false),
196
- reason: z.enum(["no-config", "already-running", "no-tests"])
203
+ reason: z.enum(["no-config", "already-running", "no-tests", "docker-unavailable"])
197
204
  })
198
205
  ]);
199
206
  var StopResponseSchema = z.discriminatedUnion("ok", [
@@ -300,7 +307,9 @@ var WebSocketMessageSchema = z2.discriminatedUnion("type", [
300
307
  z2.object({
301
308
  type: z2.literal("run-status"),
302
309
  data: z2.object({
303
- running: z2.boolean()
310
+ running: z2.boolean(),
311
+ mode: z2.enum(["local", "docker"]).optional(),
312
+ phase: z2.string().optional()
304
313
  })
305
314
  })
306
315
  ]);
@@ -330,6 +339,7 @@ var RunEndDataSchema = z2.object({
330
339
  var RegisterDataSchema = z2.object({
331
340
  playwrightSnapshotDir: z2.string().optional(),
332
341
  playwrightTestDir: z2.string().optional(),
342
+ playwrightRootDir: z2.string().optional(),
333
343
  playwrightSnapshotPathTemplate: z2.string().optional(),
334
344
  playwrightToHaveScreenshotPathTemplate: z2.string().optional(),
335
345
  configFile: z2.string().optional(),
@@ -362,7 +372,8 @@ var ReportApiResponseSchema = z2.object({
362
372
  tests: z2.record(z2.string(), TestDataSchema),
363
373
  isUpdateMode: z2.boolean().optional(),
364
374
  isRunning: z2.boolean().optional(),
365
- runEnabled: z2.boolean().optional()
375
+ runEnabled: z2.boolean().optional(),
376
+ runMode: z2.enum(["local", "docker"]).optional()
366
377
  });
367
378
  var ClientBootstrapDataSchema = z2.object({
368
379
  report: ReportApiResponseSchema.extend({
@@ -599,6 +610,7 @@ function finalizeRunEvent(state, options = {}) {
599
610
  }
600
611
 
601
612
  export {
613
+ isCI,
602
614
  isForeignAbsolutePath,
603
615
  createMutableReportState,
604
616
  applyTestBeginEvent,