@reportforge/playwright-pdf 0.0.1 → 0.2.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 CHANGED
@@ -53,7 +53,8 @@ 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
  - **CI/CD snippets** — GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps
55
55
  - **Shard merging** — combine N Playwright JSON shard reports into one PDF via `shardResults`; accepts glob patterns or explicit paths
56
- - **Webhook notifications** — post pass/fail summaries to Slack, Teams, or Discord on every run; configurable per channel with `on: 'always' | 'failure' | 'success'`
56
+ - **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`
57
+ - **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)
57
58
  - **Hybrid licensing** — one short key unlocks it; reports keep rendering offline via a cached JWT between refreshes
58
59
 
59
60
  ---
@@ -183,10 +184,11 @@ All options are the second element of the reporter tuple.
183
184
  | `serverUrl` | `string` | `'https://reportforge.org'` | Licensing server base URL (override only for self-hosting) |
184
185
  | `open` | `boolean` | `false` | Open PDF after generation (local only) |
185
186
  | `shardResults` | `string \| string[]` | — | Glob or path array of Playwright JSON shard files to merge into one PDF. |
186
- | `notify` | `object` | — | Webhook notification channels. See [Webhook Notifications](#webhook-notifications). |
187
+ | `notify` | `object` | — | Notification channels: `slack`, `teams`, `discord` (each `{ url, enabled, on }`), `email` (`{ to, enabled, on, attachPdf }`). See [Notifications](#notifications). |
187
188
  | `historyFile` | `string` | `~/.reportforge/{key}/history.json` | Path to history JSON. Relative paths resolved from cwd at startup. |
188
189
  | `historySize` | `number` | `10` | Max run entries to keep (integer ≥ 2). |
189
- | `showTrend` | `boolean` | `true` | Set to `false` to disable history write and sparkline entirely. |
190
+ | `showTrend` | `boolean` | `true` | Set to `false` to disable history write and trend charts entirely. |
191
+ | `flakinessTopN` | `number` | `5` | Max flaky tests to show in the `detailed` template flakiness table. `0` disables the table. |
190
192
  | `puppeteerExecutablePath` | `string` | auto-detect | Path to Chrome / Chromium |
191
193
 
192
194
  Full reference: [reportforge.org/docs#configuration](https://reportforge.org/docs#configuration).
@@ -215,30 +217,37 @@ The merge step can run against a dummy test file with zero tests — `shardResul
215
217
 
216
218
  > **Note:** Timed-out tests are counted as failures in shard mode (Playwright JSON stats do not distinguish `timedOut` from `failed`).
217
219
 
218
- ### Webhook Notifications
220
+ ### Notifications
219
221
 
220
- Post a summary message to Slack, Teams, or Discord after each run.
222
+ Post a summary to Slack, Teams, Discord, or email after each run.
221
223
 
222
224
  ```typescript
223
225
  notify: {
224
226
  slack: {
225
- url: 'https://hooks.slack.com/services/...',
226
- enabled: true, // required — defaults to false
227
- on: 'always', // 'always' | 'failure' | 'success' (default: 'always')
227
+ url: process.env.SLACK_WEBHOOK_URL,
228
+ enabled: true,
229
+ on: 'failure', // 'always' | 'failure' | 'success' (default: 'always')
228
230
  },
229
231
  teams: {
230
- url: 'https://outlook.office.com/webhook/...',
232
+ url: process.env.TEAMS_WEBHOOK_URL,
231
233
  enabled: true,
232
- on: 'failure',
234
+ on: 'always',
233
235
  },
234
236
  discord: {
235
- url: 'https://discord.com/api/webhooks/...',
237
+ url: process.env.DISCORD_WEBHOOK_URL,
238
+ enabled: true,
239
+ on: 'failure',
240
+ },
241
+ email: {
242
+ to: ['team@company.com', 'qa@company.com'],
236
243
  enabled: true,
244
+ on: 'failure',
245
+ attachPdf: false, // set true to attach the generated PDF
237
246
  },
238
247
  },
239
248
  ```
240
249
 
241
- Each channel is independent. `enabled: false` (the default) lets you store a URL without activating it — useful for staging configs. Set `enabled: true` to activate.
250
+ Each channel is independent. `enabled: false` (the default) lets you store a URL without activating it — useful for staging configs.
242
251
 
243
252
  The `on` trigger controls when the message fires:
244
253
 
@@ -248,7 +257,9 @@ The `on` trigger controls when the message fires:
248
257
  | `'failure'` | `stats.failed > 0` or run timed out / interrupted |
249
258
  | `'success'` | All tests passed |
250
259
 
