@reportforge/playwright-pdf 0.26.1 → 0.28.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 +48 -2
- package/dist/cli/index.js +19 -3
- package/dist/index.d.mts +37 -42
- package/dist/index.d.ts +37 -42
- package/dist/index.js +1425 -1350
- package/dist/index.mjs +1528 -1453
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Playwright PDF reporter: generate branded PDF reports from [Playwright Test](https://playwright.dev/) results. Three templates (minimal, detailed, executive) for developers, QA teams, and stakeholders. CI-ready, self-contained, with embedded screenshots and charts.
|
|
4
4
|
|
|
5
|
-
Drop it into any Playwright project and get a PDF report on every CI run. No changes to your tests.
|
|
5
|
+
Drop it into any Playwright project and get a PDF report on every CI run. No changes to your tests. Testing with Python or .NET? The same reports ship as [`reportforge-playwright-pdf` on PyPI](https://pypi.org/project/reportforge-playwright-pdf/) and `ReportForge.Playwright.Pdf` on NuGet, on the same license key (see [Python](#python) and [.NET](#net)).
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@reportforge/playwright-pdf)
|
|
8
8
|
[](https://nodejs.org/)
|
|
@@ -67,6 +67,7 @@ Three templates, one reporter. Every PDF is fully offline: fonts, charts, and sc
|
|
|
67
67
|
- **Executive report brief band**: leads with a plain-language brief (trend + root causes) and one hero pass-rate number instead of a flat KPI grid
|
|
68
68
|
- **Data protection**: AES-256 password-protected PDFs (no external tools) and opt-in redaction of credentials/PII in report content and live streams
|
|
69
69
|
- **Hybrid licensing**: one short key unlocks it; reports keep rendering offline via a locally cached license between refreshes
|
|
70
|
+
- **Python and .NET support**: the same reports for pytest-playwright (`reportforge-playwright-pdf` on PyPI) and for NUnit/MSTest/xUnit (`ReportForge.Playwright.Pdf` on NuGet); one subscription key covers every ecosystem (live runs and step trees are Node.js-only today)
|
|
70
71
|
- **Update notice**: when a newer reporter version is published, each run ends with one info line naming it and the update command; no extra network calls
|
|
71
72
|
|
|
72
73
|
---
|
|
@@ -157,6 +158,46 @@ reporter: [['@reportforge/playwright-pdf', {
|
|
|
157
158
|
|
|
158
159
|
---
|
|
159
160
|
|
|
161
|
+
## Python
|
|
162
|
+
|
|
163
|
+
The same reports for [pytest-playwright](https://playwright.dev/python/) runs, from the `reportforge-playwright-pdf` PyPI package. One subscription key covers Node.js and Python, and both count against the same machine allowance.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pip install reportforge-playwright-pdf
|
|
167
|
+
python -m playwright install chromium
|
|
168
|
+
|
|
169
|
+
export RF_LICENSE_KEY=RFSU-XXXX-XXXX-XXXX-XXXX
|
|
170
|
+
pytest --pdf
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Project defaults go in `pyproject.toml` with the same camelCase option names as this reporter:
|
|
174
|
+
|
|
175
|
+
```toml
|
|
176
|
+
[tool.reportforge]
|
|
177
|
+
enabled = true
|
|
178
|
+
template = "detailed"
|
|
179
|
+
outputFile = "reports/{date}-{branch}-report.pdf"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The plugin reuses the Node runtime and Chromium that Playwright for Python already ships, so there is nothing else to install. pytest-xdist and pytest-rerunfailures are supported; failure screenshots from `--screenshot only-on-failure` are embedded. Live runs and step trees are Node.js-only today. Full guide: [reportforge.org/docs/python](https://reportforge.org/docs/python).
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## .NET
|
|
187
|
+
|
|
188
|
+
The same reports for [Playwright .NET](https://playwright.dev/dotnet/) runs, from the `ReportForge.Playwright.Pdf` NuGet package. One vstest logger covers NUnit, MSTest, and xUnit, and the same subscription key covers every language.
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
dotnet add package ReportForge.Playwright.Pdf
|
|
192
|
+
|
|
193
|
+
set RF_LICENSE_KEY=RFSU-XXXX-XXXX-XXXX-XXXX
|
|
194
|
+
dotnet test --logger "reportforge;output=reports/run.pdf;template=detailed"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Full options come from a JSON file with the same camelCase names as this reporter: `--logger "reportforge;optionsFile=rf-options.json"`. The logger reuses the Node runtime Microsoft.Playwright places in your test output and a Playwright-managed Chromium, so there is nothing else to install. Retried tests render as flaky with their attempt history; categories become tags. Live runs and step trees are Node.js-only today. Full guide: [reportforge.org/docs/dotnet](https://reportforge.org/docs/dotnet).
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
160
201
|
## Pricing
|
|
161
202
|
|
|
162
203
|
| Plan | INR | USD | Includes |
|
|
@@ -270,7 +311,9 @@ reporter: [
|
|
|
270
311
|
|
|
271
312
|
The merge step can run against a dummy test file with zero tests: `shardResults` takes precedence over live results.
|
|
272
313
|
|
|
273
|
-
|
|
314
|
+
Timed-out tests keep their own count in shard mode: the aggregate JSON stats fold them into failures, but the per-test result status carries `timedOut` and the report recovers it for the KPI cards and charts.
|
|
315
|
+
|
|
316
|
+
The merger also honors two optional fields in the JSON report's `config` block when the emitting run provides them: `workers` (shown as the worker count in the environment panel, defaults to 1) and `metadata.playwrightVersion` (shown as the Playwright version when the merge runs where `@playwright/test` is not installed).
|
|
274
317
|
|
|
275
318
|
### Notifications
|
|
276
319
|
|
|
@@ -676,6 +719,7 @@ ReportForge ships a **hybrid offline-first** model:
|
|
|
676
719
|
3. Every subsequent run is **fully offline**: the cached license is validated on-device. No network call.
|
|
677
720
|
4. The reporter refreshes the cache automatically in the background before it expires.
|
|
678
721
|
5. Each subscription allows up to **25 active machines**. Machines that haven't run in 30 days free up automatically.
|
|
722
|
+
6. The key is **language-neutral**: the same subscription activates the Node.js reporter, the Python plugin, and the .NET logger, and a machine running several uses one slot.
|
|
679
723
|
|
|
680
724
|
Cancel the subscription and the reporter keeps working until the end of the current billing period, then stops generating PDFs until you restart. **A license issue never aborts your test run**: the reporter logs a warning and skips PDF generation; your Playwright tests still pass.
|
|
681
725
|
|
|
@@ -736,6 +780,8 @@ Full guide: [reportforge.org/docs/troubleshooting](https://reportforge.org/docs/
|
|
|
736
780
|
Full documentation at [reportforge.org/docs](https://reportforge.org/docs):
|
|
737
781
|
|
|
738
782
|
- [Quick start](https://reportforge.org/docs/quickstart): install, configure, activate
|
|
783
|
+
- [Python](https://reportforge.org/docs/python): the pytest-playwright plugin, same license key
|
|
784
|
+
- [.NET](https://reportforge.org/docs/dotnet): the NUnit/MSTest/xUnit logger, same license key
|
|
739
785
|
- [Chrome setup](https://reportforge.org/docs/running-tests#chrome-setup): Windows, Linux, macOS
|
|
740
786
|
- [CI/CD integration](https://reportforge.org/docs/ci-cd): GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps
|
|
741
787
|
- [Configuration reference](https://reportforge.org/docs/configuration): all options
|
package/dist/cli/index.js
CHANGED
|
@@ -6952,13 +6952,25 @@ var init_engine = __esm({
|
|
|
6952
6952
|
});
|
|
6953
6953
|
|
|
6954
6954
|
// src/screenshots/ScreenshotEmbedder.ts
|
|
6955
|
-
|
|
6955
|
+
function loadSharp() {
|
|
6956
|
+
if (sharpModule === void 0) {
|
|
6957
|
+
try {
|
|
6958
|
+
sharpModule = require("sharp");
|
|
6959
|
+
} catch {
|
|
6960
|
+
sharpModule = null;
|
|
6961
|
+
logger.warn(
|
|
6962
|
+
"sharp is not available \u2014 screenshots are embedded at original size. Reports with many screenshots may exceed maxFileSizeMb more often."
|
|
6963
|
+
);
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
return sharpModule;
|
|
6967
|
+
}
|
|
6968
|
+
var import_fs2, sharpModule, ScreenshotEmbedder;
|
|
6956
6969
|
var init_ScreenshotEmbedder = __esm({
|
|
6957
6970
|
"src/screenshots/ScreenshotEmbedder.ts"() {
|
|
6958
6971
|
"use strict";
|
|
6959
6972
|
init_cjs_shims();
|
|
6960
6973
|
import_fs2 = __toESM(require("fs"));
|
|
6961
|
-
import_sharp = __toESM(require("sharp"));
|
|
6962
6974
|
init_logger();
|
|
6963
6975
|
ScreenshotEmbedder = class {
|
|
6964
6976
|
async embedAll(failures, opts) {
|
|
@@ -6995,7 +7007,11 @@ var init_ScreenshotEmbedder = __esm({
|
|
|
6995
7007
|
if (this.looksLikeSvg(buf)) {
|
|
6996
7008
|
return { buffer: buf, mime: "image/svg+xml" };
|
|
6997
7009
|
}
|
|
6998
|
-
const
|
|
7010
|
+
const sharp = loadSharp();
|
|
7011
|
+
if (!sharp) {
|
|
7012
|
+
return { buffer: buf, mime: this.detectMimeType(buf) };
|
|
7013
|
+
}
|
|
7014
|
+
const img = sharp(buf, { failOn: "none" });
|
|
6999
7015
|
const meta = await img.metadata();
|
|
7000
7016
|
const needsResize = (meta.width ?? 0) > opts.maxWidth;
|
|
7001
7017
|
let pipeline = img.rotate();
|
package/dist/index.d.mts
CHANGED
|
@@ -432,43 +432,6 @@ interface ReporterOptions {
|
|
|
432
432
|
sections?: SectionsOption;
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
-
/**
|
|
436
|
-
* The resolved license for the current reporter run.
|
|
437
|
-
*
|
|
438
|
-
* The mere existence of a LicenseInfo means the subscription is active —
|
|
439
|
-
* "no license" is represented by `LicenseClient.resolve()` returning null,
|
|
440
|
-
* not by a sentinel plan or `valid: false` flag.
|
|
441
|
-
*
|
|
442
|
-
* `source` surfaces how the license was obtained so the reporter can log
|
|
443
|
-
* actionable diagnostics:
|
|
444
|
-
* - 'jwt-online' → freshly activated/refreshed against the server
|
|
445
|
-
* - 'jwt-cache' → served from ~/.reportforge/license.json (offline)
|
|
446
|
-
*/
|
|
447
|
-
interface LicenseInfo {
|
|
448
|
-
plan: LicensePlan;
|
|
449
|
-
source: 'jwt-online' | 'jwt-cache' | 'demo';
|
|
450
|
-
expiry: Date;
|
|
451
|
-
key: string;
|
|
452
|
-
/** Raw Ed25519-signed JWT from the server. Absent only in demo mode. */
|
|
453
|
-
jwt?: string;
|
|
454
|
-
machinesUsed?: number;
|
|
455
|
-
machineLimit?: number;
|
|
456
|
-
/**
|
|
457
|
-
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
458
|
-
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
459
|
-
* network trip. Undefined for caches written by reporter versions before this
|
|
460
|
-
* field was persisted — treat absence as "no extra features".
|
|
461
|
-
*/
|
|
462
|
-
features?: string[];
|
|
463
|
-
/**
|
|
464
|
-
* Latest published npm version of the reporter, as last reported by the
|
|
465
|
-
* license server (activate/refresh piggyback). Absent when the server
|
|
466
|
-
* could not reach the registry or the cache predates this field. Used
|
|
467
|
-
* only for the non-blocking run-end update notice.
|
|
468
|
-
*/
|
|
469
|
-
latestVersion?: string;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
435
|
/**
|
|
473
436
|
* PdfReporter — Playwright custom reporter that generates professional PDF reports.
|
|
474
437
|
*
|
|
@@ -526,9 +489,6 @@ declare class PdfReporter implements Reporter {
|
|
|
526
489
|
onExit(): Promise<void>;
|
|
527
490
|
onEnd(result: FullResult): Promise<void>;
|
|
528
491
|
private _collectData;
|
|
529
|
-
private _appendTrend;
|
|
530
|
-
private _populateHistoryCharts;
|
|
531
|
-
private _buildReportData;
|
|
532
492
|
printsToStdio(): boolean;
|
|
533
493
|
/**
|
|
534
494
|
* Memoized license resolution shared by the live stream (kicked early in
|
|
@@ -566,8 +526,43 @@ declare class PdfReporter implements Reporter {
|
|
|
566
526
|
* posts one message, not N. The banner still prints from every shard's own log.
|
|
567
527
|
*/
|
|
568
528
|
private announceLive;
|
|
569
|
-
|
|
570
|
-
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* The resolved license for the current reporter run.
|
|
533
|
+
*
|
|
534
|
+
* The mere existence of a LicenseInfo means the subscription is active —
|
|
535
|
+
* "no license" is represented by `LicenseClient.resolve()` returning null,
|
|
536
|
+
* not by a sentinel plan or `valid: false` flag.
|
|
537
|
+
*
|
|
538
|
+
* `source` surfaces how the license was obtained so the reporter can log
|
|
539
|
+
* actionable diagnostics:
|
|
540
|
+
* - 'jwt-online' → freshly activated/refreshed against the server
|
|
541
|
+
* - 'jwt-cache' → served from ~/.reportforge/license.json (offline)
|
|
542
|
+
*/
|
|
543
|
+
interface LicenseInfo {
|
|
544
|
+
plan: LicensePlan;
|
|
545
|
+
source: 'jwt-online' | 'jwt-cache' | 'demo';
|
|
546
|
+
expiry: Date;
|
|
547
|
+
key: string;
|
|
548
|
+
/** Raw Ed25519-signed JWT from the server. Absent only in demo mode. */
|
|
549
|
+
jwt?: string;
|
|
550
|
+
machinesUsed?: number;
|
|
551
|
+
machineLimit?: number;
|
|
552
|
+
/**
|
|
553
|
+
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
554
|
+
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
555
|
+
* network trip. Undefined for caches written by reporter versions before this
|
|
556
|
+
* field was persisted — treat absence as "no extra features".
|
|
557
|
+
*/
|
|
558
|
+
features?: string[];
|
|
559
|
+
/**
|
|
560
|
+
* Latest published npm version of the reporter, as last reported by the
|
|
561
|
+
* license server (activate/refresh piggyback). Absent when the server
|
|
562
|
+
* could not reach the registry or the cache predates this field. Used
|
|
563
|
+
* only for the non-blocking run-end update notice.
|
|
564
|
+
*/
|
|
565
|
+
latestVersion?: string;
|
|
571
566
|
}
|
|
572
567
|
|
|
573
568
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -432,43 +432,6 @@ interface ReporterOptions {
|
|
|
432
432
|
sections?: SectionsOption;
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
-
/**
|
|
436
|
-
* The resolved license for the current reporter run.
|
|
437
|
-
*
|
|
438
|
-
* The mere existence of a LicenseInfo means the subscription is active —
|
|
439
|
-
* "no license" is represented by `LicenseClient.resolve()` returning null,
|
|
440
|
-
* not by a sentinel plan or `valid: false` flag.
|
|
441
|
-
*
|
|
442
|
-
* `source` surfaces how the license was obtained so the reporter can log
|
|
443
|
-
* actionable diagnostics:
|
|
444
|
-
* - 'jwt-online' → freshly activated/refreshed against the server
|
|
445
|
-
* - 'jwt-cache' → served from ~/.reportforge/license.json (offline)
|
|
446
|
-
*/
|
|
447
|
-
interface LicenseInfo {
|
|
448
|
-
plan: LicensePlan;
|
|
449
|
-
source: 'jwt-online' | 'jwt-cache' | 'demo';
|
|
450
|
-
expiry: Date;
|
|
451
|
-
key: string;
|
|
452
|
-
/** Raw Ed25519-signed JWT from the server. Absent only in demo mode. */
|
|
453
|
-
jwt?: string;
|
|
454
|
-
machinesUsed?: number;
|
|
455
|
-
machineLimit?: number;
|
|
456
|
-
/**
|
|
457
|
-
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
458
|
-
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
459
|
-
* network trip. Undefined for caches written by reporter versions before this
|
|
460
|
-
* field was persisted — treat absence as "no extra features".
|
|
461
|
-
*/
|
|
462
|
-
features?: string[];
|
|
463
|
-
/**
|
|
464
|
-
* Latest published npm version of the reporter, as last reported by the
|
|
465
|
-
* license server (activate/refresh piggyback). Absent when the server
|
|
466
|
-
* could not reach the registry or the cache predates this field. Used
|
|
467
|
-
* only for the non-blocking run-end update notice.
|
|
468
|
-
*/
|
|
469
|
-
latestVersion?: string;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
435
|
/**
|
|
473
436
|
* PdfReporter — Playwright custom reporter that generates professional PDF reports.
|
|
474
437
|
*
|
|
@@ -526,9 +489,6 @@ declare class PdfReporter implements Reporter {
|
|
|
526
489
|
onExit(): Promise<void>;
|
|
527
490
|
onEnd(result: FullResult): Promise<void>;
|
|
528
491
|
private _collectData;
|
|
529
|
-
private _appendTrend;
|
|
530
|
-
private _populateHistoryCharts;
|
|
531
|
-
private _buildReportData;
|
|
532
492
|
printsToStdio(): boolean;
|
|
533
493
|
/**
|
|
534
494
|
* Memoized license resolution shared by the live stream (kicked early in
|
|
@@ -566,8 +526,43 @@ declare class PdfReporter implements Reporter {
|
|
|
566
526
|
* posts one message, not N. The banner still prints from every shard's own log.
|
|
567
527
|
*/
|
|
568
528
|
private announceLive;
|
|
569
|
-
|
|
570
|
-
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* The resolved license for the current reporter run.
|
|
533
|
+
*
|
|
534
|
+
* The mere existence of a LicenseInfo means the subscription is active —
|
|
535
|
+
* "no license" is represented by `LicenseClient.resolve()` returning null,
|
|
536
|
+
* not by a sentinel plan or `valid: false` flag.
|
|
537
|
+
*
|
|
538
|
+
* `source` surfaces how the license was obtained so the reporter can log
|
|
539
|
+
* actionable diagnostics:
|
|
540
|
+
* - 'jwt-online' → freshly activated/refreshed against the server
|
|
541
|
+
* - 'jwt-cache' → served from ~/.reportforge/license.json (offline)
|
|
542
|
+
*/
|
|
543
|
+
interface LicenseInfo {
|
|
544
|
+
plan: LicensePlan;
|
|
545
|
+
source: 'jwt-online' | 'jwt-cache' | 'demo';
|
|
546
|
+
expiry: Date;
|
|
547
|
+
key: string;
|
|
548
|
+
/** Raw Ed25519-signed JWT from the server. Absent only in demo mode. */
|
|
549
|
+
jwt?: string;
|
|
550
|
+
machinesUsed?: number;
|
|
551
|
+
machineLimit?: number;
|
|
552
|
+
/**
|
|
553
|
+
* Entitlement flags carried on the signed JWT (`features` claim). Surfaces
|
|
554
|
+
* server-gated capabilities (e.g. `'live'`) to the reporter without a second
|
|
555
|
+
* network trip. Undefined for caches written by reporter versions before this
|
|
556
|
+
* field was persisted — treat absence as "no extra features".
|
|
557
|
+
*/
|
|
558
|
+
features?: string[];
|
|
559
|
+
/**
|
|
560
|
+
* Latest published npm version of the reporter, as last reported by the
|
|
561
|
+
* license server (activate/refresh piggyback). Absent when the server
|
|
562
|
+
* could not reach the registry or the cache predates this field. Used
|
|
563
|
+
* only for the non-blocking run-end update notice.
|
|
564
|
+
*/
|
|
565
|
+
latestVersion?: string;
|
|
571
566
|
}
|
|
572
567
|
|
|
573
568
|
/**
|