@reportforge/playwright-pdf 0.16.1 → 0.18.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 CHANGED
@@ -3,11 +3,30 @@
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.18.0] - 2026-07-11
7
+
8
+ ### Changed
9
+
10
+ - **Node 20 is now the minimum supported version** (was Node 18). Node 18 reached end-of-life in April 2025 and no longer receives security patches, and dependencies have begun dropping support for it. If you are still on Node 18, upgrade to Node 20 or later before taking this release. CI now tests against Node 20, 22, and 24.
11
+ - `puppeteer-core` is now supported up to v25 (peer range widened to `>=21 <26`). Existing v21 to v24 installs keep working, so no action is needed unless you want to upgrade.
12
+ - Internal dependency updates: `sharp` 0.35 (which requires Node 20), and `@types/node` 26.
13
+
14
+ ---
15
+
16
+ ## [0.17.0] - 2026-07-09
17
+
18
+ ### Added
19
+
20
+ - **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.
21
+ - **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.
22
+
23
+ ---
24
+
6
25
  ## [0.16.1] - 2026-07-09
7
26
 
8
27
  ### Changed
9
28
 
10
- - **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`). Versions 0.16.0 and earlier were published under MIT and remain MIT.
29
+ - **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`).
11
30
 
12
31
  ---
13
32
 
package/README.md CHANGED
@@ -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 large runs switch to full-width suite charts that continue across pages, so per-suite coverage and failures stay visible run-wide
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 · ~2931% saving vs monthly |
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 50010000, 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
+ | `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 (50010000)
229
+ // flushMs: 2000, // batch debounce (500-10000)
229
230
  },
230
231
  }],
231
232
  ],
@@ -676,8 +677,10 @@ Full documentation at [reportforge.org/docs](https://reportforge.org/docs):
676
677
 
677
678
  Questions and bug reports: email [support@reportforge.org](mailto:support@reportforge.org).
678
679
 
679
- ## License
680
+ ## Security
681
+
682
+ Found a vulnerability? Email [support@reportforge.org](mailto:support@reportforge.org) with a subject starting with `[SECURITY]` — please don't open a public issue. Details, scope, and response timelines are in [SECURITY.md](./SECURITY.md); machine-readable contact data is at [reportforge.org/.well-known/security.txt](https://reportforge.org/.well-known/security.txt).
680
683
 
681
- [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.
684
+ ## License
682
685
 
683
- Versions 0.16.0 and earlier shipped under MIT and stay MIT.
686
+ [Elastic License 2.0](./LICENSE). The license does not allow offering the software as a hosted service, bypassing or removing the license-key check, or stripping license or copyright notices. Generating PDF reports requires an active subscription.
package/SECURITY.md ADDED
@@ -0,0 +1,50 @@
1
+ # Security Policy
2
+
3
+ ReportForge handles license keys, payment webhooks, and customer data. We take
4
+ vulnerability reports seriously and appreciate coordinated disclosure.
5
+
6
+ ## Reporting a vulnerability
7
+
8
+ Email **[support@reportforge.org](mailto:support@reportforge.org)** with the
9
+ subject line starting with `[SECURITY]`.
10
+
11
+ Please include:
12
+
13
+ - A description of the issue and where it lives (npm package
14
+ `@reportforge/playwright-pdf`, the `reportforge.org` service, or both).
15
+ - Steps to reproduce, or a proof of concept.
16
+ - The version(s) affected, if known.
17
+
18
+ Please do **not** open a public GitHub issue for security reports, and do not
19
+ test against production customer data — a trial subscription gives you a full
20
+ legitimate environment to test the license flow.
21
+
22
+ ## What to expect
23
+
24
+ - **Acknowledgement within 48 hours** of your report.
25
+ - A triage verdict (accepted / not a vulnerability / duplicate) within 7 days.
26
+ - If accepted: a fix or mitigation timeline, and credit in the release notes
27
+ if you want it. We ask for up to **90 days** of coordinated disclosure
28
+ before you publish details.
29
+ - We do not currently run a paid bounty program.
30
+
31
+ ## Scope
32
+
33
+ In scope:
34
+
35
+ - The npm package `@reportforge/playwright-pdf` (report generation, license
36
+ client, bundled assets).
37
+ - The `reportforge.org` service: license API, dashboard, checkout, webhooks.
38
+
39
+ Out of scope:
40
+
41
+ - Denial of service / volumetric attacks.
42
+ - Reports about the 25-machine licensing cap working as documented.
43
+ - Vulnerabilities exclusively in third-party services we integrate
44
+ (Razorpay, Clerk, Vercel, Resend) — report those upstream.
45
+
46
+ ## Supported versions
47
+
48
+ Only the latest published version of `@reportforge/playwright-pdf` receives
49
+ security fixes. Machine-readable contact data is published at
50
+ [`https://reportforge.org/.well-known/security.txt`](https://reportforge.org/.well-known/security.txt).
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
- const version = true ? "0.16.1" : "0.x";
14123
- logger.info(`@reportforge/playwright-pdf v${version} initialised`);
14158
+ this.version = true ? "0.18.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) return;
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
- const version = true ? "0.16.1" : "0.x";
14124
- logger.info(`@reportforge/playwright-pdf v${version} initialised`);
14159
+ this.version = true ? "0.18.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) return;
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,16 +1,11 @@
1
1
  {
2
2
  "name": "@reportforge/playwright-pdf",
3
- "version": "0.16.1",
3
+ "version": "0.18.0",
4
4
  "description": "Playwright Test reporter that generates designed PDF reports: minimal, detailed, and executive templates with CI/CD integrations",
5
5
  "license": "Elastic-2.0",
6
6
  "author": "ReportForge",
7
7
  "homepage": "https://reportforge.org",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/muralidharan92/reportforge"
11
- },
12
8
  "bugs": {
13
- "url": "https://github.com/muralidharan92/reportforge/issues",
14
9
  "email": "support@reportforge.org"
15
10
  },
