@reportforge/playwright-pdf 0.8.1 → 0.10.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.
- package/README.md +28 -0
- package/dist/cli/index.js +17 -1
- package/dist/index.d.mts +71 -1
- package/dist/index.d.ts +71 -1
- package/dist/index.js +545 -14
- package/dist/index.mjs +541 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ Three templates, one reporter. Every PDF is fully offline — fonts, charts, and
|
|
|
53
53
|
- **Dynamic filenames** — `{date}`, `{branch}`, `{status}` tokens in the output path
|
|
54
54
|
- **Instant demo report** — `npx @reportforge/playwright-pdf demo` generates a realistic sample PDF before subscribing — no license key required
|
|
55
55
|
- **CI/CD snippets** — GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps
|
|
56
|
+
- **Live runs** — opt-in `live` streams per-test progress to an unguessable watch link printed at run start; all shards of one CI run converge on a single live dashboard while tests execute. The PDF is still produced at the end, unchanged
|
|
56
57
|
- **Shard merging** — combine N Playwright JSON shard reports into one PDF via `shardResults`; accepts glob patterns or explicit paths
|
|
57
58
|
- **Notifications** — post pass/fail summaries to Slack, Teams, Discord, or email after each run; configurable trigger (`always` / `failure` / `success`) per channel; email supports optional PDF attachment via `attachPdf`
|
|
58
59
|
- **Flakiness trend** — top-N flakiest tests table with per-test dot sparkline across stored history runs in the `detailed` template; `flakinessTopN` option (default 5, `0` disables)
|
|
@@ -196,6 +197,7 @@ All options are the second element of the reporter tuple.
|
|
|
196
197
|
| `notify` | `object` | — | Notification channels: `slack`, `teams`, `discord` (each `{ url, enabled, on }`), `email` (`{ to, enabled, on, attachPdf }`). See the Notifications docs. |
|
|
197
198
|
| `failureAnalysis` | `object` | `{ enabled: true }` | Offline failure root-cause analysis (embedded Naive Bayes; no runtime network). Fields: `enabled` (default `true`), `maxClusters` (default `10`), `minStrength` (`weak`\|`moderate`\|`strong`, default `weak`), `maxFailuresToAnalyse` (default `500`), `collectUnclassified` (default `true`), `autoUpdateModel` (default `true`). See the Failure Analysis docs. |
|
|
198
199
|
| `capture` | `object` | `{}` (off) | Opt-in rich execution capture for the defect log (reporter-side; no fixtures, no test-code changes). Fields: `steps` (compacted repro-steps trail from the Playwright step tree, default `false`), `apiSteps` (include granular `pw:api` click/fill/goto actions in the trail; off by default the trail shows only `test.step` intent + `expect` assertions + the failing action, default `false`), `console` (Node stdout/stderr tail, default `false`), `evidence` (trace/video file links, default `false`), `maxSteps` (default `50`), `maxConsoleLines` (default `50`). Renders in the Defect Log section of the `detailed` template. |
|
|
200
|
+
| `live` | `object` | `{}` (off) | Opt-in live test-execution streaming. When `enabled`, the reporter prints an unguessable watch link to the CI logs at run start and streams per-test progress to the hosted dashboard while tests run — all shards of one CI run converge on a single live view. Fields: `enabled` (default `false`), `runId` (override the auto-derived run id), `serverUrl` (override the streaming server), `steps` (`none`\|`failed`\|`all`, default `failed`), `console` (stream stdout/stderr tails, default `false`), `flushMs` (batch debounce 500–10000, default `2000`). The PDF at the end of the run is unaffected. Requires an active subscription with the `live` entitlement. See the Live Runs docs. |
|
|
199
201
|
| `historyFile` | `string` | `~/.reportforge/{key}/history.json` | Path to the history JSON file. Relative paths resolve from `cwd`. Enables pass-rate trending charts in the `detailed` template. |
|
|
200
202
|
| `historySize` | `number` | `10` | Maximum number of test runs to keep in the history file (integer ≥ 2). Older runs are pruned on append. |
|
|
201
203
|
| `showTrend` | `boolean` | `true` | Show the pass-rate sparkline and delta badge in the `detailed` template. Set to `false` to disable history tracking entirely. |
|
|
@@ -207,6 +209,31 @@ All options are the second element of the reporter tuple.
|
|
|
207
209
|
|
|
208
210
|
Full reference: [reportforge.org/docs/configuration](https://reportforge.org/docs/configuration).
|
|
209
211
|
|
|
212
|
+
### Live Runs
|
|
213
|
+
|
|
214
|
+
Watch a run as it happens. With `live` enabled, the reporter prints an unguessable watch link — boxed under a `Live Tracker` heading — to your CI logs at run start and streams per-test progress to a hosted dashboard while tests execute. All shards of one CI run converge on a single live view, each running test shows the step it's currently executing, and the PDF is still generated at the end, unchanged.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// playwright.config.ts
|
|
218
|
+
reporter: [
|
|
219
|
+
['@reportforge/playwright-pdf', {
|
|
220
|
+
outputFile: 'reports/{date}-report.pdf',
|
|
221
|
+
live: {
|
|
222
|
+
enabled: true,
|
|
223
|
+
steps: 'failed', // 'none' | 'failed' | 'all'
|
|
224
|
+
// console: false, // stream stdout/stderr tails (off by default — see note)
|
|
225
|
+
// flushMs: 2000, // batch debounce (500–10000)
|
|
226
|
+
},
|
|
227
|
+
}],
|
|
228
|
+
],
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Sharded runs need no extra config — the run id is derived from the run-shared CI identifier (e.g. `GITHUB_RUN_ID`), identical across every matrix shard. Set `RF_LIVE_RUN_ID` to override when your CI is not auto-detected.
|
|
232
|
+
|
|
233
|
+
Live streaming is best-effort and entitlement-gated: if the server is unreachable the run is unaffected, and an active subscription with the `live` feature is required. If you've configured Slack/Teams/Discord notifications, the watch link is also posted to those channels when the run starts.
|
|
234
|
+
|
|
235
|
+
> **Security:** the watch link exposes test titles + statuses (and step titles when `steps` is on). Leaving `console: false` is recommended — enabling it streams your tests' stdout/stderr to anyone holding the link. Full details at [reportforge.org/docs/advanced/live](https://reportforge.org/docs/advanced/live).
|
|
236
|
+
|
|
210
237
|
### Shard Merging
|
|
211
238
|
|
|
212
239
|
Combine parallel Playwright shards into one PDF without re-running any tests.
|
|
@@ -629,6 +656,7 @@ Full documentation at [reportforge.org/docs](https://reportforge.org/docs):
|
|
|
629
656
|
- [Configuration reference](https://reportforge.org/docs/configuration) — all options
|
|
630
657
|
- [Filename tokens](https://reportforge.org/docs/configuration#tokens) — `{date}`, `{branch}`, `{status}`
|
|
631
658
|
- [Templates](https://reportforge.org/docs/templates) — minimal, detailed, executive
|
|
659
|
+
- [Live runs](https://reportforge.org/docs/advanced/live) — stream per-test progress to a shared watch link
|
|
632
660
|
- [Report Sections](https://reportforge.org/docs/configuration#report-sections) — add or remove sections per template
|
|
633
661
|
- [License & offline behaviour](https://reportforge.org/docs/licensing) — JWT cache, machine cap, cancellation
|
|
634
662
|
- [Troubleshooting](https://reportforge.org/docs/troubleshooting) — common issues and debug flags
|
package/dist/cli/index.js
CHANGED
|
@@ -11831,7 +11831,7 @@ ${issues}`);
|
|
|
11831
11831
|
}
|
|
11832
11832
|
return result.data;
|
|
11833
11833
|
}
|
|
11834
|
-
var hexColor, channelConfigSchema, emailChannelConfigSchema, notifyConfigSchema, failureAnalysisConfigSchema, captureConfigSchema, sectionFlagsShape, sectionFlagsSchema, sectionsSchema, ReporterOptionsSchema;
|
|
11834
|
+
var hexColor, channelConfigSchema, emailChannelConfigSchema, notifyConfigSchema, failureAnalysisConfigSchema, captureConfigSchema, liveConfigSchema, sectionFlagsShape, sectionFlagsSchema, sectionsSchema, ReporterOptionsSchema;
|
|
11835
11835
|
var init_schema = __esm({
|
|
11836
11836
|
"src/config/schema.ts"() {
|
|
11837
11837
|
"use strict";
|
|
@@ -11878,6 +11878,21 @@ var init_schema = __esm({
|
|
|
11878
11878
|
maxSteps: external_exports.number().int().min(1).max(500).default(50),
|
|
11879
11879
|
maxConsoleLines: external_exports.number().int().min(1).max(1e3).default(50)
|
|
11880
11880
|
}).default({});
|
|
11881
|
+
liveConfigSchema = external_exports.object({
|
|
11882
|
+
enabled: external_exports.boolean().default(false),
|
|
11883
|
+
// Override the auto-derived run id. All shards of one run must share it.
|
|
11884
|
+
runId: external_exports.string().optional(),
|
|
11885
|
+
// Override the streaming/server base URL (defaults to the license serverUrl).
|
|
11886
|
+
serverUrl: external_exports.string().url().optional(),
|
|
11887
|
+
// Step verbosity: 'none' skips steps, 'failed' streams intent + assertions +
|
|
11888
|
+
// errored steps, 'all' streams every step.
|
|
11889
|
+
steps: external_exports.enum(["none", "failed", "all"]).default("failed"),
|
|
11890
|
+
// Stream test stdout/stderr tails. Off by default — may leak secrets printed
|
|
11891
|
+
// by tests to a token-holder.
|
|
11892
|
+
console: external_exports.boolean().default(false),
|
|
11893
|
+
// Debounce window for batched flushes (ms).
|
|
11894
|
+
flushMs: external_exports.number().int().min(500).max(1e4).default(2e3)
|
|
11895
|
+
}).default({});
|
|
11881
11896
|
sectionFlagsShape = Object.fromEntries(
|
|
11882
11897
|
SECTION_KEYS.map((k) => [k, external_exports.boolean().optional()])
|
|
11883
11898
|
);
|
|
@@ -11919,6 +11934,7 @@ var init_schema = __esm({
|
|
|
11919
11934
|
slowTestThreshold: external_exports.number().int().min(0, "slowTestThreshold must be 0 or greater").optional().default(DEFAULT_OPTIONS.slowTestThreshold),
|
|
11920
11935
|
failureAnalysis: failureAnalysisConfigSchema,
|
|
11921
11936
|
capture: captureConfigSchema,
|
|
11937
|
+
live: liveConfigSchema,
|
|
11922
11938
|
templatePath: external_exports.union([
|
|
11923
11939
|
external_exports.string().regex(/\.hbs$/, "templatePath must end with .hbs").refine((v) => v.slice(0, -4).trim().length > 0, "templatePath basename must not be empty"),
|
|
11924
11940
|
external_exports.array(
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
|
|
1
|
+
import { Reporter, FullConfig, Suite, TestCase, TestResult, TestStep, FullResult } from '@playwright/test/reporter';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Canonical section catalog. 13 block toggles (section present/absent) followed
|
|
@@ -237,6 +237,38 @@ interface ReporterOptions {
|
|
|
237
237
|
/** Max console lines retained per stream. Default: 50 */
|
|
238
238
|
maxConsoleLines?: number;
|
|
239
239
|
};
|
|
240
|
+
/**
|
|
241
|
+
* Live test-execution streaming (opt-in, off by default). When enabled the
|
|
242
|
+
* reporter mints an unguessable watch link, prints it to the CI logs at run
|
|
243
|
+
* start, and streams per-test progress (and optionally per-step / console
|
|
244
|
+
* tails) to the hosted dashboard while your tests run. All shards of one CI
|
|
245
|
+
* run converge on a single live view automatically. The PDF generated at the
|
|
246
|
+
* end of the run is unaffected. Requires an active subscription with the
|
|
247
|
+
* `live` entitlement; degrades to a no-op otherwise.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* live: { enabled: true, steps: 'all' }
|
|
251
|
+
*/
|
|
252
|
+
live?: {
|
|
253
|
+
/** Enable live streaming. Default: false */
|
|
254
|
+
enabled?: boolean;
|
|
255
|
+
/** Override the auto-derived run id. All shards of one run must share it. */
|
|
256
|
+
runId?: string;
|
|
257
|
+
/** Override the streaming server base URL. Defaults to the license `serverUrl`. */
|
|
258
|
+
serverUrl?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Step verbosity: `'none'` skips steps, `'failed'` streams author intent +
|
|
261
|
+
* assertions + errored steps, `'all'` streams every step. Default: `'failed'`
|
|
262
|
+
*/
|
|
263
|
+
steps?: 'none' | 'failed' | 'all';
|
|
264
|
+
/**
|
|
265
|
+
* Stream test stdout/stderr tails to the watch page. Off by default — may
|
|
266
|
+
* leak secrets printed by tests to anyone holding the watch link. Default: false
|
|
267
|
+
*/
|
|
268
|
+
console?: boolean;
|
|
269
|
+
/** Debounce window for batched flushes, in milliseconds (500–10000). Default: 2000 */
|
|
270
|
+
flushMs?: number;
|
|
271
|
+
};
|
|
240
272
|
/**
|
|
241
273
|
* Path to the history JSON file. Defaults to
|
|
242
274
|
* `~/.reportforge/{projectKey}/history.json` where `projectKey` is derived
|
|
@@ -330,6 +362,13 @@ interface LicenseInfo {
|
|
|
330
362
|
jwt?: string;
|
|
331
363
|
machinesUsed?: number;
|
|
332
364
|
machineLimit?: number;
|
|
365
|
+
/**
|
|
366
|
+
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
367
|
+
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
368
|
+
* network trip. Undefined for caches written by reporter versions before this
|
|
369
|
+
* field was persisted — treat absence as "no extra features".
|
|
370
|
+
*/
|
|
371
|
+
features?: string[];
|
|
333
372
|
}
|
|
334
373
|
|
|
335
374
|
/**
|
|
@@ -371,16 +410,47 @@ declare class PdfReporter implements Reporter {
|
|
|
371
410
|
private readonly licenseClient;
|
|
372
411
|
private readonly dataCollector;
|
|
373
412
|
private readonly pdfGenerator;
|
|
413
|
+
private licensePromise?;
|
|
414
|
+
private liveStreamer?;
|
|
415
|
+
private liveShardKey;
|
|
416
|
+
private liveSteps;
|
|
417
|
+
private liveConsole;
|
|
374
418
|
constructor(rawOptions?: ReporterOptions);
|
|
375
419
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
420
|
+
onTestBegin(test: TestCase): void;
|
|
376
421
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
422
|
+
onStepBegin(test: TestCase, _result: TestResult, step: TestStep): void;
|
|
423
|
+
onStepEnd(test: TestCase, _result: TestResult, step: TestStep): void;
|
|
424
|
+
onStdOut(chunk: string | Buffer, test?: TestCase): void;
|
|
425
|
+
onStdErr(chunk: string | Buffer, test?: TestCase): void;
|
|
426
|
+
onExit(): Promise<void>;
|
|
377
427
|
onEnd(result: FullResult): Promise<void>;
|
|
378
428
|
private _collectData;
|
|
379
429
|
private _appendTrend;
|
|
380
430
|
private _populateHistoryCharts;
|
|
381
431
|
private _buildReportData;
|
|
382
432
|
printsToStdio(): boolean;
|
|
433
|
+
/**
|
|
434
|
+
* Memoized license resolution shared by the live stream (kicked early in
|
|
435
|
+
* onBegin) and PDF generation (awaited in onEnd) — at most one network trip.
|
|
436
|
+
*/
|
|
437
|
+
private license;
|
|
383
438
|
private resolveLicense;
|
|
439
|
+
/**
|
|
440
|
+
* Wires up live streaming: derives the run id (shared by all shards), kicks
|
|
441
|
+
* the license resolution early, builds the streamer, and prints the watch
|
|
442
|
+
* link to the CI logs. Throws are caught by the onBegin try/catch.
|
|
443
|
+
*/
|
|
444
|
+
private setupLive;
|
|
445
|
+
/**
|
|
446
|
+
* Announces the watch link once the run is confirmed live-entitled. Gating on
|
|
447
|
+
* the SAME resolved entitlement the streamer requires (`jwt` + the `'live'`
|
|
448
|
+
* feature) guarantees the link is never printed or posted for a run that will
|
|
449
|
+
* never stream — no dead links. The chat ping fires from the primary shard only
|
|
450
|
+
* (unsharded, or `shard.current === 1`) so an N-way matrix posts one message,
|
|
451
|
+
* not N. The banner still prints from every shard's own log.
|
|
452
|
+
*/
|
|
453
|
+
private announceLive;
|
|
384
454
|
private resolveProjectName;
|
|
385
455
|
private openPdf;
|
|
386
456
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
|
|
1
|
+
import { Reporter, FullConfig, Suite, TestCase, TestResult, TestStep, FullResult } from '@playwright/test/reporter';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Canonical section catalog. 13 block toggles (section present/absent) followed
|
|
@@ -237,6 +237,38 @@ interface ReporterOptions {
|
|
|
237
237
|
/** Max console lines retained per stream. Default: 50 */
|
|
238
238
|
maxConsoleLines?: number;
|
|
239
239
|
};
|
|
240
|
+
/**
|
|
241
|
+
* Live test-execution streaming (opt-in, off by default). When enabled the
|
|
242
|
+
* reporter mints an unguessable watch link, prints it to the CI logs at run
|
|
243
|
+
* start, and streams per-test progress (and optionally per-step / console
|
|
244
|
+
* tails) to the hosted dashboard while your tests run. All shards of one CI
|
|
245
|
+
* run converge on a single live view automatically. The PDF generated at the
|
|
246
|
+
* end of the run is unaffected. Requires an active subscription with the
|
|
247
|
+
* `live` entitlement; degrades to a no-op otherwise.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* live: { enabled: true, steps: 'all' }
|
|
251
|
+
*/
|
|
252
|
+
live?: {
|
|
253
|
+
/** Enable live streaming. Default: false */
|
|
254
|
+
enabled?: boolean;
|
|
255
|
+
/** Override the auto-derived run id. All shards of one run must share it. */
|
|
256
|
+
runId?: string;
|
|
257
|
+
/** Override the streaming server base URL. Defaults to the license `serverUrl`. */
|
|
258
|
+
serverUrl?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Step verbosity: `'none'` skips steps, `'failed'` streams author intent +
|
|
261
|
+
* assertions + errored steps, `'all'` streams every step. Default: `'failed'`
|
|
262
|
+
*/
|
|
263
|
+
steps?: 'none' | 'failed' | 'all';
|
|
264
|
+
/**
|
|
265
|
+
* Stream test stdout/stderr tails to the watch page. Off by default — may
|
|
266
|
+
* leak secrets printed by tests to anyone holding the watch link. Default: false
|
|
267
|
+
*/
|
|
268
|
+
console?: boolean;
|
|
269
|
+
/** Debounce window for batched flushes, in milliseconds (500–10000). Default: 2000 */
|
|
270
|
+
flushMs?: number;
|
|
271
|
+
};
|
|
240
272
|
/**
|
|
241
273
|
* Path to the history JSON file. Defaults to
|
|
242
274
|
* `~/.reportforge/{projectKey}/history.json` where `projectKey` is derived
|
|
@@ -330,6 +362,13 @@ interface LicenseInfo {
|
|
|
330
362
|
jwt?: string;
|
|
331
363
|
machinesUsed?: number;
|
|
332
364
|
machineLimit?: number;
|
|
365
|
+
/**
|
|
366
|
+
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
367
|
+
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
368
|
+
* network trip. Undefined for caches written by reporter versions before this
|
|
369
|
+
* field was persisted — treat absence as "no extra features".
|
|
370
|
+
*/
|
|
371
|
+
features?: string[];
|
|
333
372
|
}
|
|
334
373
|
|
|
335
374
|
/**
|
|
@@ -371,16 +410,47 @@ declare class PdfReporter implements Reporter {
|
|
|
371
410
|
private readonly licenseClient;
|
|
372
411
|
private readonly dataCollector;
|
|
373
412
|
private readonly pdfGenerator;
|
|
413
|
+
private licensePromise?;
|
|
414
|
+
private liveStreamer?;
|
|
415
|
+
private liveShardKey;
|
|
416
|
+
private liveSteps;
|
|
417
|
+
private liveConsole;
|
|
374
418
|
constructor(rawOptions?: ReporterOptions);
|
|
375
419
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
420
|
+
onTestBegin(test: TestCase): void;
|
|
376
421
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
422
|
+
onStepBegin(test: TestCase, _result: TestResult, step: TestStep): void;
|
|
423
|
+
onStepEnd(test: TestCase, _result: TestResult, step: TestStep): void;
|
|
424
|
+
onStdOut(chunk: string | Buffer, test?: TestCase): void;
|
|
425
|
+
onStdErr(chunk: string | Buffer, test?: TestCase): void;
|
|
426
|
+
onExit(): Promise<void>;
|
|
377
427
|
onEnd(result: FullResult): Promise<void>;
|
|
378
428
|
private _collectData;
|
|
379
429
|
private _appendTrend;
|
|
380
430
|
private _populateHistoryCharts;
|
|
381
431
|
private _buildReportData;
|
|
382
432
|
printsToStdio(): boolean;
|
|
433
|
+
/**
|
|
434
|
+
* Memoized license resolution shared by the live stream (kicked early in
|
|
435
|
+
* onBegin) and PDF generation (awaited in onEnd) — at most one network trip.
|
|
436
|
+
*/
|
|
437
|
+
private license;
|
|
383
438
|
private resolveLicense;
|
|
439
|
+
/**
|
|
440
|
+
* Wires up live streaming: derives the run id (shared by all shards), kicks
|
|
441
|
+
* the license resolution early, builds the streamer, and prints the watch
|
|
442
|
+
* link to the CI logs. Throws are caught by the onBegin try/catch.
|
|
443
|
+
*/
|
|
444
|
+
private setupLive;
|
|
445
|
+
/**
|
|
446
|
+
* Announces the watch link once the run is confirmed live-entitled. Gating on
|
|
447
|
+
* the SAME resolved entitlement the streamer requires (`jwt` + the `'live'`
|
|
448
|
+
* feature) guarantees the link is never printed or posted for a run that will
|
|
449
|
+
* never stream — no dead links. The chat ping fires from the primary shard only
|
|
450
|
+
* (unsharded, or `shard.current === 1`) so an N-way matrix posts one message,
|
|
451
|
+
* not N. The banner still prints from every shard's own log.
|
|
452
|
+
*/
|
|
453
|
+
private announceLive;
|
|
384
454
|
private resolveProjectName;
|
|
385
455
|
private openPdf;
|
|
386
456
|
}
|