251
- The summary includes pass rate, test counts, duration, and the report filename. Notifications require a valid license and fire after PDF generation (or after a PDF generation failureyou still get the ping).
260
+ **Email** requires `RESEND_API_KEY` in the environment (get one at [resend.com](https://resend.com)). Sender defaults to `noreply@reportforge.org`; override with `RESEND_FROM`. Store webhook URLs and API keys as CI secretsnever commit them.
261
+
262
+ The summary includes pass rate, test counts, duration, and the report filename. Notifications require a valid license and fire after PDF generation (or after a PDF failure — you still get the ping).
252
263
 
253
264
  ### Test History Trending
254
265
 
@@ -277,6 +288,19 @@ reporter: [['@reportforge/playwright-pdf', {
277
288
 
278
289
  **Monorepo** — each package needs a distinct `historyFile` (e.g. `.reportforge/api-history.json`, `.reportforge/web-history.json`) so runs do not overwrite each other.
279
290
 
291
+ ### Flakiness Trend Table
292
+
293
+ The `detailed` template includes a **Top flaky tests** table showing which tests flake most often across your stored history. Each row shows the test name, flake rate (%), run count, and a dot sparkline (amber dot = flaky in that run).
294
+
295
+ ```typescript
296
+ reporter: [['@reportforge/playwright-pdf', {
297
+ template: 'detailed',
298
+ flakinessTopN: 5, // default — show top 5; set 0 to disable
299
+ }]]
300
+ ```
301
+
302
+ The table is gated behind `showTrend: true` (the default) and appears automatically once history entries are present. Runs written before the flakiness feature was added are excluded from the denominator — the table fills in correctly as newer runs accumulate. Set `flakinessTopN: 0` to hide the table entirely.
303
+
280
304
  ### Filename tokens
281
305
 
282
306
  | Token | Replaced with | Example |
package/dist/index.d.mts CHANGED
@@ -176,6 +176,24 @@ interface ReporterOptions {
176
176
  * @default true
177
177
  */
178
178
  showTrend?: boolean;
179
+ /**
180
+ * Number of flaky tests to display in the flakiness table (detailed template).
181
+ * Set to 0 to disable. Must be a non-negative integer.
182
+ * @default 5
183
+ */
184
+ flakinessTopN?: number;
185
+ /**
186
+ * Path to a custom Handlebars (.hbs) template file. When set, takes
187
+ * precedence over `template`. Relative paths resolve from `process.cwd()`.
188
+ * Pass an array to generate one PDF per template in a single run — each
189
+ * output filename gets the template basename injected automatically.
190
+ *
191
+ * @example
192
+ * templatePath: './templates/brand-report.hbs'
193
+ * @example
194
+ * templatePath: ['./templates/exec.hbs', './templates/eng.hbs']
195
+ */
196
+ templatePath?: string | string[];
179
197
  }
180
198
 
181
199
  /**
@@ -244,6 +262,7 @@ declare class PdfReporter implements Reporter {
244
262
  onEnd(result: FullResult): Promise<void>;
245
263
  private _collectData;
246
264
  private _appendTrend;
265
+ private _populateHistoryCharts;
247
266
  private _buildReportData;
248
267
  printsToStdio(): boolean;
249
268
  private resolveLicense;
package/dist/index.d.ts CHANGED
@@ -176,6 +176,24 @@ interface ReporterOptions {
176
176
  * @default true
177
177
  */
178
178
  showTrend?: boolean;
179
+ /**
180
+ * Number of flaky tests to display in the flakiness table (detailed template).
181
+ * Set to 0 to disable. Must be a non-negative integer.
182
+ * @default 5
183
+ */
184
+ flakinessTopN?: number;
185
+ /**
186
+ * Path to a custom Handlebars (.hbs) template file. When set, takes
187
+ * precedence over `template`. Relative paths resolve from `process.cwd()`.
188
+ * Pass an array to generate one PDF per template in a single run — each
189
+ * output filename gets the template basename injected automatically.
190
+ *
191
+ * @example
192
+ * templatePath: './templates/brand-report.hbs'
193
+ * @example
194
+ * templatePath: ['./templates/exec.hbs', './templates/eng.hbs']
195
+ */
196
+ templatePath?: string | string[];
179
197
  }
180
198
 
181
199
  /**
@@ -244,6 +262,7 @@ declare class PdfReporter implements Reporter {
244
262
  onEnd(result: FullResult): Promise<void>;
245
263
  private _collectData;
246
264
  private _appendTrend;
265
+ private _populateHistoryCharts;
247
266
  private _buildReportData;
248
267
  printsToStdio(): boolean;
249
268
  private resolveLicense;