16
11
  "keywords": [
@@ -30,7 +25,11 @@
30
25
  "pdf-generator",
31
26
  "ci",
32
27
  "puppeteer",
33
- "html-to-pdf"
28
+ "html-to-pdf",
29
+ "reportforge",
30
+ "reportforge-playwright-pdf",
31
+ "report",
32
+ "forge"
34
33
  ],
35
34
  "main": "./dist/index.js",
36
35
  "module": "./dist/index.mjs",
@@ -53,7 +52,8 @@
53
52
  "ci-templates",
54
53
  "README.md",
55
54
  "CHANGELOG.md",
56
- "LICENSE"
55
+ "LICENSE",
56
+ "SECURITY.md"
57
57
  ],
58
58
  "scripts": {
59
59
  "prebuild": "npm run bundle-chartjs && npm run bundle-fonts && npm run bundle-pubkey && npm run bundle-model && npm run precompile-templates",
@@ -82,14 +82,14 @@
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@playwright/test": ">=1.40.0",
85
- "puppeteer-core": ">=21.0.0 <25.0.0"
85
+ "puppeteer-core": ">=21.0.0 <26.0.0"
86
86
  },
87
87
  "dependencies": {
88
88
  "chrome-finder": "^1.0.7",
89
89
  "framer-motion": "^12.40.0",
90
90
  "glob": "^13.0.6",
91
91
  "handlebars": "^4.7.8",
92
- "sharp": "^0.34.5",
92
+ "sharp": "^0.35.3",
93
93
  "zod": "^3.23.8"
94
94
  },
95
95
  "devDependencies": {
@@ -98,20 +98,20 @@
98
98
  "@fontsource/source-serif-pro": "^5.2.5",
99
99
  "@playwright/test": "^1.49.0",
100
100
  "@types/handlebars": "^4.1.0",
101
- "@types/node": "^22.0.0",
101
+ "@types/node": "^26.1.1",
102
102
  "@typescript-eslint/eslint-plugin": "^8.0.0",
103
103
  "@typescript-eslint/parser": "^8.0.0",
104
- "@vitest/coverage-v8": "^2.1.0",
104
+ "@vitest/coverage-v8": "^4.1.10",
105
105
  "chart.js": "^4.4.0",
106
106
  "eslint": "^9.0.0",
107
107
  "prettier": "^3.3.0",
108
- "puppeteer-core": "^23.0.0",
108
+ "puppeteer-core": "^25.3.0",
109
109
  "tsup": "^8.3.0",
110
110
  "tsx": "^4.19.0",
111
- "typescript": "^5.6.0",
112
- "vitest": "^2.1.0"
111
+ "typescript": "^5.9.3",
112
+ "vitest": "^4.1.10"
113
113
  },
114
114
  "engines": {
115
- "node": ">=18.0.0"
115
+ "node": ">=20.0.0"
116
116
  }
117
117
  }