@reportforge/playwright-pdf 0.16.0 → 0.17.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/CHANGELOG.md +17 -0
- package/LICENSE +93 -19
- package/README.md +8 -7
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +46 -6
- package/dist/index.mjs +46 -6
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## [0.17.0] - 2026-07-09
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **The reporter now tells you when a newer version is available.** Each run ends with one info line naming the current and latest version and the update command, e.g. `Update available: 0.16.1 -> 0.17.0. Run: npm i -D @reportforge/playwright-pdf@latest`. The latest published version is piggybacked on the existing license activate/refresh call, so there are no extra network calls; the notice never blocks or fails a run and disappears once you update.
|
|
11
|
+
- **Admins can send release announcement emails.** A new `/admin/announce` panel builds the email body from the changelog entry for a chosen version and sends it to a selected audience (active subscribers, all subscribers, or active plus recently churned within 90 days), with a preview step and idempotency protection against duplicate sends.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## [0.16.1] - 2026-07-09
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Relicensed from MIT to the Elastic License 2.0** (source-available). The source stays readable, copyable, and modifiable; the license does not allow offering the software as a hosted service, bypassing or removing the license-key check, or stripping license/copyright notices. Surfaces updated together: `LICENSE`, `package.json` license metadata, README badge + License section, docs badge, marketing footer, pricing FAQ, and legal terms (§2 License grant, §7 IP, `lastUpdated`).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
6
23
|
## [0.16.0] - 2026-07-07
|
|
7
24
|
|
|
8
25
|
### Added
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,95 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
1
|
Copyright (c) 2026 ReportForge
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
3
|
+
Elastic License 2.0
|
|
4
|
+
|
|
5
|
+
URL: https://www.elastic.co/licensing/elastic-license
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
|
14
|
+
non-sublicensable, non-transferable license to use, copy, distribute, make
|
|
15
|
+
available, and prepare derivative works of the software, in each case subject to
|
|
16
|
+
the limitations and conditions below.
|
|
17
|
+
|
|
18
|
+
## Limitations
|
|
19
|
+
|
|
20
|
+
You may not provide the software to third parties as a hosted or managed
|
|
21
|
+
service, where the service provides users with access to any substantial set of
|
|
22
|
+
the features or functionality of the software.
|
|
23
|
+
|
|
24
|
+
You may not move, change, disable, or circumvent the license key functionality
|
|
25
|
+
in the software, and you may not remove or obscure any functionality in the
|
|
26
|
+
software that is protected by the license key.
|
|
27
|
+
|
|
28
|
+
You may not alter, remove, or obscure any licensing, copyright, or other notices
|
|
29
|
+
of the licensor in the software. Any use of the licensor’s trademarks is subject
|
|
30
|
+
to applicable law.
|
|
31
|
+
|
|
32
|
+
## Patents
|
|
33
|
+
|
|
34
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
35
|
+
license, or becomes able to license, to make, have made, use, sell, offer for
|
|
36
|
+
sale, import and have imported the software, in each case subject to the
|
|
37
|
+
limitations and conditions in this license. This license does not cover any
|
|
38
|
+
patent claims that you cause to be infringed by modifications or additions to
|
|
39
|
+
the software. If you or your company make any written claim that the software
|
|
40
|
+
infringes or contributes to infringement of any patent, your patent license for
|
|
41
|
+
the software granted under these terms ends immediately. If your company makes
|
|
42
|
+
such a claim, your patent license ends immediately for work on behalf of your
|
|
43
|
+
company.
|
|
44
|
+
|
|
45
|
+
## Notices
|
|
46
|
+
|
|
47
|
+
You must ensure that anyone who gets a copy of any part of the software from you
|
|
48
|
+
also gets a copy of these terms.
|
|
49
|
+
|
|
50
|
+
If you modify the software, you must include in any modified copies of the
|
|
51
|
+
software prominent notices stating that you have modified the software.
|
|
52
|
+
|
|
53
|
+
## No Other Rights
|
|
54
|
+
|
|
55
|
+
These terms do not imply any licenses other than those expressly granted in
|
|
56
|
+
these terms.
|
|
57
|
+
|
|
58
|
+
## Termination
|
|
59
|
+
|
|
60
|
+
If you use the software in violation of these terms, such use is not licensed,
|
|
61
|
+
and your licenses will automatically terminate. If the licensor provides you
|
|
62
|
+
with a notice of your violation, and you cease all violation of this license no
|
|
63
|
+
later than 30 days after you receive that notice, your licenses will be
|
|
64
|
+
reinstated retroactively. However, if you violate these terms after such
|
|
65
|
+
reinstatement, any additional violation of these terms will cause your licenses
|
|
66
|
+
to terminate automatically and permanently.
|
|
67
|
+
|
|
68
|
+
## No Liability
|
|
69
|
+
|
|
70
|
+
*As far as the law allows, the software comes as is, without any warranty or
|
|
71
|
+
condition, and the licensor will not be liable to you for any damages arising
|
|
72
|
+
out of these terms or the use or nature of the software, under any kind of
|
|
73
|
+
legal claim.*
|
|
74
|
+
|
|
75
|
+
## Definitions
|
|
76
|
+
|
|
77
|
+
The **licensor** is the entity offering these terms, and the **software** is the
|
|
78
|
+
software the licensor makes available under these terms, including any portion
|
|
79
|
+
of it.
|
|
80
|
+
|
|
81
|
+
**you** refers to the individual or entity agreeing to these terms.
|
|
82
|
+
|
|
83
|
+
**your company** is any legal entity, sole proprietorship, or other kind of
|
|
84
|
+
organization that you work for, plus all organizations that have control over,
|
|
85
|
+
are under the control of, or are under common control with that
|
|
86
|
+
organization. **control** means ownership of substantially all the assets of an
|
|
87
|
+
entity, or the power to direct its management and policies by vote, contract, or
|
|
88
|
+
otherwise. Control can be direct or indirect.
|
|
89
|
+
|
|
90
|
+
**your licenses** are all the licenses granted to you for the software under
|
|
91
|
+
these terms.
|
|
92
|
+
|
|
93
|
+
**use** means anything you do with the software requiring one of your licenses.
|
|
94
|
+
|
|
95
|
+
**trademark** means trademarks, service marks, and similar rights.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Drop it into any Playwright project and get a PDF report on every CI run. No cha
|
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@reportforge/playwright-pdf)
|
|
8
8
|
[](https://nodejs.org/)
|
|
9
|
-
[](./LICENSE)
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://reportforge.org/pricing">
|
|
@@ -47,7 +47,7 @@ Three templates, one reporter. Every PDF is fully offline: fonts, charts, and sc
|
|
|
47
47
|
|
|
48
48
|
- **3 templates**: `minimal` (developer), `detailed` (QA team), `executive` (stakeholders)
|
|
49
49
|
- **Detailed reports**: KPI dashboard, suite breakdown with inline failure detail (error, screenshot, root-cause chip) under each failed test, CI/CD environment
|
|
50
|
-
- **Embedded Chart.js**: pass-rate doughnut + per-suite bar chart, bundled inline (no CDN); every suite gets its own bar
|
|
50
|
+
- **Embedded Chart.js**: pass-rate doughnut + per-suite bar chart, bundled inline (no CDN); every suite gets its own bar, and large runs switch to full-width suite charts that continue across pages, so per-suite coverage and failures stay visible run-wide
|
|
51
51
|
- **Self-contained PDFs**: screenshots, fonts, logos all embedded; share or archive with confidence
|
|
52
52
|
- **Custom branding**: logo, primary/accent colours, watermark, PDF password encryption
|
|
53
53
|
- **Dynamic filenames**: `{date}`, `{branch}`, `{status}` tokens in the output path
|
|
@@ -63,6 +63,7 @@ Three templates, one reporter. Every PDF is fully offline: fonts, charts, and sc
|
|
|
63
63
|
- **Configurable sections**: add or remove any report section per template via `sections`.
|
|
64
64
|
- **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
|
|
65
65
|
- **Hybrid licensing**: one short key unlocks it; reports keep rendering offline via a cached JWT between refreshes
|
|
66
|
+
- **Update notice**: when a newer reporter version is published, each run ends with one info line naming it and the update command; delivered over the existing license refresh, no extra network calls
|
|
66
67
|
|
|
67
68
|
---
|
|
68
69
|
|
|
@@ -97,7 +98,7 @@ npx playwright test
|
|
|
97
98
|
|
|
98
99
|
> **See it first.** Run `npx @reportforge/playwright-pdf demo` to generate a realistic sample PDF in under 60 seconds, no license key required. Supports `--template=minimal|detailed|executive` and `--output=<path>`.
|
|
99
100
|
|
|
100
|
-
> **License required.** Start a **[7-day free trial at reportforge.org/pricing](https://reportforge.org/pricing)**: card required, no charge until day 8. Paste the resulting `RFSU-…` key into `RF_LICENSE_KEY`. Without a valid license the reporter logs a warning and skips PDF generation; your Playwright tests still run normally.
|
|
101
|
+
> **License required.** Start a **[7-day free trial at reportforge.org/pricing](https://reportforge.org/pricing)**: card required, no charge until day 8. Paste the resulting `RFSU-…` key into `RF_LICENSE_KEY`. Without a valid license the reporter logs a warning and skips PDF generation; your Playwright tests still run normally. When a newer reporter version exists, runs end with a one-line update notice.
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
@@ -157,7 +158,7 @@ reporter: [['@reportforge/playwright-pdf', {
|
|
|
157
158
|
| Plan | INR | USD | Includes |
|
|
158
159
|
|---|---|---|---|
|
|
159
160
|
| **Monthly** | **₹999 / month** | **$12 / month** | All three templates · custom branding · PDF encryption · up to 25 active machines · priority email support |
|
|
160
|
-
| **Yearly** | **₹8,499 / year** | **$99 / year** | Everything in Monthly · ~29
|
|
161
|
+
| **Yearly** | **₹8,499 / year** | **$99 / year** | Everything in Monthly · ~29-31% saving vs monthly |
|
|
161
162
|
|
|
162
163
|
Currency is auto-detected by region; toggle on the pricing page.
|
|
163
164
|
|
|
@@ -198,7 +199,7 @@ All options are the second element of the reporter tuple.
|
|
|
198
199
|
| `notify` | `object` | n/a | Notification channels: `slack`, `teams` (each `{ url, enabled, on }`), `discord` (`{ url, enabled, on, attachPdf }`), `email` (`{ to, enabled, on, attachPdf }`). See the Notifications docs. |
|
|
199
200
|
| `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. |
|
|
200
201
|
| `capture` | `object` | `{}` (off) | Opt-in rich execution capture for the defect log (reporter-side; no fixtures, no test-code changes). Fields: `steps` (a copy-pasteable "Steps to Reproduce" outline built from the Playwright step tree; each row is a Markdown list line indented under its parent `test.step`, default `false`), `apiSteps` (include every top-level `pw:api` action (click/fill/check/goto) in the outline for a full action trail; without it the outline shows only `test.step` intent + `expect` assertions, 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. |
|
|
201
|
-
| `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`\|`intent`\|`all`, default `failed`; `intent` shows only your `test.step` names plus any failing step), `console` (stream stdout/stderr tails, default `false`), `flushMs` (batch debounce 500
|
|
202
|
+
| `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`\|`intent`\|`all`, default `failed`; `intent` shows only your `test.step` names plus any failing step), `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. |
|
|
202
203
|
| `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. |
|
|
203
204
|
| `historySize` | `number` | `10` | Maximum number of test runs to keep in the history file (integer ≥ 2). Older runs are pruned on append. |
|
|
204
205
|
| `showTrend` | `boolean` | `true` | Show the pass-rate sparkline and delta badge in the `detailed` template. Set to `false` to disable history tracking entirely. |
|
|
@@ -225,7 +226,7 @@ reporter: [
|
|
|
225
226
|
enabled: true,
|
|
226
227
|
steps: 'failed', // 'none' | 'failed' | 'intent' | 'all'
|
|
227
228
|
// console: false, // stream stdout/stderr tails (off by default; see note)
|
|
228
|
-
// flushMs: 2000, // batch debounce (500
|
|
229
|
+
// flushMs: 2000, // batch debounce (500-10000)
|
|
229
230
|
},
|
|
230
231
|
}],
|
|
231
232
|
],
|
|
@@ -678,4 +679,4 @@ Questions and bug reports: email [support@reportforge.org](mailto:support@report
|
|
|
678
679
|
|
|
679
680
|
## License
|
|
680
681
|
|
|
681
|
-
|
|
682
|
+
[Elastic License 2.0](./LICENSE), source-available. Read, copy, and modify the source freely. Three things the license does not allow: offering the software as a hosted service, bypassing or removing the license-key check, and stripping license or copyright notices. Generating PDF reports requires an active subscription.
|
package/dist/index.d.mts
CHANGED
|
@@ -379,6 +379,13 @@ interface LicenseInfo {
|
|
|
379
379
|
* field was persisted — treat absence as "no extra features".
|
|
380
380
|
*/
|
|
381
381
|
features?: string[];
|
|
382
|
+
/**
|
|
383
|
+
* Latest published npm version of the reporter, as last reported by the
|
|
384
|
+
* license server (activate/refresh piggyback). Absent when the server
|
|
385
|
+
* could not reach the registry or the cache predates this field. Used
|
|
386
|
+
* only for the non-blocking run-end update notice.
|
|
387
|
+
*/
|
|
388
|
+
latestVersion?: string;
|
|
382
389
|
}
|
|
383
390
|
|
|
384
391
|
/**
|
|
@@ -417,6 +424,7 @@ interface LicenseInfo {
|
|
|
417
424
|
declare class PdfReporter implements Reporter {
|
|
418
425
|
private readonly options;
|
|
419
426
|
private readonly cwd;
|
|
427
|
+
private readonly version;
|
|
420
428
|
private readonly licenseClient;
|
|
421
429
|
private readonly dataCollector;
|
|
422
430
|
private readonly pdfGenerator;
|
package/dist/index.d.ts
CHANGED
|
@@ -379,6 +379,13 @@ interface LicenseInfo {
|
|
|
379
379
|
* field was persisted — treat absence as "no extra features".
|
|
380
380
|
*/
|
|
381
381
|
features?: string[];
|
|
382
|
+
/**
|
|
383
|
+
* Latest published npm version of the reporter, as last reported by the
|
|
384
|
+
* license server (activate/refresh piggyback). Absent when the server
|
|
385
|
+
* could not reach the registry or the cache predates this field. Used
|
|
386
|
+
* only for the non-blocking run-end update notice.
|
|
387
|
+
*/
|
|
388
|
+
latestVersion?: string;
|
|
382
389
|
}
|
|
383
390
|
|
|
384
391
|
/**
|
|
@@ -417,6 +424,7 @@ interface LicenseInfo {
|
|
|
417
424
|
declare class PdfReporter implements Reporter {
|
|
418
425
|
private readonly options;
|
|
419
426
|
private readonly cwd;
|
|
427
|
+
private readonly version;
|
|
420
428
|
private readonly licenseClient;
|
|
421
429
|
private readonly dataCollector;
|
|
422
430
|
private readonly pdfGenerator;
|
package/dist/index.js
CHANGED
|
@@ -10995,7 +10995,8 @@ var LicenseClient = class {
|
|
|
10995
10995
|
fingerprintHash: this.fingerprint.hash,
|
|
10996
10996
|
machinesUsed: result.machinesUsed,
|
|
10997
10997
|
machineLimit: result.machineLimit,
|
|
10998
|
-
features: payload.features
|
|
10998
|
+
features: payload.features,
|
|
10999
|
+
latestVersion: result.latestVersion
|
|
10999
11000
|
};
|
|
11000
11001
|
writeCache(entry);
|
|
11001
11002
|
logger.debug(`license path=${cached ? "refresh" : "activate"} response`, {
|
|
@@ -11014,7 +11015,8 @@ var LicenseClient = class {
|
|
|
11014
11015
|
expiry: new Date(payload.exp * 1e3),
|
|
11015
11016
|
machinesUsed: result.machinesUsed,
|
|
11016
11017
|
machineLimit: result.machineLimit,
|
|
11017
|
-
features: payload.features
|
|
11018
|
+
features: payload.features,
|
|
11019
|
+
latestVersion: result.latestVersion
|
|
11018
11020
|
};
|
|
11019
11021
|
} catch (err) {
|
|
11020
11022
|
const msg = err.message;
|
|
@@ -11111,13 +11113,47 @@ function toLicenseInfo(payload, cached, normalizedKey, source) {
|
|
|
11111
11113
|
// Prefer the signed `features` claim (authenticated) over the unauthenticated
|
|
11112
11114
|
// sidecar — falls back to the sidecar only for caches written before the
|
|
11113
11115
|
// payload was threaded through here.
|
|
11114
|
-
features: payload.features ?? cached.features
|
|
11116
|
+
features: payload.features ?? cached.features,
|
|
11117
|
+
latestVersion: cached.latestVersion
|
|
11115
11118
|
};
|
|
11116
11119
|
}
|
|
11117
11120
|
function normalizeUrl(url) {
|
|
11118
11121
|
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
11119
11122
|
}
|
|
11120
11123
|
|
|
11124
|
+
// src/license/update-notice.ts
|
|
11125
|
+
init_cjs_shims();
|
|
11126
|
+
|
|
11127
|
+
// src/license/version.ts
|
|
11128
|
+
init_cjs_shims();
|
|
11129
|
+
function parseTriple(v) {
|
|
11130
|
+
if (!v) return null;
|
|
11131
|
+
const m = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(v.trim());
|
|
11132
|
+
if (!m) return null;
|
|
11133
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
11134
|
+
}
|
|
11135
|
+
function isNewer(latest, current) {
|
|
11136
|
+
const l = parseTriple(latest);
|
|
11137
|
+
const c = parseTriple(current);
|
|
11138
|
+
if (!l || !c) return false;
|
|
11139
|
+
if (l[0] !== c[0]) return l[0] > c[0];
|
|
11140
|
+
if (l[1] !== c[1]) return l[1] > c[1];
|
|
11141
|
+
return l[2] > c[2];
|
|
11142
|
+
}
|
|
11143
|
+
|
|
11144
|
+
// src/license/update-notice.ts
|
|
11145
|
+
function maybePrintUpdateNotice(licenseInfo, currentVersion) {
|
|
11146
|
+
try {
|
|
11147
|
+
const latest = licenseInfo?.latestVersion;
|
|
11148
|
+
if (!latest || !isNewer(latest, currentVersion)) return;
|
|
11149
|
+
const shown = latest.replace(/[^\w.+-]/g, "");
|
|
11150
|
+
logger.info(
|
|
11151
|
+
`Update available: ${currentVersion} -> ${shown}. Run: npm i -D @reportforge/playwright-pdf@latest`
|
|
11152
|
+
);
|
|
11153
|
+
} catch {
|
|
11154
|
+
}
|
|
11155
|
+
}
|
|
11156
|
+
|
|
11121
11157
|
// src/analysis/index.ts
|
|
11122
11158
|
init_cjs_shims();
|
|
11123
11159
|
|
|
@@ -14119,8 +14155,8 @@ var PdfReporter = class {
|
|
|
14119
14155
|
this.liveConsole = false;
|
|
14120
14156
|
this.options = parseOptions(rawOptions);
|
|
14121
14157
|
this.dataCollector = new DataCollector(this.options.capture);
|
|
14122
|
-
|
|
14123
|
-
logger.info(`@reportforge/playwright-pdf v${version} initialised`);
|
|
14158
|
+
this.version = true ? "0.17.0" : "0.x";
|
|
14159
|
+
logger.info(`@reportforge/playwright-pdf v${this.version} initialised`);
|
|
14124
14160
|
this.licenseClient = new LicenseClient({
|
|
14125
14161
|
licenseKey: this.options.licenseKey,
|
|
14126
14162
|
serverUrl: this.options.serverUrl,
|
|
@@ -14193,7 +14229,10 @@ var PdfReporter = class {
|
|
|
14193
14229
|
const licenseInfo = await this.license();
|
|
14194
14230
|
if (!licenseInfo) return;
|
|
14195
14231
|
const collected = this._collectData(result);
|
|
14196
|
-
if (!collected)
|
|
14232
|
+
if (!collected) {
|
|
14233
|
+
maybePrintUpdateNotice(licenseInfo, this.version);
|
|
14234
|
+
return;
|
|
14235
|
+
}
|
|
14197
14236
|
if (this.options.showTrend && collected.stats.total > 0) {
|
|
14198
14237
|
try {
|
|
14199
14238
|
this._appendTrend(collected);
|
|
@@ -14218,6 +14257,7 @@ var PdfReporter = class {
|
|
|
14218
14257
|
const sender = new NotificationSender();
|
|
14219
14258
|
await sender.sendAll(reportData, this.options.notify, pdfPaths);
|
|
14220
14259
|
}
|
|
14260
|
+
maybePrintUpdateNotice(licenseInfo, this.version);
|
|
14221
14261
|
}
|
|
14222
14262
|
_collectData(result) {
|
|
14223
14263
|
if (this.options.shardResults && this.options.shardResults.length > 0) {
|
package/dist/index.mjs
CHANGED
|
@@ -10996,7 +10996,8 @@ var LicenseClient = class {
|
|
|
10996
10996
|
fingerprintHash: this.fingerprint.hash,
|
|
10997
10997
|
machinesUsed: result.machinesUsed,
|
|
10998
10998
|
machineLimit: result.machineLimit,
|
|
10999
|
-
features: payload.features
|
|
10999
|
+
features: payload.features,
|
|
11000
|
+
latestVersion: result.latestVersion
|
|
11000
11001
|
};
|
|
11001
11002
|
writeCache(entry);
|
|
11002
11003
|
logger.debug(`license path=${cached ? "refresh" : "activate"} response`, {
|
|
@@ -11015,7 +11016,8 @@ var LicenseClient = class {
|
|
|
11015
11016
|
expiry: new Date(payload.exp * 1e3),
|
|
11016
11017
|
machinesUsed: result.machinesUsed,
|
|
11017
11018
|
machineLimit: result.machineLimit,
|
|
11018
|
-
features: payload.features
|
|
11019
|
+
features: payload.features,
|
|
11020
|
+
latestVersion: result.latestVersion
|
|
11019
11021
|
};
|
|
11020
11022
|
} catch (err) {
|
|
11021
11023
|
const msg = err.message;
|
|
@@ -11112,13 +11114,47 @@ function toLicenseInfo(payload, cached, normalizedKey, source) {
|
|
|
11112
11114
|
// Prefer the signed `features` claim (authenticated) over the unauthenticated
|
|
11113
11115
|
// sidecar — falls back to the sidecar only for caches written before the
|
|
11114
11116
|
// payload was threaded through here.
|
|
11115
|
-
features: payload.features ?? cached.features
|
|
11117
|
+
features: payload.features ?? cached.features,
|
|
11118
|
+
latestVersion: cached.latestVersion
|
|
11116
11119
|
};
|
|
11117
11120
|
}
|
|
11118
11121
|
function normalizeUrl(url) {
|
|
11119
11122
|
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
11120
11123
|
}
|
|
11121
11124
|
|
|
11125
|
+
// src/license/update-notice.ts
|
|
11126
|
+
init_esm_shims();
|
|
11127
|
+
|
|
11128
|
+
// src/license/version.ts
|
|
11129
|
+
init_esm_shims();
|
|
11130
|
+
function parseTriple(v) {
|
|
11131
|
+
if (!v) return null;
|
|
11132
|
+
const m = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(v.trim());
|
|
11133
|
+
if (!m) return null;
|
|
11134
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
11135
|
+
}
|
|
11136
|
+
function isNewer(latest, current) {
|
|
11137
|
+
const l = parseTriple(latest);
|
|
11138
|
+
const c = parseTriple(current);
|
|
11139
|
+
if (!l || !c) return false;
|
|
11140
|
+
if (l[0] !== c[0]) return l[0] > c[0];
|
|
11141
|
+
if (l[1] !== c[1]) return l[1] > c[1];
|
|
11142
|
+
return l[2] > c[2];
|
|
11143
|
+
}
|
|
11144
|
+
|
|
11145
|
+
// src/license/update-notice.ts
|
|
11146
|
+
function maybePrintUpdateNotice(licenseInfo, currentVersion) {
|
|
11147
|
+
try {
|
|
11148
|
+
const latest = licenseInfo?.latestVersion;
|
|
11149
|
+
if (!latest || !isNewer(latest, currentVersion)) return;
|
|
11150
|
+
const shown = latest.replace(/[^\w.+-]/g, "");
|
|
11151
|
+
logger.info(
|
|
11152
|
+
`Update available: ${currentVersion} -> ${shown}. Run: npm i -D @reportforge/playwright-pdf@latest`
|
|
11153
|
+
);
|
|
11154
|
+
} catch {
|
|
11155
|
+
}
|
|
11156
|
+
}
|
|
11157
|
+
|
|
11122
11158
|
// src/analysis/index.ts
|
|
11123
11159
|
init_esm_shims();
|
|
11124
11160
|
|
|
@@ -14120,8 +14156,8 @@ var PdfReporter = class {
|
|
|
14120
14156
|
this.liveConsole = false;
|
|
14121
14157
|
this.options = parseOptions(rawOptions);
|
|
14122
14158
|
this.dataCollector = new DataCollector(this.options.capture);
|
|
14123
|
-
|
|
14124
|
-
logger.info(`@reportforge/playwright-pdf v${version} initialised`);
|
|
14159
|
+
this.version = true ? "0.17.0" : "0.x";
|
|
14160
|
+
logger.info(`@reportforge/playwright-pdf v${this.version} initialised`);
|
|
14125
14161
|
this.licenseClient = new LicenseClient({
|
|
14126
14162
|
licenseKey: this.options.licenseKey,
|
|
14127
14163
|
serverUrl: this.options.serverUrl,
|
|
@@ -14194,7 +14230,10 @@ var PdfReporter = class {
|
|
|
14194
14230
|
const licenseInfo = await this.license();
|
|
14195
14231
|
if (!licenseInfo) return;
|
|
14196
14232
|
const collected = this._collectData(result);
|
|
14197
|
-
if (!collected)
|
|
14233
|
+
if (!collected) {
|
|
14234
|
+
maybePrintUpdateNotice(licenseInfo, this.version);
|
|
14235
|
+
return;
|
|
14236
|
+
}
|
|
14198
14237
|
if (this.options.showTrend && collected.stats.total > 0) {
|
|
14199
14238
|
try {
|
|
14200
14239
|
this._appendTrend(collected);
|
|
@@ -14219,6 +14258,7 @@ var PdfReporter = class {
|
|
|
14219
14258
|
const sender = new NotificationSender();
|
|
14220
14259
|
await sender.sendAll(reportData, this.options.notify, pdfPaths);
|
|
14221
14260
|
}
|
|
14261
|
+
maybePrintUpdateNotice(licenseInfo, this.version);
|
|
14222
14262
|
}
|
|
14223
14263
|
_collectData(result) {
|
|
14224
14264
|
if (this.options.shardResults && this.options.shardResults.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reportforge/playwright-pdf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Playwright Test reporter that generates designed PDF reports: minimal, detailed, and executive templates with CI/CD integrations",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "Elastic-2.0",
|
|
6
6
|
"author": "ReportForge",
|
|
7
7
|
"homepage": "https://reportforge.org",
|
|
8
8
|
"repository": {
|