@tracelane/playwright 0.1.0-alpha.6 → 0.1.0-alpha.8

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/README.md CHANGED
@@ -10,6 +10,10 @@
10
10
  [![downloads](https://img.shields.io/npm/dw/@tracelane/playwright.svg)](https://www.npmjs.com/package/@tracelane/playwright)
11
11
  [![license](https://img.shields.io/npm/l/@tracelane/playwright.svg)](https://github.com/Cubenest/rrweb-stack/blob/main/LICENSE)
12
12
  [![CI](https://github.com/Cubenest/rrweb-stack/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Cubenest/rrweb-stack/actions/workflows/ci.yml)
13
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Cubenest/rrweb-stack/badge)](https://scorecard.dev/viewer/?uri=github.com/Cubenest/rrweb-stack)
14
+ [![types](https://img.shields.io/npm/types/@tracelane/playwright.svg)](https://www.npmjs.com/package/@tracelane/playwright)
15
+ [![node](https://img.shields.io/node/v/@tracelane/playwright.svg)](https://www.npmjs.com/package/@tracelane/playwright)
16
+ ![status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)
13
17
 
14
18
  Docs: <https://tracelane.cubenest.in>
15
19
 
@@ -19,7 +23,7 @@ Docs: <https://tracelane.cubenest.in>
19
23
  npm install --save-dev @tracelane/playwright
20
24
  ```
21
25
 
22
- `@playwright/test` (>= 1.40) is a peer dependency — you already have it.
26
+ `@playwright/test` (>= 1.40) is a peer dependency — you already have it. Requires **Node >= 22**.
23
27
 
24
28
  ## Wire it (two edits)
25
29
 
@@ -55,19 +59,49 @@ Run your suite. On a failing test you get one `.html` file at `./tracelane-repor
55
59
 
56
60
  - **The fixture** owns the recording — and keeps it going across navigations, so the replay is one continuous session, not a set of per-page snapshots. It is the only place with a live `page` + `testInfo`, so it injects the rrweb bundle via `context.addInitScript` AND hooks `page.on('framenavigated')` to call `recorder.reinject` on every main-frame navigation (each navigation emits a `tracelane.nav` boundary marker in the replay). It starts the recorder before your test body, and — after it — builds + writes the report. It reuses `@tracelane/core`'s recorder and `@tracelane/report`'s HTML builder.
57
61
  - **The reporter** owns config only: it validates options at startup and bridges them to the fixture via `TRACELANE_*` env vars. By design it never touches `page`, prints nothing, and produces no end-of-run summary (the fixture writes the per-test reports).
58
- - **Failed-network capture** uses CDP on Chromium (4xx/5xx responses and no-response failures are surfaced into the report's network panel). On Firefox/WebKit it degrades silently to rrweb + console.
62
+ - **Network capture** is captured **in-page** by the framework-agnostic `rrweb/network@1` plugin — it works on **every browser** (Chromium, Firefox, WebKit) with no CDP, because it wraps `fetch`/`XHR` and reads `PerformanceObserver` entries from inside the page. Privacy-first: only URL/method/status/timing (headers + bodies off). On **Chromium** tracelane *additionally* uses CDP to enrich the panel with authoritative HTTP status for failed responses (`4xx`/`5xx`) and true no-response failures (CORS/DNS/offline/abort); the report merges the CDP rows over the in-page rows for the same request (real status wins). Off entirely when `capture.network` is `false`.
59
63
  - **Parallel-safe**: report filenames are namespaced by the Playwright **project name** and carry a millisecond timestamp. Different projects are isolated by name; parallel workers *within one project* share the project-name segment and rely on the timestamp (plus spec + title) to stay distinct.
60
64
  - **Coexists** with Playwright's own `trace` — keep `trace: 'on-first-retry'` if you like; tracelane writes a separate, self-contained artifact.
61
65
 
62
66
  ## Options
63
67
 
64
- | Option | Default | Notes |
65
- | --- | --- | --- |
66
- | `mode` | `'failed'` | `'failed'` writes a report only on failure; `'all'` writes one for every test. Overridable with `TRACELANE_MODE`. |
67
- | `outDir` | `'./tracelane-reports'` | Where reports are written. Overridable with `TRACELANE_OUT_DIR`. |
68
- | `captureNetwork` | `true` | CDP failed-network capture (Chromium-only). Overridable with `TRACELANE_CAPTURE_NETWORK`. |
68
+ | Option | Type | Default | Notes |
69
+ | --- | --- | --- | --- |
70
+ | `mode` | `'failed' \| 'all'` | `'failed'` | `'failed'` writes a report only on failure; `'all'` writes one for every test. Env: `TRACELANE_MODE`. |
71
+ | `outDir` | `string` | `'./tracelane-reports'` | Where reports are written. Env: `TRACELANE_OUT_DIR`. |
72
+ | `capture.rrweb` | `boolean` | `true` | Record the rrweb session. When `false`, no recorder starts and **no report is written** at all. Env: `TRACELANE_CAPTURE_RRWEB`. |
73
+ | `capture.network` | `boolean` | `true` | Network capture: the in-page `rrweb/network@1` plugin on **all browsers**, plus CDP enrichment (authoritative status + no-response failures) on Chromium. Env: `TRACELANE_CAPTURE_NETWORK`. Supersedes the deprecated top-level `captureNetwork`. |
74
+ | `capture.console` | `boolean` | `true` | Capture `console.*` via the rrweb console plugin. When `false` the console plugin patches nothing (`{ level: [] }`). Env: `TRACELANE_CAPTURE_CONSOLE`. |
75
+ | `capture.networkOptions` | `NetworkRecordOptions` | plugin defaults | Forwarded to the in-page network plugin (`recordHeaders`, `recordBody`, `payloadHostDenyList`, …). Defaults are privacy-first (headers + bodies off). Ignored when `capture.network` is `false`. **Function-valued props (`maskRequestFn`, `maskResponseFn`) are NOT supported** via reporter config — see below. Env: `TRACELANE_NETWORK_OPTIONS` (JSON). |
76
+ | `consolePluginOptions` | `ConsolePluginOptions` | plugin defaults | Forwarded to the in-page console plugin. Env: `TRACELANE_CONSOLE_OPTIONS` (JSON). |
77
+ | `security` | `boolean` | `true` | Advisory security-hygiene signals in the report. `false` disables both the `[tracelane.sec]` capture and the report-side analysis (the report omits the "Security hygiene (advisory)" section). Env: `TRACELANE_SECURITY`. |
78
+ | `report.footer` | `boolean` | `true` | Render the report's "Generated by tracelane" footer. `false` suppresses it. Env: `TRACELANE_FOOTER`. |
79
+ | `drainIntervalMs` | `number` | `500` (core default) | Node-side drain poll interval. Env: `TRACELANE_DRAIN_INTERVAL_MS`. |
80
+ | `cooldownMs` | `number` | `250` (core default) | Re-injection cooldown guard (suppresses double-init on hash/HMR navigation). Env: `TRACELANE_COOLDOWN_MS`. |
81
+ | `captureNetwork` | `boolean` | `true` | **Deprecated** — use `capture.network`. Kept for back-compat; `capture.network` wins when both are set. Env: `TRACELANE_CAPTURE_NETWORK`. |
69
82
 
70
- > Reporter options (`mode`, `outDir`, `captureNetwork`) are honored by the fixture the reporter bridges them to `TRACELANE_MODE` / `TRACELANE_OUT_DIR` / `TRACELANE_CAPTURE_NETWORK` at startup (only when those env vars are not already set). An explicit env var always wins over the reporter option.
83
+ The options type is published`import type { TraceLaneOptions } from '@tracelane/playwright'`.
84
+
85
+ > **The options→env bridge.** The Playwright fixture runs in a **separate worker process** and reads its configuration **only** from `TRACELANE_*` env vars. The reporter bridges its constructor options to those env vars at startup — but only when the env var is not already set, so an explicit env var (or CLI value) always wins. Boolean/number options bridge as strings; `capture.networkOptions` and `consolePluginOptions` bridge as JSON strings.
86
+
87
+ > **Mask functions are not supported via reporter config (worker-process limitation).** Because options cross to the fixture worker as env-var strings, the JSON bridge for `capture.networkOptions` cannot carry **function-valued** props — `maskRequestFn` / `maskResponseFn` are silently dropped (`JSON.stringify` strips them). Use only JSON-serializable masking options (`recordHeaders`, `recordBody`, `payloadHostDenyList`, …) when configuring through the reporter.
88
+
89
+ ## Security hygiene (advisory)
90
+
91
+ By default the report includes an advisory security-hygiene section derived from privacy-safe main-document response metadata captured on Chromium (`[tracelane.sec]` — security-header **presence** + cookie-flag hygiene; never header or cookie **values**). Set `security: false` to disable both the capture and the report-side analysis.
92
+
93
+ You can silence known-acceptable signals by committing a `tracelane.security.suppress.json` file in the project working directory; it's loaded at report-write time (a missing/malformed file never throws — it degrades to no suppressions):
94
+
95
+ ```json
96
+ {
97
+ "suppressions": [
98
+ { "signal": "missing-csp", "evidence": "https://app.test" },
99
+ { "signal": "insecure-cookie" }
100
+ ]
101
+ }
102
+ ```
103
+
104
+ It carries only advisory `{ signal?, evidence? }` rules — no secrets — so reading it from the working directory is safe.
71
105
 
72
106
  ## What this is NOT
73
107
 
@@ -82,4 +116,17 @@ Run your suite. On a failing test you get one `.html` file at `./tracelane-repor
82
116
 
83
117
  ## License
84
118
 
85
- Apache-2.0. See [`NOTICE`](./NOTICE) for bundled third-party software (the rrweb fork + console plugin).
119
+ Apache-2.0. See [`NOTICE`](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-playwright/NOTICE) for bundled third-party software (the rrweb fork + console plugin).
120
+
121
+ For the privacy/security posture of the capture (what is and isn't recorded, masking, and the advisory security-hygiene signals), see the [security notes](https://github.com/Cubenest/rrweb-stack/blob/main/docs/SECURITY-NOTES.md).
122
+
123
+ Full version history: [CHANGELOG](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-playwright/CHANGELOG.md).
124
+
125
+ ## Related packages
126
+
127
+ Part of the [tracelane](https://github.com/Cubenest/rrweb-stack) stack:
128
+
129
+ - [`@tracelane/wdio`](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-wdio/README.md) — the same recorder as a WebdriverIO reporter.
130
+ - [`@tracelane/cli`](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-cli/README.md) — one command that wires the recorder into your WebdriverIO and Playwright suites.
131
+ - [`@tracelane/core`](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-core/README.md) — the shared recorder engine.
132
+ - [`@tracelane/report`](https://github.com/Cubenest/rrweb-stack/blob/main/packages/tracelane-report/README.md) — the self-contained HTML report builder.
package/dist/options.d.ts CHANGED
@@ -1,7 +1,35 @@
1
- import type { Mode } from '@tracelane/core';
1
+ import type { NetworkRecordOptions } from '@cubenest/rrweb-core';
2
+ import type { ConsolePluginOptions, Mode } from '@tracelane/core';
2
3
  /** The default output directory for reports (matches @tracelane/wdio). */
3
4
  export declare const DEFAULT_OUT_DIR = "./tracelane-reports";
4
5
  type EnvLike = Record<string, string | undefined>;
6
+ /** Which capture channels are enabled (mirrors @tracelane/wdio §M.1). */
7
+ export interface CaptureOptions {
8
+ /** Record the rrweb session. Default `true`. When `false`, no recorder starts and no report is written. */
9
+ rrweb?: boolean;
10
+ /**
11
+ * Capture network requests. Default `true`. Supersedes the deprecated
12
+ * top-level {@link TraceLaneOptions.captureNetwork}. Captured in-page by the
13
+ * framework-agnostic `rrweb/network@1` plugin (all browsers, no CDP); on
14
+ * Chromium CDP additionally enriches failed responses.
15
+ */
16
+ network?: boolean;
17
+ /** Capture `console.*` via the rrweb console plugin. Default `true`. */
18
+ console?: boolean;
19
+ /**
20
+ * Options forwarded to the in-page rrweb network plugin
21
+ * (`getRecordNetworkPlugin`): `recordHeaders`, `recordBody`,
22
+ * `payloadHostDenyList`, etc. Defaults are privacy-first (headers + bodies
23
+ * off). Ignored when {@link network} is `false`.
24
+ *
25
+ * LIMITATION (worker-process bridge): function-valued props
26
+ * (`maskRequestFn`, `maskResponseFn`) are NOT supported via reporter config.
27
+ * The reporter bridges this object to the fixture as a JSON string, and
28
+ * functions cannot survive `JSON.stringify` / an env var — they are dropped
29
+ * silently. Use only JSON-serializable masking options here.
30
+ */
31
+ networkOptions?: NetworkRecordOptions;
32
+ }
5
33
  /** User-supplied options (all optional; passed to the reporter and/or fixture). */
6
34
  export interface TraceLaneOptions {
7
35
  /**
@@ -12,33 +40,72 @@ export interface TraceLaneOptions {
12
40
  /** Directory to write reports into. Default `'./tracelane-reports'`. `TRACELANE_OUT_DIR` overrides. */
13
41
  outDir?: string;
14
42
  /**
15
- * Capture failed network requests via CDP (Chromium-only). Default `true`.
16
- * Routed into the report's network panel through the rrweb console plugin.
43
+ * Capture network requests. Default `true`.
44
+ *
45
+ * @deprecated Use {@link CaptureOptions.network} (`capture: { network }`)
46
+ * instead. Kept for back-compat; `capture.network` wins when both are set.
47
+ *
48
+ * Captured in-page by the framework-agnostic `rrweb/network@1` plugin, which
49
+ * works on ALL browsers (Chromium/Firefox/WebKit) with no CDP. On Chromium,
50
+ * CDP additionally enriches the report with authoritative status for failed
51
+ * responses and true no-response failures (the report merges the two). Set
52
+ * `false` to disable network capture entirely (both channels).
17
53
  *
18
54
  * The reporter bridges this option to `TRACELANE_CAPTURE_NETWORK` at startup
19
55
  * (only when that env var is not already set), so the fixture honors it. An
20
56
  * explicit `TRACELANE_CAPTURE_NETWORK` env var always wins over this option.
21
- * To force-disable CDP capture regardless of reporter config, set:
22
- * `TRACELANE_CAPTURE_NETWORK=false` before running Playwright.
23
57
  */
24
58
  captureNetwork?: boolean;
59
+ /** Per-channel capture toggles (rrweb / network / console) + network masking. */
60
+ capture?: CaptureOptions;
61
+ /**
62
+ * Advisory security-hygiene signals in the report. Default `true`. Set
63
+ * `false` to disable both the `[tracelane.sec]` capture and the report-side
64
+ * analysis. Bridged via `TRACELANE_SECURITY` (`'false'` disables).
65
+ */
66
+ security?: boolean;
67
+ /** Report-output tweaks. */
68
+ report?: {
69
+ /** Render the report's "Generated by tracelane" footer. Default `true`. */
70
+ footer?: boolean;
71
+ };
72
+ /** Node-side drain poll interval in ms (ADR-0006). Default from @tracelane/core when unset. */
73
+ drainIntervalMs?: number;
74
+ /** Re-injection cooldown guard in ms (ADR-0006). Default from @tracelane/core when unset. */
75
+ cooldownMs?: number;
76
+ /**
77
+ * Options forwarded to the in-page rrweb console plugin. Bridged to the
78
+ * fixture as a JSON string, so only JSON-serializable props survive.
79
+ */
80
+ consolePluginOptions?: ConsolePluginOptions;
25
81
  }
26
- /** Fully-resolved options — every field present. */
82
+ /** Fully-resolved options — every always-present field present. */
27
83
  export interface ResolvedOptions {
28
84
  mode: Mode;
29
85
  outDir: string;
30
86
  captureNetwork: boolean;
87
+ captureRrweb: boolean;
88
+ captureConsole: boolean;
89
+ security: boolean;
90
+ footer: boolean;
91
+ drainIntervalMs?: number;
92
+ cooldownMs?: number;
93
+ networkOptions?: NetworkRecordOptions;
94
+ consolePluginOptions?: ConsolePluginOptions;
31
95
  }
32
96
  /**
33
97
  * Resolve user options into a fully-resolved shape, applying defaults and the
34
- * `TRACELANE_MODE` / `TRACELANE_OUT_DIR` / `TRACELANE_CAPTURE_NETWORK` env
35
- * overrides (env wins over config, matching @tracelane/core's resolveMode). An
36
- * invalid `TRACELANE_MODE` is ignored. `env` is injectable for testing.
98
+ * `TRACELANE_*` env overrides (env wins over config, matching @tracelane/core's
99
+ * resolveMode). An invalid `TRACELANE_MODE` is ignored. `env` is injectable for
100
+ * testing.
37
101
  *
38
- * `TRACELANE_CAPTURE_NETWORK=false` (case-insensitive) disables CDP network
39
- * capture in the fixture. The reporter bridges the `captureNetwork` option to
40
- * this env var at startup (when not already set), so the fixture receives it.
41
- * An explicit env var always wins over the reporter option.
102
+ * Env overrides:
103
+ * - `TRACELANE_MODE`, `TRACELANE_OUT_DIR`
104
+ * - `TRACELANE_CAPTURE_NETWORK` (`'false'` disables both the in-page plugin and
105
+ * the Chromium CDP enrichment) / `_RRWEB` / `_CONSOLE` (`'false'` disables)
106
+ * - `TRACELANE_SECURITY`, `TRACELANE_FOOTER` (`'false'` disables)
107
+ * - `TRACELANE_DRAIN_INTERVAL_MS`, `TRACELANE_COOLDOWN_MS` (parsed int; NaN ignored)
108
+ * - `TRACELANE_NETWORK_OPTIONS`, `TRACELANE_CONSOLE_OPTIONS` (JSON; bad JSON → undefined)
42
109
  */
43
110
  export declare function resolveOptions(opts?: TraceLaneOptions, env?: EnvLike): ResolvedOptions;
44
111
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,0EAA0E;AAC1E,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAElD,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,uGAAuG;IACvG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;CACzB;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,IAAI,GAAE,gBAAqB,EAC3B,GAAG,GAAE,OAAsB,GAC1B,eAAe,CASjB"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAElE,0EAA0E;AAC1E,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAElD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,2GAA2G;IAC3G,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,uGAAuG;IACvG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,MAAM,CAAC,EAAE;QACP,2EAA2E;QAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,+FAA+F;IAC/F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AA0CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,IAAI,GAAE,gBAAqB,EAC3B,GAAG,GAAE,OAAsB,GAC1B,eAAe,CAkDjB"}
package/dist/options.js CHANGED
@@ -1,10 +1,18 @@
1
1
  // User-facing options for the Playwright reporter + fixture, and resolveOptions
2
2
  // which normalizes them into the fully-resolved shape the session consumes.
3
3
  //
4
- // The option names mirror @tracelane/wdio (mode, outDir) and the env contract
5
- // mirrors @tracelane/core (TRACELANE_MODE) plus TRACELANE_OUT_DIR. MVP capture
6
- // surface is rrweb + console (always on) + failed-network (captureNetwork,
7
- // default on; Chromium-only at runtime — see playwright-session.ts).
4
+ // The option names mirror @tracelane/wdio (mode, outDir, capture.*, security,
5
+ // report.footer, drainIntervalMs, cooldownMs, consolePluginOptions) and the env
6
+ // contract mirrors @tracelane/core (TRACELANE_MODE) plus the TRACELANE_* bridge
7
+ // the reporter sets at startup.
8
+ //
9
+ // IMPORTANT — the worker-process bridge: the Playwright fixture runs in a
10
+ // SEPARATE worker process and reads configuration ONLY from TRACELANE_* env
11
+ // vars, which the Reporter (reporter.ts) bridges from its constructor options.
12
+ // Env vars are strings, so JSON-serializable options (networkOptions,
13
+ // consolePluginOptions) cross as JSON; FUNCTION-valued options (e.g. a network
14
+ // `maskRequestFn` / `maskResponseFn`) CANNOT cross this boundary and are NOT
15
+ // supported via reporter config — see the JSDoc on `capture.networkOptions`.
8
16
  /** The default output directory for reports (matches @tracelane/wdio). */
9
17
  export const DEFAULT_OUT_DIR = './tracelane-reports';
10
18
  function isMode(value) {
@@ -14,24 +22,94 @@ function isMode(value) {
14
22
  function defaultEnv() {
15
23
  return globalThis.process?.env ?? {};
16
24
  }
25
+ /** True unless the env var is present and (case-insensitively) `'false'`. */
26
+ function envDisables(value) {
27
+ return value !== undefined && value.toLowerCase() === 'false';
28
+ }
29
+ /**
30
+ * Resolve a boolean channel toggle: an env var (`'false'` disables, anything
31
+ * else enables) wins over the option, which defaults to `true`.
32
+ */
33
+ function resolveBoolChannel(envValue, optValue) {
34
+ if (envValue !== undefined)
35
+ return envValue.toLowerCase() !== 'false';
36
+ return optValue ?? true;
37
+ }
38
+ /** Parse an integer env var; return undefined for missing / NaN values. */
39
+ function parseIntEnv(value) {
40
+ if (value === undefined)
41
+ return undefined;
42
+ const n = Number.parseInt(value, 10);
43
+ return Number.isNaN(n) ? undefined : n;
44
+ }
45
+ /** Parse a JSON env var into an object; return undefined on parse failure. */
46
+ function parseJsonEnv(value) {
47
+ if (value === undefined)
48
+ return undefined;
49
+ try {
50
+ return JSON.parse(value);
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ }
17
56
  /**
18
57
  * Resolve user options into a fully-resolved shape, applying defaults and the
19
- * `TRACELANE_MODE` / `TRACELANE_OUT_DIR` / `TRACELANE_CAPTURE_NETWORK` env
20
- * overrides (env wins over config, matching @tracelane/core's resolveMode). An
21
- * invalid `TRACELANE_MODE` is ignored. `env` is injectable for testing.
58
+ * `TRACELANE_*` env overrides (env wins over config, matching @tracelane/core's
59
+ * resolveMode). An invalid `TRACELANE_MODE` is ignored. `env` is injectable for
60
+ * testing.
22
61
  *
23
- * `TRACELANE_CAPTURE_NETWORK=false` (case-insensitive) disables CDP network
24
- * capture in the fixture. The reporter bridges the `captureNetwork` option to
25
- * this env var at startup (when not already set), so the fixture receives it.
26
- * An explicit env var always wins over the reporter option.
62
+ * Env overrides:
63
+ * - `TRACELANE_MODE`, `TRACELANE_OUT_DIR`
64
+ * - `TRACELANE_CAPTURE_NETWORK` (`'false'` disables both the in-page plugin and
65
+ * the Chromium CDP enrichment) / `_RRWEB` / `_CONSOLE` (`'false'` disables)
66
+ * - `TRACELANE_SECURITY`, `TRACELANE_FOOTER` (`'false'` disables)
67
+ * - `TRACELANE_DRAIN_INTERVAL_MS`, `TRACELANE_COOLDOWN_MS` (parsed int; NaN ignored)
68
+ * - `TRACELANE_NETWORK_OPTIONS`, `TRACELANE_CONSOLE_OPTIONS` (JSON; bad JSON → undefined)
27
69
  */
28
70
  export function resolveOptions(opts = {}, env = defaultEnv()) {
29
71
  const mode = isMode(env.TRACELANE_MODE) ? env.TRACELANE_MODE : (opts.mode ?? 'failed');
30
72
  const outDir = env.TRACELANE_OUT_DIR ?? opts.outDir ?? DEFAULT_OUT_DIR;
73
+ // Network-on: env wins; else capture.network ?? legacy captureNetwork ?? true.
31
74
  const envCaptureNetwork = env.TRACELANE_CAPTURE_NETWORK;
32
75
  const captureNetwork = envCaptureNetwork !== undefined
33
76
  ? envCaptureNetwork.toLowerCase() !== 'false'
34
- : (opts.captureNetwork ?? true);
35
- return { mode, outDir, captureNetwork };
77
+ : (opts.capture?.network ?? opts.captureNetwork ?? true);
78
+ const captureRrweb = resolveBoolChannel(env.TRACELANE_CAPTURE_RRWEB, opts.capture?.rrweb);
79
+ const captureConsole = resolveBoolChannel(env.TRACELANE_CAPTURE_CONSOLE, opts.capture?.console);
80
+ const security = envDisables(env.TRACELANE_SECURITY)
81
+ ? false
82
+ : env.TRACELANE_SECURITY !== undefined
83
+ ? true
84
+ : (opts.security ?? true);
85
+ const footer = envDisables(env.TRACELANE_FOOTER)
86
+ ? false
87
+ : env.TRACELANE_FOOTER !== undefined
88
+ ? true
89
+ : (opts.report?.footer ?? true);
90
+ const drainIntervalMs = parseIntEnv(env.TRACELANE_DRAIN_INTERVAL_MS) ?? opts.drainIntervalMs;
91
+ const cooldownMs = parseIntEnv(env.TRACELANE_COOLDOWN_MS) ?? opts.cooldownMs;
92
+ // JSON-serializable masking options: env (JSON) wins over the option.
93
+ const networkOptions = parseJsonEnv(env.TRACELANE_NETWORK_OPTIONS) ??
94
+ opts.capture?.networkOptions;
95
+ const consolePluginOptions = parseJsonEnv(env.TRACELANE_CONSOLE_OPTIONS) ?? opts.consolePluginOptions;
96
+ const resolved = {
97
+ mode,
98
+ outDir,
99
+ captureNetwork,
100
+ captureRrweb,
101
+ captureConsole,
102
+ security,
103
+ footer,
104
+ };
105
+ if (drainIntervalMs !== undefined)
106
+ resolved.drainIntervalMs = drainIntervalMs;
107
+ if (cooldownMs !== undefined)
108
+ resolved.cooldownMs = cooldownMs;
109
+ if (networkOptions !== undefined)
110
+ resolved.networkOptions = networkOptions;
111
+ if (consolePluginOptions !== undefined)
112
+ resolved.consolePluginOptions = consolePluginOptions;
113
+ return resolved;
36
114
  }
37
115
  //# sourceMappingURL=options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,qEAAqE;AAIrE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAiCrD,SAAS,MAAM,CAAC,KAAyB;IACvC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,CAAC;AAC/C,CAAC;AAED,yEAAyE;AACzE,SAAS,UAAU;IACjB,OAAQ,UAA8C,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAyB,EAAE,EAC3B,MAAe,UAAU,EAAE;IAE3B,MAAM,IAAI,GAAS,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC;IACvE,MAAM,iBAAiB,GAAG,GAAG,CAAC,yBAAyB,CAAC;IACxD,MAAM,cAAc,GAClB,iBAAiB,KAAK,SAAS;QAC7B,CAAC,CAAC,iBAAiB,CAAC,WAAW,EAAE,KAAK,OAAO;QAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC;IACpC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,gCAAgC;AAChC,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,+EAA+E;AAC/E,sEAAsE;AACtE,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAK7E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAiGrD,SAAS,MAAM,CAAC,KAAyB;IACvC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,CAAC;AAC/C,CAAC;AAED,yEAAyE;AACzE,SAAS,UAAU;IACjB,OAAQ,UAA8C,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED,6EAA6E;AAC7E,SAAS,WAAW,CAAC,KAAyB;IAC5C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,QAA4B,EAAE,QAA6B;IACrF,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;IACtE,OAAO,QAAQ,IAAI,IAAI,CAAC;AAC1B,CAAC;AAED,2EAA2E;AAC3E,SAAS,WAAW,CAAC,KAAyB;IAC5C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,8EAA8E;AAC9E,SAAS,YAAY,CAAI,KAAyB;IAChD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAyB,EAAE,EAC3B,MAAe,UAAU,EAAE;IAE3B,MAAM,IAAI,GAAS,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC;IAEvE,+EAA+E;IAC/E,MAAM,iBAAiB,GAAG,GAAG,CAAC,yBAAyB,CAAC;IACxD,MAAM,cAAc,GAClB,iBAAiB,KAAK,SAAS;QAC7B,CAAC,CAAC,iBAAiB,CAAC,WAAW,EAAE,KAAK,OAAO;QAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC;IAE7D,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1F,MAAM,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhG,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAClD,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,GAAG,CAAC,kBAAkB,KAAK,SAAS;YACpC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC9C,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,GAAG,CAAC,gBAAgB,KAAK,SAAS;YAClC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;IAEpC,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC;IAC7F,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;IAE7E,sEAAsE;IACtE,MAAM,cAAc,GAClB,YAAY,CAAuB,GAAG,CAAC,yBAAyB,CAAC;QACjE,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;IAC/B,MAAM,oBAAoB,GACxB,YAAY,CAAuB,GAAG,CAAC,yBAAyB,CAAC,IAAI,IAAI,CAAC,oBAAoB,CAAC;IAEjG,MAAM,QAAQ,GAAoB;QAChC,IAAI;QACJ,MAAM;QACN,cAAc;QACd,YAAY;QACZ,cAAc;QACd,QAAQ;QACR,MAAM;KACP,CAAC;IACF,IAAI,eAAe,KAAK,SAAS;QAAE,QAAQ,CAAC,eAAe,GAAG,eAAe,CAAC;IAC9E,IAAI,UAAU,KAAK,SAAS;QAAE,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/D,IAAI,cAAc,KAAK,SAAS;QAAE,QAAQ,CAAC,cAAc,GAAG,cAAc,CAAC;IAC3E,IAAI,oBAAoB,KAAK,SAAS;QAAE,QAAQ,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;IAC7F,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-session.d.ts","sourceRoot":"","sources":["../src/playwright-session.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,KAAK,QAAQ,EAAwC,MAAM,iBAAiB,CAAC;AAEtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,oFAAoF;IACpF,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,sFAAsF;AACtF,wBAAsB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAsFzE;AAoBD,qFAAqF;AACrF,wBAAsB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B9F;AAED,mFAAmF;AACnF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAOf"}
1
+ {"version":3,"file":"playwright-session.d.ts","sourceRoot":"","sources":["../src/playwright-session.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,oFAAoF;IACpF,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAeD,sFAAsF;AACtF,wBAAsB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAyHzE;AAoBD,qFAAqF;AACrF,wBAAsB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC9F;AAED,mFAAmF;AACnF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -10,10 +10,12 @@
10
10
  // recorder's own start() (which evals the bundle + installs the in-page buffer
11
11
  // in the CURRENT document). The recorder then drains events Node-side on its
12
12
  // poll loop and at finalize (ADR-0006).
13
- import { attachNetworkCapture, createRecorder } from '@tracelane/core';
13
+ import { cwd } from 'node:process';
14
+ import { attachNetworkCapture, createRecorder, } from '@tracelane/core';
14
15
  import { writeReport } from '@tracelane/report';
15
16
  import { createPlaywrightExecutor } from './playwright-executor.js';
16
17
  import { isPassed, mapStatus } from './result-status.js';
18
+ import { loadSecuritySuppressions } from './security-suppress.js';
17
19
  /** The Playwright browser-type name, when resolvable from the page's context. */
18
20
  function browserNameOf(page) {
19
21
  try {
@@ -23,9 +25,29 @@ function browserNameOf(page) {
23
25
  return undefined;
24
26
  }
25
27
  }
28
+ /**
29
+ * Resolve the console-plugin options: when `captureConsole` is false, pass
30
+ * `{ level: [] }` so the rrweb console plugin patches no `console.*` methods
31
+ * and installs no error/rejection listeners — i.e. console capture is off
32
+ * (mirrors @tracelane/wdio). Otherwise forward any user-supplied
33
+ * `consolePluginOptions` (the core recorder applies its defaults when none are
34
+ * given, so `undefined` is returned to keep that behavior).
35
+ */
36
+ function resolveConsolePluginOptions(options) {
37
+ if (options.captureConsole === false)
38
+ return { level: [] };
39
+ return options.consolePluginOptions;
40
+ }
26
41
  /** Inject the rrweb bundle on the context, build the executor, start the recorder. */
27
42
  export async function runStart(input) {
28
43
  const { page, options, rrwebBundle } = input;
44
+ // rrweb opt-out: when capture.rrweb is false, no recorder starts and no
45
+ // report is written (mirrors @tracelane/wdio `capture.rrweb:false`). We skip
46
+ // the context injection + CDP entirely. The returned session is disabled, so
47
+ // runFinalize writes nothing. Default-on: only an explicit `false` disables.
48
+ if (options.captureRrweb === false) {
49
+ return { recorder: undefined, disabled: true };
50
+ }
29
51
  const context = page.context();
30
52
  // Inject on the context so newly-created / navigated documents get rrweb
31
53
  // before any app script runs.
@@ -48,30 +70,56 @@ export async function runStart(input) {
48
70
  }
49
71
  catch {
50
72
  cdp = undefined; // no CDP; rrweb+console still work
51
- console.warn('[tracelane] could not open a CDP session; network capture unavailable, degrading to rrweb+console only.');
73
+ console.warn('[tracelane] could not open a CDP session; CDP network enrichment unavailable, continuing with in-page rrweb network capture.');
52
74
  }
53
75
  }
54
76
  // ONE executor for both network capture and the recorder (recorder uses only
55
77
  // execute(); cdp/on are used solely by attachNetworkCapture).
56
78
  const executor = createPlaywrightExecutor(page, cdp);
57
- const recorder = createRecorder({
79
+ const recorderOptions = {
58
80
  executor,
59
81
  rrwebBundle,
60
82
  mode: options.mode,
61
- // MVP: in-page network plugin off; the CDP path above is the network
62
- // channel. The recorder still captures rrweb + console on all browsers.
63
- });
83
+ };
84
+ // Drain/cooldown tuning (ADR-0006): forward only when set, else the core
85
+ // recorder applies its defaults.
86
+ if (options.drainIntervalMs !== undefined) {
87
+ recorderOptions.drainIntervalMs = options.drainIntervalMs;
88
+ }
89
+ if (options.cooldownMs !== undefined) {
90
+ recorderOptions.cooldownMs = options.cooldownMs;
91
+ }
92
+ // Console capture: `{ level: [] }` disables it; otherwise the user's options
93
+ // (or undefined → core defaults).
94
+ const consolePluginOptions = resolveConsolePluginOptions(options);
95
+ if (consolePluginOptions !== undefined) {
96
+ recorderOptions.consolePluginOptions = consolePluginOptions;
97
+ }
98
+ // In-page rrweb network plugin (`rrweb/network@1`): the framework-agnostic
99
+ // network channel that works on ALL browsers (Chromium/Firefox/WebKit) with
100
+ // no CDP — it wraps fetch/XHR + reads PerformanceObserver from inside the
101
+ // page. Privacy-first defaults (`{}`): URL/method/status/timing only, headers
102
+ // + bodies off. On Chromium the CDP path above ALSO runs and enriches these
103
+ // rows with authoritative status + true no-response failures; the report
104
+ // merges the two (real status wins). Mirrors @tracelane/wdio. Off entirely
105
+ // when `captureNetwork` is false.
106
+ if (options.captureNetwork) {
107
+ recorderOptions.networkPluginOptions =
108
+ options.networkOptions ?? {};
109
+ }
110
+ const recorder = createRecorder(recorderOptions);
64
111
  // Network capture is best-effort: if it fails, detach CDP and continue.
65
112
  if (cdp) {
66
113
  try {
67
114
  await attachNetworkCapture(executor, {
115
+ security: options.security,
68
116
  onSecurityMeta: (m) => recorder.addCustomEvent('tracelane.sec', m),
69
117
  });
70
118
  }
71
119
  catch {
72
120
  await cdp.detach().catch(() => { });
73
121
  cdp = undefined;
74
- console.warn('[tracelane] network capture unavailable (CDP); degrading to rrweb+console only.');
122
+ console.warn('[tracelane] CDP network enrichment unavailable; continuing with in-page rrweb network capture.');
75
123
  }
76
124
  }
77
125
  // Capture start is best-effort: a CSP / injection failure must NOT fail the
@@ -144,6 +192,10 @@ export async function runFinalize(session, input) {
144
192
  });
145
193
  if (!shouldBuildReport)
146
194
  return;
195
+ // Load the optional suppression file at report-write time. The loader never
196
+ // throws and falls back to `[]`, so a missing/malformed file can't break the
197
+ // report. Skip the read entirely when security is off.
198
+ const securitySuppress = options.security ? loadSecuritySuppressions(cwd()) : [];
147
199
  writeReport({
148
200
  outDir: options.outDir,
149
201
  // project.name namespaces the filename so parallel projects/workers never
@@ -151,6 +203,9 @@ export async function runFinalize(session, input) {
151
203
  cid: testInfo.project?.name,
152
204
  events,
153
205
  meta: buildMeta(testInfo, session),
206
+ footer: options.footer,
207
+ security: options.security,
208
+ securitySuppress,
154
209
  });
155
210
  }
156
211
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-session.js","sourceRoot":"","sources":["../src/playwright-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"playwright-session.js","sourceRoot":"","sources":["../src/playwright-session.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,cAAc,CAAC;AAErE;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;gBACpC,IAAI,GAAE,gBAAqB;IA8BvC,4EAA4E;IAC5E,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI;IAIjD,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIvD,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAKrD,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;CAKjC;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,cAAc,CAAC;AAoBrE;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;gBACpC,IAAI,GAAE,gBAAqB;IAiEvC,4EAA4E;IAC5E,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI;IAIjD,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIvD,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAKrD,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;CAKjC;AAED,eAAe,iBAAiB,CAAC"}
package/dist/reporter.js CHANGED
@@ -15,6 +15,25 @@
15
15
  // The reporter does NOT tally pass/fail counts and does NOT print any
16
16
  // end-of-run summary. All per-test reporting is handled by the fixture.
17
17
  import { resolveOptions } from './options.js';
18
+ /**
19
+ * Serialize a JSON-bridgeable option to a string for the env bridge, or
20
+ * `undefined` when there's nothing to bridge. `JSON.stringify` silently drops
21
+ * function-valued props (e.g. network `maskRequestFn` / `maskResponseFn`) —
22
+ * those cannot survive the worker-process env boundary, a documented
23
+ * limitation. Returns `undefined` if the result is empty (`{}`) or fails.
24
+ */
25
+ function bridgeJson(value) {
26
+ if (value === undefined || value === null)
27
+ return undefined;
28
+ try {
29
+ const json = JSON.stringify(value);
30
+ // `{}` carries no information once functions are stripped — skip it.
31
+ return json === undefined || json === '{}' ? undefined : json;
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
18
37
  /**
19
38
  * tracelane's Playwright reporter. Pair it with the fixture
20
39
  * (`import { test } from '@tracelane/playwright/fixture'`) — the fixture records
@@ -27,15 +46,28 @@ export class TraceLaneReporter {
27
46
  resolveOptions(opts);
28
47
  const env = globalThis.process?.env;
29
48
  if (env !== undefined) {
30
- if (opts.mode !== undefined && env.TRACELANE_MODE === undefined) {
31
- env.TRACELANE_MODE = opts.mode;
32
- }
33
- if (opts.outDir !== undefined && env.TRACELANE_OUT_DIR === undefined) {
34
- env.TRACELANE_OUT_DIR = opts.outDir;
35
- }
36
- if (opts.captureNetwork !== undefined && env.TRACELANE_CAPTURE_NETWORK === undefined) {
37
- env.TRACELANE_CAPTURE_NETWORK = String(opts.captureNetwork);
38
- }
49
+ // Each option is bridged only when its env var is unset, so an explicit
50
+ // env var / CLI value always wins.
51
+ const set = (key, value) => {
52
+ if (value !== undefined && env[key] === undefined)
53
+ env[key] = value;
54
+ };
55
+ set('TRACELANE_MODE', opts.mode);
56
+ set('TRACELANE_OUT_DIR', opts.outDir);
57
+ // capture.network (preferred) wins over the deprecated top-level captureNetwork.
58
+ const network = opts.capture?.network ?? opts.captureNetwork;
59
+ set('TRACELANE_CAPTURE_NETWORK', network !== undefined ? String(network) : undefined);
60
+ set('TRACELANE_CAPTURE_RRWEB', opts.capture?.rrweb !== undefined ? String(opts.capture.rrweb) : undefined);
61
+ set('TRACELANE_CAPTURE_CONSOLE', opts.capture?.console !== undefined ? String(opts.capture.console) : undefined);
62
+ set('TRACELANE_SECURITY', opts.security !== undefined ? String(opts.security) : undefined);
63
+ set('TRACELANE_FOOTER', opts.report?.footer !== undefined ? String(opts.report.footer) : undefined);
64
+ set('TRACELANE_DRAIN_INTERVAL_MS', opts.drainIntervalMs !== undefined ? String(opts.drainIntervalMs) : undefined);
65
+ set('TRACELANE_COOLDOWN_MS', opts.cooldownMs !== undefined ? String(opts.cooldownMs) : undefined);
66
+ // JSON-serializable masking options. JSON.stringify naturally drops
67
+ // function-valued props (maskRequestFn / maskResponseFn) — they cannot
68
+ // cross the worker-process env bridge, a documented limitation.
69
+ set('TRACELANE_NETWORK_OPTIONS', bridgeJson(opts.capture?.networkOptions));
70
+ set('TRACELANE_CONSOLE_OPTIONS', bridgeJson(opts.consolePluginOptions));
39
71
  }
40
72
  }
41
73
  /** The fixture + Playwright own the run output; this reporter is silent. */
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6DAA6D;AAC7D,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,iEAAiE;AACjE,8EAA8E;AAC9E,8CAA8C;AAC9C,2EAA2E;AAC3E,8EAA8E;AAC9E,iFAAiF;AACjF,+EAA+E;AAC/E,0EAA0E;AAC1E,EAAE;AACF,sEAAsE;AACtE,wEAAwE;AAUxE,OAAO,EAAyB,cAAc,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAC5B,YAAY,OAAyB,EAAE;QACrC,yDAAyD;QACzD,cAAc,CAAC,IAAI,CAAC,CAAC;QAcrB,MAAM,GAAG,GAAI,UAAgD,CAAC,OAAO,EAAE,GAAG,CAAC;QAC3E,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAChE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;gBACrE,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;YACtC,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,GAAG,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;gBACrF,GAAG,CAAC,yBAAyB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,aAAa;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,OAAmB,EAAE,MAAa;QACxC,kEAAkE;IACpE,CAAC;IAED,WAAW,CAAC,KAAe,EAAE,OAAmB;QAC9C,mDAAmD;IACrD,CAAC;IAED,SAAS,CAAC,KAAe,EAAE,OAAmB;QAC5C,2EAA2E;QAC3E,0BAA0B;IAC5B,CAAC;IAED,KAAK,CAAC,OAAmB;QACvB,0EAA0E;QAC1E,2EAA2E;QAC3E,8BAA8B;IAChC,CAAC;CACF;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Suppression } from '@tracelane/report';
2
+ /** The fixed filename looked up in the project cwd. */
3
+ export declare const SUPPRESS_FILE_NAME = "tracelane.security.suppress.json";
4
+ /**
5
+ * Load `tracelane.security.suppress.json` from `cwd`, if present. Returns the
6
+ * parsed suppression rules, or `[]` when the file is missing/unreadable/
7
+ * malformed/wrong-shaped. Never throws.
8
+ */
9
+ export declare function loadSecuritySuppressions(cwd: string): Suppression[];
10
+ //# sourceMappingURL=security-suppress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-suppress.d.ts","sourceRoot":"","sources":["../src/security-suppress.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AA0BrE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAUnE"}
@@ -0,0 +1,58 @@
1
+ // Optional security-suppression file loader (ported from @tracelane/wdio).
2
+ //
3
+ // tracelane's advisory security analyzer (`@tracelane/security`) accepts a list
4
+ // of `Suppression` rules to silence known-acceptable signals. To let teams
5
+ // commit those rules alongside their suite, the playwright adapter looks for a
6
+ // `tracelane.security.suppress.json` in the project cwd at report-write time.
7
+ //
8
+ // This loader is deliberately defensive: a missing, unreadable, malformed, or
9
+ // wrong-shaped file MUST NEVER throw and MUST NEVER break the report. Any of
10
+ // those cases degrade to `[]` (no suppressions). The file only ever carries
11
+ // advisory `{ signal?, evidence? }` rules — no secrets — so reading it from cwd
12
+ // is safe (P1 security MVP privacy invariant).
13
+ import { existsSync, readFileSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ /** The fixed filename looked up in the project cwd. */
16
+ export const SUPPRESS_FILE_NAME = 'tracelane.security.suppress.json';
17
+ /**
18
+ * Coerce arbitrary parsed JSON into a `Suppression[]`, leniently:
19
+ * - a bare array → used as-is;
20
+ * - an object with a `suppressions` array → that array;
21
+ * - anything else → `[]`.
22
+ *
23
+ * Element shape is not validated beyond "is an object" — the analyzer reads
24
+ * only `signal` / `evidence` and ignores the rest, so a loose pass-through is
25
+ * both safe and forgiving of hand-edited files.
26
+ */
27
+ function coerceSuppressions(parsed) {
28
+ const arr = Array.isArray(parsed)
29
+ ? parsed
30
+ : isRecord(parsed) && Array.isArray(parsed.suppressions)
31
+ ? parsed.suppressions
32
+ : undefined;
33
+ if (!arr)
34
+ return [];
35
+ return arr.filter(isRecord);
36
+ }
37
+ function isRecord(v) {
38
+ return typeof v === 'object' && v !== null;
39
+ }
40
+ /**
41
+ * Load `tracelane.security.suppress.json` from `cwd`, if present. Returns the
42
+ * parsed suppression rules, or `[]` when the file is missing/unreadable/
43
+ * malformed/wrong-shaped. Never throws.
44
+ */
45
+ export function loadSecuritySuppressions(cwd) {
46
+ const filePath = join(cwd, SUPPRESS_FILE_NAME);
47
+ try {
48
+ if (!existsSync(filePath))
49
+ return [];
50
+ const raw = readFileSync(filePath, 'utf8');
51
+ return coerceSuppressions(JSON.parse(raw));
52
+ }
53
+ catch {
54
+ // Missing/unreadable/malformed file must never break the report.
55
+ return [];
56
+ }
57
+ }
58
+ //# sourceMappingURL=security-suppress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-suppress.js","sourceRoot":"","sources":["../src/security-suppress.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,+EAA+E;AAC/E,8EAA8E;AAC9E,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,+CAA+C;AAE/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,uDAAuD;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,kCAAkC,CAAC;AAErE;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAAC,MAAe;IACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;YACtD,CAAC,CAAC,MAAM,CAAC,YAAY;YACrB,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAkB,CAAC;AAC/C,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;QACjE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tracelane/playwright",
3
- "version": "0.1.0-alpha.6",
4
- "description": "Playwright reporter + auto-fixture that writes a self-contained replayable HTML report on test failure (rrweb + console + failed-network). No SaaS.",
3
+ "version": "0.1.0-alpha.8",
4
+ "description": "Playwright reporter + auto-fixture that writes a self-contained replayable HTML report on failed tests — or every test in `all` mode (rrweb + console + failed-network). No SaaS.",
5
5
  "keywords": [
6
6
  "tracelane",
7
7
  "playwright",
@@ -41,8 +41,8 @@
41
41
  "README.md"
42
42
  ],
43
43
  "dependencies": {
44
- "@tracelane/core": "0.1.0-alpha.15",
45
- "@tracelane/report": "0.1.0-alpha.18"
44
+ "@tracelane/core": "0.1.0-alpha.17",
45
+ "@tracelane/report": "0.1.0-alpha.20"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "@playwright/test": ">=1.40.0"
@@ -51,7 +51,7 @@
51
51
  "@playwright/test": "^1.60.0",
52
52
  "esbuild": "^0.28.0",
53
53
  "tsx": "^4.19.0",
54
- "@cubenest/rrweb-core": "0.1.0-alpha.6"
54
+ "@cubenest/rrweb-core": "0.1.0-alpha.7"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public",