Reference
Configuration
All options are passed to the reporter in playwright.config.ts. Every option is optional; the defaults work without a license key (PDF is skipped).
Options reference
| Option | Type | Default | Description |
|---|---|---|---|
| outputFile | string | 'playwright-report/{date}-report.pdf' | Output path. Supports tokens: {date}, {datetime}, {branch}, {status}, {total}, {passed}, {failed}, {project}. Directory is created if absent. |
| template | 'minimal' | 'detailed' | 'executive' or array | 'minimal' | Template(s) to generate. Pass an array to produce one PDF per template in one run: the template name is appended to each output filename automatically (e.g. report-detailed.pdf). |
| licenseKey | string | env RF_LICENSE_KEY | Subscription key for the test runner in use (format RFPW-…, RFPY-…, RFNT-… or RFCY-…). Falls back to the RF_LICENSE_KEY environment variable. PDF generation is skipped when absent or invalid. |
| logo | string | n/a | Path to a logo image (PNG, JPG, or SVG) to embed in the report header. Supports absolute and relative paths. |
| primaryColor | string | '#CC785C' | Primary brand colour (3-, 6-, or 8-digit hex). Used for headers and accent bars. |
| accentColor | string | '#3F7D58' | Accent brand colour (hex). Used for highlights and badges. |
| watermark | string | n/a | Text to render as a diagonal watermark overlay from the Suite Breakdown page onward (summary/chart pages stay clean), e.g. 'CONFIDENTIAL' or 'DRAFT'. |
| pdfPassword | string | n/a | Password-protect the generated PDF with AES-256, applied in-process with no external tools required. Also encrypts the failure-overflow sidecar (*-failures.json.enc; decrypt with npx @reportforge/playwright-pdf decrypt-failures). Recommended: process.env.RF_PDF_PASSWORD. |
| reportTitle | string | 'Playwright Test Report' | Custom title for the report cover page and running header. |
| projectName | string | from package.json | Project or application name. Inferred from the package.json name field if absent. |
| open | boolean | false | Open the generated PDF automatically after generation. For local use only; ignored in CI. |
| logLevel | 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'info' | Console verbosity for [reportforge] log lines. 'silent' suppresses everything including errors; 'debug' adds diagnostics. The RF_DEBUG=1 env var always forces debug, overriding this option. |
| puppeteerExecutablePath | string | auto-detect | Full path to a Chrome or Chromium binary. Falls back to PUPPETEER_EXECUTABLE_PATH env, then system Chrome discovery. |
| serverUrl | string | 'https://reportforge.org' | Base URL for the ReportForge licensing server. Override only for self-hosting or local development. |
| compressionLevel | 'auto' | 'none' | 'balanced' | 'max' | 'auto' | Screenshot JPEG quality preset. 'auto' picks based on failure volume; 'none' keeps original PNGs; 'balanced' uses JPEG q85; 'max' uses JPEG q70. |
| includeScreenshots | boolean | true | Embed Playwright screenshots in the PDF. Set to false to omit images; useful for exec-audience reports or reducing file size. |
| maxInlineFailures | number | derived from compressionLevel | Cap on failure entries rendered inline in the PDF. Overflow is written to a sibling {basename}-failures.json sidecar file. |
| maxFileSizeMb | number | 8 | Soft cap on the final PDF size in MB. If exceeded, the report is re-rendered once with the 'max' compression preset. |
| shardResults | string | string[] | n/a | Glob or path array of Playwright JSON shard report files to merge into one PDF. See the Shard Merging docs. |
| 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. |
| failureAnalysis | object | { enabled: true } | Offline failure root-cause analysis (embedded classifier; no runtime network) with on-device personalization: label collected failures, then the train-model CLI trains + evaluates a local layer entirely on your machine; it activates only when it beats the base model, and nothing leaves the machine. Fields: enabled (default true), maxClusters (default 10), minStrength (weak|moderate|strong, default weak), maxFailuresToAnalyse (default 500), collectUnclassified (default true), collectScope (blind-spots|all, default blind-spots), autoUpdateModel (default true), localModel (use the gate-passed on-device model, default true), localModelPath (share a team-trained model via a repo-committed file). See the Failure Analysis docs. |
| 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. |
| redact | object | { enabled: false } | Opt-in masking of likely credentials/PII (passwords, tokens, API keys, Bearer/JWT values, emails, high-entropy strings) in report text and the live stream. builtins (default true) toggles the built-in patterns; patterns adds custom regexes (fully masked); mask sets the replacement text (default '[REDACTED]'). Screenshots cannot be redacted; use includeScreenshots: false for strict environments. |
| 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. |
| 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. |
| historySize | number | 10 | Maximum number of test runs to keep in the history file (integer ≥ 2). Older runs are pruned on append. |
| showTrend | boolean | true | Show the pass-rate sparkline and delta badge in the detailed template. Set to false to disable history tracking entirely. |
| remoteHistory | boolean | false | Opt-in server-side trend store so the pass-rate trend survives ephemeral CI runners (the local history file is wiped with the workspace, leaving the chart stuck at one data point). One small authenticated request per run carrying aggregate numbers only — no test titles, no error text, and the branch name never travels in plaintext. Falls back to the local history file on any failure. See the History docs. |
| flakinessTopN | number | 5 | Maximum flaky tests to show in the flakiness table (detailed template). Set to 0 to disable the table entirely. |
| quarantineThreshold | number | 40 | Flake-rate percentage (0-100) at which a test gets a QUARANTINE chip in the flakiness table, plus a callout with the candidate count. Applies once a test has 3+ history runs with flakiness data. Set to 0 to disable flagging. |
| evidenceUrlTemplate | string | n/a | URL template that turns local trace/video artifact paths (from capture.evidence) into clickable CI links with a QR code in the defect log. Must contain {path}, replaced with the forward-slashed artifact path, e.g. https://ci.example.com/job/123/artifacts/{path}. Unset = plain paths as before. |
| slowTestThreshold | number | 10 | Minimum timed-test count before SLOW badges appear in the suite breakdown: below this, every test is trivially the "slowest" so badges stay hidden. On larger runs only genuine outliers (at least 2× the median test duration) are badged, so the badge stays rare. Set to 0 to drop the run-size gate (outliers still required). |
| requirementTagPattern | string | '^@?[A-Z][A-Z0-9]*-\\d+$' | Regex deciding which tags count as requirement IDs in the Requirements Traceability section (detailed template). Matching tags (ticket shapes like @ODP-5328, REQ-001) get the traceability matrix; everything else (@regression, @sanity) collapses into a compact tag summary instead of repeating identical rows. Set to '' to disable the split and list every tag in the matrix. |
| templatePath | string | string[] | n/a | Path to a custom Handlebars (.hbs) template file. Takes precedence over template. Pass an array to generate one PDF per custom template. See the Custom Templates docs. |
| sections | object | per-template | Override which report sections appear, on top of the chosen template's defaults. Flat keys are the baseline for every chosen template; per-template keys (minimal|detailed|executive) override per template. 21 keys total. Block toggles: coverPage, analysisOneliner, releaseGate, summary, charts, trend, requirementsMatrix, ciEnvironment, suiteBreakdown, failureDeepDive, failureAnalysis, slowTests, defectLog, briefBand, runDiff, browserMatrix. Display modifiers: passRate, fullEnvironment, retries, fullFailures, stackTraces. runDiff (block toggle, on by default in all three templates) shows new failures, fixed tests, and still-failing tests compared with the previous run on the same branch. browserMatrix (block toggle, on by default in detailed) compares per-test outcomes across the run's projects and appears only when the run has 2+ projects. See the Report Sections docs. |
Execution capture
Opt-in rich detail for the defectLog section of the detailed template. The reporter reads what Playwright already records on each failed test (the step tree, Node stdout/stderr, and trace/video attachments), so there are no fixtures and no test-code changes. Everything is off by default; reports are unchanged until you opt in.
Under each defect, capture adds:
- steps: a copy-pasteable Steps to Reproduce outline: your test.step intent and expect assertions, each indented under its parent test.step and the failing step marked. Each row is a Markdown list line, so the outline pastes straight into a bug tracker as a nested list. Set apiSteps to also include every top-level pw:api action (click/fill/check/goto) for a full action trail; off by default to keep the outline intent-level. Capped by maxSteps (default 50).
- console: the tail of the test's Node stdout/stderr, capped by maxConsoleLines (default 50).
- evidence: file links to the Playwright trace.zip and video (set trace/video in your Playwright use config to produce them). Add evidenceUrlTemplate (a URL containing {path}) and each link becomes a clickable CI artifact URL with a QR code beside it, so a printed report jumps straight to the trace viewer from a phone camera.
Capture is reporter-side, so it behaves identically on single-machine runs and merged shardResults runs.
['@reportforge/playwright-pdf', { template: 'detailed', capture: { steps: true, // "Steps to Reproduce" outline: test.step intent + expect, failing step marked apiSteps: false, // also include every top-level pw:api action for a full trail (default false) console: true, // Node stdout/stderr tail evidence: true, // trace.zip + video file links // maxSteps: 50, maxConsoleLines: 50 // caps (optional) },}]// Produce trace/video so the evidence links resolve:// use: { trace: 'on', video: 'on', screenshot: 'only-on-failure' }Filename tokens
Token expansion runs at write time. All tokens are safe to use in CI; unknown tokens are left as-is.
| Token | Expands to |
|---|---|
| {date} | YYYY-MM-DD in local time (e.g. 2026-04-27) |
| {datetime} | YYYY-MM-DD-HHmmss |
| {branch} | Current git branch (or unknown if not in a repo) |
| {status} | passed or failed |
| {total} | Total test count |
| {passed} | Passed test count |
| {failed} | Failed test count |
| {project} | Value of projectName option (slugified) |
Report Sections
Each built-in template ships a curated set of sections. The sections option adds a section a template hides or removes one it shows, per template, without a custom template. Resolution order, lowest to highest: the template defaults, then flat keys (baseline for every chosen template), then per-template keys (minimal / detailed / executive). An unknown key throws a configuration error.
Block toggles: which sections appear
| Key | Renders |
|---|---|
| coverPage | Full-page cover: title, verdict badge, KPI stats strip, branch + commit |
| analysisOneliner | One-line failure-analysis summary banner |
| releaseGate | Ship/hold recommendation banner (APPROVED TO SHIP / HOLD, or a neutral NO TESTS RAN when the run executed zero tests) |
| summary | KPI strip (total, passed, failed, timed-out, skipped, flaky), verdict, duration, pass rate, flaky callout |
| charts | Pass-rate doughnut and stacked suite-results bar |
| trend | Pass-rate trend line, run-history table, and flakiness table (rendered inside charts) |
| requirementsMatrix | Requirement-ID tags as a traceability matrix with pass-rate bars, plus a category tag summary |
| ciEnvironment | Branch, commit, browsers, CI provider, OS, Node, Playwright, projects, workers |
| suiteBreakdown | Per-suite to per-test table (status, duration, tags, retries) |
| failureDeepDive | Failure cards: error message, stack trace, screenshot, retry history |
| failureAnalysis | Clustered root-cause buckets from the offline classifier |
| slowTests | Slowest tests, duration-ranked |
| defectLog | DEF-#### numbered failure table (severity, duration), plus opt-in repro detail (see Execution capture) |
| briefBand | Plain-language lede: trend delta + root-cause tally as one sentence (executive default; supersedes analysisOneliner there) |
| runDiff | Since Last Run: new failures, fixed tests, and still-failing tests vs. the previous run on the same branch |
| browserMatrix | Cross-browser comparison: per-test outcomes side by side across the run's projects, divergent tests first. Appears only when the run has 2+ projects |
Display modifiers: tune a section that is on
| Key | Effect |
|---|---|
| passRate | Pass-rate % on the Passed KPI card (summary) |
| fullEnvironment | Full environment table instead of the compact grid (ciEnvironment) |
| retries | Retries column in the suite breakdown (suiteBreakdown) |
| fullFailures | Full failure cards instead of one-line summaries (failureDeepDive) |
| stackTraces | Include stack traces in the failure cards (failureDeepDive) |
Per-template defaults
Omit sections and each template renders exactly this.
| Section | minimal | detailed | executive |
|---|---|---|---|
| coverPage | – | – | ✓ |
| analysisOneliner | – | – | – |
| releaseGate | ✓ | ✓ | ✓ |
| summary | ✓ | ✓ | ✓ |
| charts | – | ✓ | ✓ |
| trend | – | ✓ | ✓ |
| requirementsMatrix | – | ✓ | – |
| ciEnvironment | ✓ | ✓ | ✓ |
| suiteBreakdown | ✓ | ✓ | ✓ |
| failureDeepDive | ✓ | ✓ | ✓ |
| failureAnalysis | – | ✓ | – |
| slowTests | – | ✓ | ✓ |
| defectLog | – | ✓ | – |
| briefBand | – | – | ✓ |
| runDiff | ✓ | ✓ | ✓ |
| browserMatrix | – | ✓ | – |
| passRate | ✓ | ✓ | ✓ |
| fullEnvironment | – | ✓ | – |
| retries | ✓ | ✓ | – |
| fullFailures | ✓ | ✓ | – |
| stackTraces | ✓ | ✓ | – |
Dependencies
- trend needs charts on (the trend, run-history, and flakiness blocks live inside charts) plus history data; keep showTrend on. Enabling trend with charts off is coerced off.
- Data-gated sections (failureAnalysis, requirementsMatrix, slowTests, defectLog) render only when matching data exists. browserMatrix needs 2+ projects in the run (multi-project Playwright configs, or pytest with --browser given twice), so single-browser runs never show it.
- Render-layer only: sections never changes data collection. The data switches stay separate: showTrend, flakinessTopN, failureAnalysis.enabled, includeScreenshots.
- Custom templates (templatePath) control their own layout and ignore sections (you get a warning if both are set).
sections: { defectLog: false, // baseline for every chosen template minimal: { charts: true }, // add charts to minimal detailed: { ciEnvironment: false },}Full example
// playwright.config.tsimport { defineConfig } from '@playwright/test';import { defineReporterConfig } from '@reportforge/playwright-pdf';export default defineConfig({ reporter: [ ['list'], ['@reportforge/playwright-pdf', defineReporterConfig({ licenseKey: process.env.RF_LICENSE_KEY, template: 'detailed', outputFile: 'reports/{date}-{branch}-{status}.pdf', projectName: 'Acme E2E Suite', logo: './assets/logo.png', puppeteerExecutablePath: process.env.PUPPETEER_EXECUTABLE_PATH, maxFileSizeMb: 12, includeScreenshots: true, historyFile: '.rf-history/history.json', notify: { slack: { url: process.env.SLACK_WEBHOOK_URL, enabled: true, on: 'failure' }, }, })], ], use: { screenshot: 'only-on-failure' },});