@reportforge/playwright-pdf 0.0.1
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 +285 -0
- package/LICENSE +21 -0
- package/README.md +524 -0
- package/ci-templates/azure-devops/azure-pipelines.yml +58 -0
- package/ci-templates/bitbucket/bitbucket-pipelines.yml +42 -0
- package/ci-templates/github-actions/basic-workflow.yml +44 -0
- package/ci-templates/github-actions/matrix-workflow.yml +69 -0
- package/ci-templates/gitlab-ci/.gitlab-ci.yml +42 -0
- package/ci-templates/jenkins/Jenkinsfile +54 -0
- package/dist/index.d.mts +272 -0
- package/dist/index.d.ts +272 -0
- package/dist/index.js +12566 -0
- package/dist/index.mjs +12567 -0
- package/dist/templates/layouts/detailed.hbs +38 -0
- package/dist/templates/layouts/executive.hbs +35 -0
- package/dist/templates/layouts/minimal.hbs +29 -0
- package/dist/templates/partials/charts.hbs +306 -0
- package/dist/templates/partials/ci-environment.hbs +56 -0
- package/dist/templates/partials/cover-page.hbs +46 -0
- package/dist/templates/partials/defect-log.hbs +27 -0
- package/dist/templates/partials/executive-summary.hbs +60 -0
- package/dist/templates/partials/failure-deep-dive.hbs +61 -0
- package/dist/templates/partials/head.hbs +17 -0
- package/dist/templates/partials/release-gate.hbs +63 -0
- package/dist/templates/partials/requirements-matrix.hbs +35 -0
- package/dist/templates/partials/slow-tests.hbs +27 -0
- package/dist/templates/partials/suite-breakdown.hbs +58 -0
- package/dist/templates/partials/watermark.hbs +3 -0
- package/dist/templates/styles/base.css +234 -0
- package/dist/templates/styles/detailed.css +311 -0
- package/dist/templates/styles/executive.css +334 -0
- package/dist/templates/styles/minimal.css +208 -0
- package/package.json +99 -0
package/README.md
ADDED
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
# @reportforge/playwright-pdf
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
Drop it into any Playwright project and get a PDF report on every CI run. No changes to your tests.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@reportforge/playwright-pdf)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://reportforge.org/pricing">
|
|
13
|
+
<img src="https://img.shields.io/badge/Start%20Free%20Trial-reportforge.org%2Fpricing-CC785C?style=for-the-badge" alt="Start free trial at reportforge.org/pricing" />
|
|
14
|
+
</a><br>
|
|
15
|
+
<sub>7-day trial · ₹999/mo or $12/mo after · 25 machines · all 3 templates · cancel anytime</sub>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
**[Docs](https://reportforge.org/docs)** · **[Pricing](https://reportforge.org/pricing)** · **[Support](mailto:support@reportforge.org)**
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Report Gallery
|
|
23
|
+
|
|
24
|
+
Three templates, one reporter. Every PDF is fully offline — fonts, charts, and screenshots are embedded.
|
|
25
|
+
|
|
26
|
+
<table>
|
|
27
|
+
<tr>
|
|
28
|
+
<th align="center"><code>minimal</code><br/><sub>Developer / PR checks</sub></th>
|
|
29
|
+
<th align="center"><code>detailed</code><br/><sub>QA team</sub></th>
|
|
30
|
+
<th align="center"><code>executive</code><br/><sub>Stakeholders</sub></th>
|
|
31
|
+
</tr>
|
|
32
|
+
<tr>
|
|
33
|
+
<td><a href="https://reportforge.org/template-minimal.png"><img src="https://reportforge.org/template-minimal.png" alt="minimal template preview" width="300"/></a></td>
|
|
34
|
+
<td><a href="https://reportforge.org/template-detailed.png"><img src="https://reportforge.org/template-detailed.png" alt="detailed template preview" width="300"/></a></td>
|
|
35
|
+
<td><a href="https://reportforge.org/template-executive.png"><img src="https://reportforge.org/template-executive.png" alt="executive template preview" width="300"/></a></td>
|
|
36
|
+
</tr>
|
|
37
|
+
<tr>
|
|
38
|
+
<td align="center"><sub>KPI dashboard · suite breakdown · failure stack traces · embedded screenshots</sub></td>
|
|
39
|
+
<td align="center"><sub>Everything in minimal <strong>+ charts · requirements matrix · defect log · full environment</strong></sub></td>
|
|
40
|
+
<td align="center"><sub>Cover page · KPI dashboard · charts · failure summary <em>(no stack traces)</em></sub></td>
|
|
41
|
+
</tr>
|
|
42
|
+
</table>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **3 templates** — `minimal` (developer), `detailed` (QA team), `executive` (stakeholders)
|
|
49
|
+
- **Detailed reports** — KPI dashboard, suite breakdown, failure deep-dive with screenshots, CI/CD environment
|
|
50
|
+
- **Embedded Chart.js** — pass-rate doughnut + per-suite bar chart, bundled inline (no CDN)
|
|
51
|
+
- **Self-contained PDFs** — screenshots, fonts, logos all embedded; share or archive with confidence
|
|
52
|
+
- **Custom branding** — logo, primary/accent colours, watermark, PDF password encryption
|
|
53
|
+
- **Dynamic filenames** — `{date}`, `{branch}`, `{status}` tokens in the output path
|
|
54
|
+
- **CI/CD snippets** — GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps
|
|
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'`
|
|
57
|
+
- **Hybrid licensing** — one short key unlocks it; reports keep rendering offline via a cached JWT between refreshes
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm install --save-dev @reportforge/playwright-pdf puppeteer-core
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
// playwright.config.ts
|
|
69
|
+
import { defineConfig } from '@playwright/test';
|
|
70
|
+
import { defineReporterConfig } from '@reportforge/playwright-pdf';
|
|
71
|
+
|
|
72
|
+
export default defineConfig({
|
|
73
|
+
reporter: [
|
|
74
|
+
['@reportforge/playwright-pdf', defineReporterConfig({
|
|
75
|
+
template: 'detailed',
|
|
76
|
+
outputFile: 'reports/{date}-{branch}-{status}.pdf',
|
|
77
|
+
})],
|
|
78
|
+
],
|
|
79
|
+
use: { screenshot: 'only-on-failure' },
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`defineReporterConfig` is an optional typed identity helper — it gives you IntelliSense and type-checking on the options object without a separate `ReporterOptions` import. You can also pass a plain object literal if you prefer.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx playwright test
|
|
87
|
+
# → reports/2026-05-01-main-failed.pdf
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
> **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.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Installation
|
|
95
|
+
|
|
96
|
+
### Requirements
|
|
97
|
+
|
|
98
|
+
- Node.js ≥ 18
|
|
99
|
+
- `@playwright/test` ≥ 1.40 (peer dependency)
|
|
100
|
+
- `puppeteer-core` ≥ 21 (peer dependency)
|
|
101
|
+
- Chrome or Chromium installed on the machine
|
|
102
|
+
|
|
103
|
+
### Chrome setup
|
|
104
|
+
|
|
105
|
+
The reporter auto-detects Chrome via `PUPPETEER_EXECUTABLE_PATH`, then system Chrome, then `chrome-finder`. Full per-OS instructions: [reportforge.org/docs#chrome-setup](https://reportforge.org/docs#chrome-setup).
|
|
106
|
+
|
|
107
|
+
**Windows**
|
|
108
|
+
|
|
109
|
+
```powershell
|
|
110
|
+
winget install Google.Chrome
|
|
111
|
+
$env:PUPPETEER_EXECUTABLE_PATH = "C:\Program Files\Google\Chrome\Application\chrome.exe"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Linux (Debian / Ubuntu)**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | \
|
|
118
|
+
sudo gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
|
|
119
|
+
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] \
|
|
120
|
+
http://dl.google.com/linux/chrome/deb/ stable main" | \
|
|
121
|
+
sudo tee /etc/apt/sources.list.d/google-chrome.list
|
|
122
|
+
sudo apt-get update -qq && sudo apt-get install -y google-chrome-stable
|
|
123
|
+
export PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> **Note:** Do not use the `chromium-browser` apt package — it installs as a snap on Ubuntu and Puppeteer cannot drive it.
|
|
127
|
+
|
|
128
|
+
**macOS**
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
brew install --cask google-chrome
|
|
132
|
+
export PUPPETEER_EXECUTABLE_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Or set the path in `playwright.config.ts`:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
reporter: [['@reportforge/playwright-pdf', {
|
|
139
|
+
puppeteerExecutablePath: '/usr/bin/google-chrome-stable',
|
|
140
|
+
}]]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Pricing
|
|
146
|
+
|
|
147
|
+
| Plan | INR | USD | Includes |
|
|
148
|
+
|---|---|---|---|
|
|
149
|
+
| **Monthly** | **₹999 / month** | **$12 / month** | All three templates · custom branding · PDF encryption · up to 25 active machines · priority email support |
|
|
150
|
+
| **Yearly** | **₹8,499 / year** | **$99 / year** | Everything in Monthly · ~29–31% saving vs monthly |
|
|
151
|
+
|
|
152
|
+
Currency is auto-detected by region; toggle on the pricing page.
|
|
153
|
+
|
|
154
|
+
<p align="center">
|
|
155
|
+
<a href="https://reportforge.org/pricing">
|
|
156
|
+
<img src="https://img.shields.io/badge/Start%20Free%20Trial-reportforge.org%2Fpricing-CC785C?style=for-the-badge" alt="Start free trial" />
|
|
157
|
+
</a><br>
|
|
158
|
+
<sub>7-day trial · no charge until day 8 · cancel anytime from your dashboard</sub>
|
|
159
|
+
</p>
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
All options are the second element of the reporter tuple.
|
|
166
|
+
|
|
167
|
+
| Option | Type | Default | Description |
|
|
168
|
+
|---|---|---|---|
|
|
169
|
+
| `template` | `'minimal' \| 'detailed' \| 'executive'` or array | `'minimal'` | Template(s) to generate. Pass an array to produce one PDF per template — the template name is appended automatically (e.g. `report-detailed.pdf`). |
|
|
170
|
+
| `outputFile` | `string` | `'playwright-report/{date}-report.pdf'` | Output path (supports tokens) |
|
|
171
|
+
| `reportTitle` | `string` | `'Playwright Test Report'` | Title in header and cover |
|
|
172
|
+
| `projectName` | `string` | from `package.json` | Project name shown in report |
|
|
173
|
+
| `logo` | `string` | — | Path to logo image (PNG / JPG / SVG) |
|
|
174
|
+
| `primaryColor` | `string` | `'#CC785C'` | Brand colour (hex) |
|
|
175
|
+
| `accentColor` | `string` | `'#3F7D58'` | Accent colour (hex) |
|
|
176
|
+
| `watermark` | `string` | — | Diagonal watermark text (e.g. `'CONFIDENTIAL'`) |
|
|
177
|
+
| `pdfPassword` | `string` | — | Password-protect the PDF (requires `qpdf`) |
|
|
178
|
+
| `licenseKey` | `string` | env `RF_LICENSE_KEY` | Subscription key (format `RFSU-…`) |
|
|
179
|
+
| `compressionLevel` | `'auto' \| 'none' \| 'balanced' \| 'max'` | `'auto'` | Screenshot JPEG quality + inline failure cap |
|
|
180
|
+
| `includeScreenshots` | `boolean` | `true` | Embed screenshots in the PDF. Set to `false` to omit images — useful for exec-audience reports or reducing file size. |
|
|
181
|
+
| `maxInlineFailures` | `number` | derived from `compressionLevel` | Cap on inline failures; overflow spills to `{basename}-failures.json` |
|
|
182
|
+
| `maxFileSizeMb` | `number` | `8` | Soft cap; reporter re-renders with `max` compression once if exceeded |
|
|
183
|
+
| `serverUrl` | `string` | `'https://reportforge.org'` | Licensing server base URL (override only for self-hosting) |
|
|
184
|
+
| `open` | `boolean` | `false` | Open PDF after generation (local only) |
|
|
185
|
+
| `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
|
+
| `historyFile` | `string` | `~/.reportforge/{key}/history.json` | Path to history JSON. Relative paths resolved from cwd at startup. |
|
|
188
|
+
| `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
|
+
| `puppeteerExecutablePath` | `string` | auto-detect | Path to Chrome / Chromium |
|
|
191
|
+
|
|
192
|
+
Full reference: [reportforge.org/docs#configuration](https://reportforge.org/docs#configuration).
|
|
193
|
+
|
|
194
|
+
### Shard Merging
|
|
195
|
+
|
|
196
|
+
Combine parallel Playwright shards into one PDF without re-running any tests.
|
|
197
|
+
|
|
198
|
+
**Workflow:**
|
|
199
|
+
|
|
200
|
+
1. Run each shard with `--reporter=json` to produce a JSON output file.
|
|
201
|
+
2. In a separate step, point `shardResults` at those files — accepts a glob or an explicit array.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// playwright.config.ts (merge step)
|
|
205
|
+
reporter: [
|
|
206
|
+
['@reportforge/playwright-pdf', {
|
|
207
|
+
shardResults: 'results/shard-*.json', // glob
|
|
208
|
+
// or: shardResults: ['results/shard-1.json', 'results/shard-2.json'],
|
|
209
|
+
outputFile: 'reports/{date}-report.pdf',
|
|
210
|
+
}],
|
|
211
|
+
],
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The merge step can run against a dummy test file with zero tests — `shardResults` takes precedence over live results.
|
|
215
|
+
|
|
216
|
+
> **Note:** Timed-out tests are counted as failures in shard mode (Playwright JSON stats do not distinguish `timedOut` from `failed`).
|
|
217
|
+
|
|
218
|
+
### Webhook Notifications
|
|
219
|
+
|
|
220
|
+
Post a summary message to Slack, Teams, or Discord after each run.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
notify: {
|
|
224
|
+
slack: {
|
|
225
|
+
url: 'https://hooks.slack.com/services/...',
|
|
226
|
+
enabled: true, // required — defaults to false
|
|
227
|
+
on: 'always', // 'always' | 'failure' | 'success' (default: 'always')
|
|
228
|
+
},
|
|
229
|
+
teams: {
|
|
230
|
+
url: 'https://outlook.office.com/webhook/...',
|
|
231
|
+
enabled: true,
|
|
232
|
+
on: 'failure',
|
|
233
|
+
},
|
|
234
|
+
discord: {
|
|
235
|
+
url: 'https://discord.com/api/webhooks/...',
|
|
236
|
+
enabled: true,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
```
|
|
240
|
+
|
|
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.
|
|
242
|
+
|
|
243
|
+
The `on` trigger controls when the message fires:
|
|
244
|
+
|
|
245
|
+
| Value | Sends when |
|
|
246
|
+
|---|---|
|
|
247
|
+
| `'always'` | Every run |
|
|
248
|
+
| `'failure'` | `stats.failed > 0` or run timed out / interrupted |
|
|
249
|
+
| `'success'` | All tests passed |
|
|
250
|
+
|
|
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 failure — you still get the ping).
|
|
252
|
+
|
|
253
|
+
### Test History Trending
|
|
254
|
+
|
|
255
|
+
After each run the reporter appends a summary entry to a local JSON file and renders a pass-rate sparkline + verdict row in the `detailed` template.
|
|
256
|
+
|
|
257
|
+
**Local dev (zero config)** — history is written automatically to `~/.reportforge/{projectKey}/history.json`. The sparkline appears once two or more runs have been recorded.
|
|
258
|
+
|
|
259
|
+
**CI with ephemeral runners** — set `historyFile` to a project-relative path and cache it between runs:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// playwright.config.ts
|
|
263
|
+
reporter: [['@reportforge/playwright-pdf', {
|
|
264
|
+
template: 'detailed',
|
|
265
|
+
historyFile: '.reportforge/history.json',
|
|
266
|
+
}]]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
# .github/workflows/test.yml
|
|
271
|
+
- uses: actions/cache@v4
|
|
272
|
+
with:
|
|
273
|
+
path: .reportforge/history.json
|
|
274
|
+
key: reportforge-history-${{ github.ref }}
|
|
275
|
+
# Omit restore-keys — cross-branch fallback causes misleading sparklines on PRs
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**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
|
+
|
|
280
|
+
### Filename tokens
|
|
281
|
+
|
|
282
|
+
| Token | Replaced with | Example |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| `{date}` | `YYYY-MM-DD` (UTC) | `2026-04-21` |
|
|
285
|
+
| `{branch}` | Git branch, sanitised | `feature-auth` |
|
|
286
|
+
| `{status}` | Overall verdict | `passed` / `failed` / `timedout` / `interrupted` |
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Templates
|
|
291
|
+
|
|
292
|
+
### `minimal` — Developer-focused
|
|
293
|
+
|
|
294
|
+
Clean layout, KPI numbers, hierarchical test table, failure details with stack traces and embedded screenshots. Fast to generate. Good for local development and PR checks.
|
|
295
|
+
|
|
296
|
+
### `detailed` — QA Team
|
|
297
|
+
|
|
298
|
+
Everything in `minimal`, **plus** Chart.js pass-rate + suite-results charts, a numbered defect log, a requirements traceability matrix derived from `@TAG` annotations, and the full CI/CD environment table.
|
|
299
|
+
|
|
300
|
+
### `executive` — Stakeholder presentations
|
|
301
|
+
|
|
302
|
+
Full-page cover with verdict + KPI strip, followed by a compact dashboard with charts and a failures summary (titles only — **no raw stack traces**). Best for sprint reports and management dashboards.
|
|
303
|
+
|
|
304
|
+
### Generating multiple templates in one run
|
|
305
|
+
|
|
306
|
+
Pass an array to `template` to generate one PDF per template from a single test run. The template name is appended to the output filename automatically:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
// playwright.config.ts
|
|
310
|
+
reporter: [
|
|
311
|
+
['@reportforge/playwright-pdf', {
|
|
312
|
+
template: ['detailed', 'executive'],
|
|
313
|
+
outputFile: 'reports/{date}-report.pdf',
|
|
314
|
+
licenseKey: process.env.RF_LICENSE_KEY,
|
|
315
|
+
}],
|
|
316
|
+
]
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
# → reports/2026-04-28-report-detailed.pdf
|
|
321
|
+
# → reports/2026-04-28-report-executive.pdf
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
One license check, one data-collection pass — faster than multiple reporter instances. Duplicate entries are silently deduplicated.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## CI/CD Integration
|
|
329
|
+
|
|
330
|
+
Full workflows for all four CI providers: [reportforge.org/docs#ci-cd](https://reportforge.org/docs#ci-cd).
|
|
331
|
+
|
|
332
|
+
### GitHub Actions
|
|
333
|
+
|
|
334
|
+
```yaml
|
|
335
|
+
- name: Run Playwright tests
|
|
336
|
+
run: npx playwright test
|
|
337
|
+
env:
|
|
338
|
+
RF_LICENSE_KEY: ${{ secrets.RF_LICENSE_KEY }}
|
|
339
|
+
PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome-stable
|
|
340
|
+
|
|
341
|
+
- name: Upload PDF report
|
|
342
|
+
if: always()
|
|
343
|
+
uses: actions/upload-artifact@v4
|
|
344
|
+
with:
|
|
345
|
+
name: playwright-pdf-report
|
|
346
|
+
path: reports/*.pdf
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### GitHub Actions — Sharded runs
|
|
350
|
+
|
|
351
|
+
Run shards in parallel with `--reporter=json`, then merge all JSON files into one PDF:
|
|
352
|
+
|
|
353
|
+
```yaml
|
|
354
|
+
jobs:
|
|
355
|
+
test:
|
|
356
|
+
strategy:
|
|
357
|
+
matrix:
|
|
358
|
+
shard: [1, 2, 3, 4]
|
|
359
|
+
runs-on: ubuntu-latest
|
|
360
|
+
steps:
|
|
361
|
+
- uses: actions/checkout@v4
|
|
362
|
+
- uses: actions/setup-node@v4
|
|
363
|
+
with: { node-version: '20' }
|
|
364
|
+
- run: npm ci
|
|
365
|
+
- run: npx playwright test --shard=${{ matrix.shard }}/4 --reporter=json
|
|
366
|
+
env:
|
|
367
|
+
PLAYWRIGHT_JSON_OUTPUT_NAME: results/shard-${{ matrix.shard }}.json
|
|
368
|
+
- uses: actions/upload-artifact@v4
|
|
369
|
+
with:
|
|
370
|
+
name: shard-json-${{ matrix.shard }}
|
|
371
|
+
path: results/shard-${{ matrix.shard }}.json
|
|
372
|
+
|
|
373
|
+
merge-pdf:
|
|
374
|
+
needs: test
|
|
375
|
+
runs-on: ubuntu-latest
|
|
376
|
+
steps:
|
|
377
|
+
- uses: actions/checkout@v4
|
|
378
|
+
- uses: actions/setup-node@v4
|
|
379
|
+
with: { node-version: '20' }
|
|
380
|
+
- run: npm ci
|
|
381
|
+
- uses: actions/download-artifact@v4
|
|
382
|
+
with: { pattern: shard-json-*, merge-multiple: true, path: results }
|
|
383
|
+
- run: npx playwright test --reporter=@reportforge/playwright-pdf tests/dummy.spec.ts
|
|
384
|
+
env:
|
|
385
|
+
RF_LICENSE_KEY: ${{ secrets.RF_LICENSE_KEY }}
|
|
386
|
+
PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome-stable
|
|
387
|
+
SHARD_RESULTS_GLOB: 'results/shard-*.json'
|
|
388
|
+
- uses: actions/upload-artifact@v4
|
|
389
|
+
with: { name: playwright-pdf-report, path: reports/*.pdf }
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
In `playwright.config.ts` set `shardResults: process.env.SHARD_RESULTS_GLOB`. `tests/dummy.spec.ts` can be a single skipped test — live results are ignored when `shardResults` is set.
|
|
393
|
+
|
|
394
|
+
### GitLab CI
|
|
395
|
+
|
|
396
|
+
```yaml
|
|
397
|
+
playwright-tests:
|
|
398
|
+
image: mcr.microsoft.com/playwright:v1.49.0-jammy
|
|
399
|
+
script:
|
|
400
|
+
- npm ci && npx playwright test
|
|
401
|
+
artifacts:
|
|
402
|
+
paths: [reports/*.pdf]
|
|
403
|
+
when: always
|
|
404
|
+
expire_in: 30 days
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Bitbucket Pipelines
|
|
408
|
+
|
|
409
|
+
```yaml
|
|
410
|
+
image: mcr.microsoft.com/playwright:v1.49.0-jammy
|
|
411
|
+
pipelines:
|
|
412
|
+
default:
|
|
413
|
+
- step:
|
|
414
|
+
name: Playwright Tests + PDF Report
|
|
415
|
+
caches: [node]
|
|
416
|
+
script:
|
|
417
|
+
- npm ci
|
|
418
|
+
- npx playwright test
|
|
419
|
+
artifacts:
|
|
420
|
+
- playwright-report/*.pdf
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Set `RF_LICENSE_KEY` in **Repository Settings → Repository variables**.
|
|
424
|
+
|
|
425
|
+
### Jenkins
|
|
426
|
+
|
|
427
|
+
```groovy
|
|
428
|
+
stage('Playwright Tests') {
|
|
429
|
+
withCredentials([string(credentialsId: 'rf-license', variable: 'RF_LICENSE_KEY')]) {
|
|
430
|
+
sh 'npx playwright test'
|
|
431
|
+
}
|
|
432
|
+
archiveArtifacts artifacts: 'reports/*.pdf', allowEmptyArchive: true
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Azure DevOps
|
|
437
|
+
|
|
438
|
+
```yaml
|
|
439
|
+
- script: npx playwright test
|
|
440
|
+
env: { RF_LICENSE_KEY: $(RF_LICENSE_KEY) }
|
|
441
|
+
- task: PublishPipelineArtifact@1
|
|
442
|
+
inputs:
|
|
443
|
+
targetPath: reports
|
|
444
|
+
artifact: playwright-pdf-report
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Licensing
|
|
450
|
+
|
|
451
|
+
ReportForge ships a **hybrid offline-first** model:
|
|
452
|
+
|
|
453
|
+
1. Paste your `RFSU-…` key into the config once (or set `RF_LICENSE_KEY`).
|
|
454
|
+
2. On first run the reporter activates against the license server, receives a short-lived **Ed25519-signed JWT**, and caches it at `~/.reportforge/license.json`.
|
|
455
|
+
3. Every subsequent run is **fully offline** — the cached JWT is verified locally against a public key bundled into the npm package. No network call.
|
|
456
|
+
4. When the cache has less than 24 hours left, the reporter refreshes it in the background.
|
|
457
|
+
5. Each subscription allows up to **25 active machines** in any rolling 30-day window. Machines that haven't run in 30 days are pruned automatically.
|
|
458
|
+
|
|
459
|
+
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.
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
export RF_LICENSE_KEY=RFSU-XXXX-XXXX-XXXX-XXXX
|
|
463
|
+
npx playwright test
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Full lifecycle + offline failure modes: [reportforge.org/docs#license](https://reportforge.org/docs#license).
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Requirements Traceability
|
|
471
|
+
|
|
472
|
+
The `detailed` template generates a requirements matrix from test tags. Tag tests to link them to requirements:
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
test('@REQ-101 user can login', async ({ page }) => { /* ... */ });
|
|
476
|
+
test.describe('@FEAT-payment', () => { /* ... */ });
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
The matrix rolls tests up per tag with pass count, fail count, and coverage percentage.
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## Troubleshooting
|
|
484
|
+
|
|
485
|
+
Set `RF_DEBUG=1` to log the full activation flow and error stack traces:
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
RF_DEBUG=1 npx playwright test 2>&1 | grep '\[reportforge\]'
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Common issues:
|
|
492
|
+
|
|
493
|
+
- **`Chrome/Chromium not found`** → install Google Chrome Stable; don't use the Ubuntu `chromium-browser` snap.
|
|
494
|
+
- **Charts blank** → ensure `npm run bundle-chartjs` ran at build; the reporter waits up to 30s for `window.__chartsReady`.
|
|
495
|
+
- **`pdfPassword` ignored** → requires `qpdf` on `PATH` (`apt install qpdf` / `brew install qpdf` / `choco install qpdf`).
|
|
496
|
+
- **No PDF generated** → verify `RF_LICENSE_KEY` is set and your subscription is active. `RF_DEBUG=1` will show the activation result; missing key, expired subscription, network failure, or no JWT cache all skip PDF generation.
|
|
497
|
+
|
|
498
|
+
Full guide: [reportforge.org/docs#troubleshooting](https://reportforge.org/docs#troubleshooting).
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Documentation
|
|
503
|
+
|
|
504
|
+
Full documentation at [reportforge.org/docs](https://reportforge.org/docs):
|
|
505
|
+
|
|
506
|
+
- [Quick start](https://reportforge.org/docs#install) — install, configure, activate
|
|
507
|
+
- [Chrome setup](https://reportforge.org/docs#chrome-setup) — Windows, Linux, macOS
|
|
508
|
+
- [CI/CD integration](https://reportforge.org/docs#ci-cd) — GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps
|
|
509
|
+
- [Configuration reference](https://reportforge.org/docs#configuration) — all options
|
|
510
|
+
- [Filename tokens](https://reportforge.org/docs#tokens) — `{date}`, `{branch}`, `{status}`
|
|
511
|
+
- [Templates](https://reportforge.org/docs#templates) — minimal, detailed, executive
|
|
512
|
+
- [License & offline behaviour](https://reportforge.org/docs#license) — JWT cache, machine cap, cancellation
|
|
513
|
+
- [Troubleshooting](https://reportforge.org/docs#troubleshooting) — common issues and debug flags
|
|
514
|
+
- **Changelog** — [CHANGELOG.md](./CHANGELOG.md)
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Contributing
|
|
519
|
+
|
|
520
|
+
Questions and bug reports: email [support@reportforge.org](mailto:support@reportforge.org).
|
|
521
|
+
|
|
522
|
+
## License
|
|
523
|
+
|
|
524
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Add this to your azure-pipelines.yml
|
|
2
|
+
# Requires Node.js tool installed on the agent
|
|
3
|
+
|
|
4
|
+
trigger:
|
|
5
|
+
branches:
|
|
6
|
+
include:
|
|
7
|
+
- main
|
|
8
|
+
- develop
|
|
9
|
+
|
|
10
|
+
pr:
|
|
11
|
+
branches:
|
|
12
|
+
include:
|
|
13
|
+
- main
|
|
14
|
+
|
|
15
|
+
pool:
|
|
16
|
+
vmImage: 'ubuntu-latest'
|
|
17
|
+
|
|
18
|
+
variables:
|
|
19
|
+
- group: reportforge-secrets # Variable group containing RF_LICENSE_KEY
|
|
20
|
+
|
|
21
|
+
stages:
|
|
22
|
+
- stage: Test
|
|
23
|
+
displayName: 'Playwright Tests + PDF Report'
|
|
24
|
+
jobs:
|
|
25
|
+
- job: PlaywrightTest
|
|
26
|
+
displayName: 'Run Tests'
|
|
27
|
+
steps:
|
|
28
|
+
- task: NodeTool@0
|
|
29
|
+
displayName: 'Install Node.js'
|
|
30
|
+
inputs:
|
|
31
|
+
versionSpec: '22.x'
|
|
32
|
+
|
|
33
|
+
- script: npm ci
|
|
34
|
+
displayName: 'Install dependencies'
|
|
35
|
+
|
|
36
|
+
- script: npx playwright install chromium --with-deps
|
|
37
|
+
displayName: 'Install Playwright browsers'
|
|
38
|
+
|
|
39
|
+
- script: npx playwright test
|
|
40
|
+
displayName: 'Run Playwright tests'
|
|
41
|
+
env:
|
|
42
|
+
RF_LICENSE_KEY: $(RF_LICENSE_KEY)
|
|
43
|
+
|
|
44
|
+
- task: PublishPipelineArtifact@1
|
|
45
|
+
displayName: 'Upload PDF Report'
|
|
46
|
+
condition: always()
|
|
47
|
+
inputs:
|
|
48
|
+
targetPath: playwright-report
|
|
49
|
+
artifact: playwright-pdf-report
|
|
50
|
+
publishLocation: pipeline
|
|
51
|
+
|
|
52
|
+
- task: PublishTestResults@2
|
|
53
|
+
displayName: 'Publish Test Results'
|
|
54
|
+
condition: always()
|
|
55
|
+
inputs:
|
|
56
|
+
testResultsFormat: 'JUnit'
|
|
57
|
+
testResultsFiles: 'test-results/results.xml'
|
|
58
|
+
failTaskOnFailedTests: false
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copy this file to bitbucket-pipelines.yml in your project root.
|
|
2
|
+
# Set RF_LICENSE_KEY in Repository Settings > Repository variables.
|
|
3
|
+
# Uses the official Playwright Docker image which includes Chromium.
|
|
4
|
+
|
|
5
|
+
image: mcr.microsoft.com/playwright:v1.49.0-jammy
|
|
6
|
+
|
|
7
|
+
pipelines:
|
|
8
|
+
default:
|
|
9
|
+
- step:
|
|
10
|
+
name: Playwright Tests + PDF Report
|
|
11
|
+
caches:
|
|
12
|
+
- node
|
|
13
|
+
script:
|
|
14
|
+
- npm ci
|
|
15
|
+
- npx playwright test
|
|
16
|
+
artifacts:
|
|
17
|
+
- playwright-report/*.pdf
|
|
18
|
+
after-script:
|
|
19
|
+
- |
|
|
20
|
+
if [ -n "$BITBUCKET_PR_ID" ] && [ -n "$BITBUCKET_WORKSPACE" ] && [ -n "$BB_API_TOKEN" ]; then
|
|
21
|
+
curl -s -X POST \
|
|
22
|
+
-u "${BITBUCKET_REPO_OWNER}:${BB_API_TOKEN}" \
|
|
23
|
+
-H "Content-Type: application/json" \
|
|
24
|
+
-d "{\"content\": {\"raw\": \"PDF report available — download from the [pipeline artifacts](https://bitbucket.org/${BITBUCKET_WORKSPACE}/${BITBUCKET_REPO_SLUG}/pipelines/results/${BITBUCKET_PIPELINE_UUID}).\"}, \"inline\": false}" \
|
|
25
|
+
"https://api.bitbucket.org/2.0/repositories/${BITBUCKET_WORKSPACE}/${BITBUCKET_REPO_SLUG}/pullrequests/${BITBUCKET_PR_ID}/comments" || true
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
branches:
|
|
29
|
+
main:
|
|
30
|
+
- step:
|
|
31
|
+
name: Playwright Tests + PDF Report
|
|
32
|
+
caches:
|
|
33
|
+
- node
|
|
34
|
+
script:
|
|
35
|
+
- npm ci
|
|
36
|
+
- npx playwright test
|
|
37
|
+
artifacts:
|
|
38
|
+
- playwright-report/*.pdf
|
|
39
|
+
|
|
40
|
+
definitions:
|
|
41
|
+
caches:
|
|
42
|
+
node: node_modules
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Copy this file to .github/workflows/playwright.yml in your project
|
|
2
|
+
name: Playwright Tests + PDF Report
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, develop]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: '22'
|
|
19
|
+
cache: 'npm'
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: npm ci
|
|
23
|
+
|
|
24
|
+
- name: Install Playwright browsers
|
|
25
|
+
run: npx playwright install chromium --with-deps
|
|
26
|
+
|
|
27
|
+
- name: Run Playwright tests
|
|
28
|
+
run: npx playwright test
|
|
29
|
+
env:
|
|
30
|
+
RF_LICENSE_KEY: ${{ secrets.RF_LICENSE_KEY }}
|
|
31
|
+
|
|
32
|
+
- name: Upload PDF Report
|
|
33
|
+
if: always()
|
|
34
|
+
uses: actions/upload-artifact@v4
|
|
35
|
+
with:
|
|
36
|
+
name: playwright-pdf-report
|
|
37
|
+
path: playwright-report/*.pdf
|
|
38
|
+
retention-days: 30
|
|
39
|
+
|
|
40
|
+
- name: Comment PR
|
|
41
|
+
if: always() && github.event_name == 'pull_request'
|
|
42
|
+
uses: ./.github/actions/playwright-pdf-report
|
|
43
|
+
with:
|
|
44
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|