Skip to main content

Advanced

Data protection

Two independent, opt-in controls. pdfPassword encrypts the generated PDF; redact masks likely credentials and PII out of report content before it is written or streamed. Both default off: turn on what your environment needs.

Why it matters

Playwright captures whatever your tests touch: error messages, assertion diffs, step titles, console output, annotations. A failing request assertion can carry an API key in its URL. A debug console.log can print an auth header. A form-fill step title can carry a password typed during setup. None of that is a ReportForge bug, it is exactly what your test did, faithfully reported.

A generated PDF often ends up somewhere with broader read access than the pipeline that produced it: attached to an email, posted to Slack or Discord, sitting in a CI artifact bucket. redact and pdfPassword reduce what leaks if that happens.

Redact credentials & PII

Enable redact to mask likely secrets in report text: error messages and stack traces, step titles, captured console output, test and suite titles, annotations, failure-analysis text, and chart labels. The live watch stream is covered too, so redact and live compose safely.

ts
reporter: [['@reportforge/playwright-pdf', {  redact: {    enabled: true,    builtins: true,                // built-in credential/PII patterns (default: true)    patterns: ['MYCO_[A-Z0-9]+'],  // your own regexes, always fully masked    mask: '[REDACTED]',            // replacement text (default)  },}]]

Redaction runs after failure analysis, so the classifier still scores the original text and category accuracy is unaffected; only the rendered and streamed output is masked.

Built-in patterns

With builtins: true (the default once redact.enabled is on), these patterns are masked automatically:

CatchesKept as-isExample
key=value / "key": "value" credentials (password, secret, token, apiKey, auth, credential, privateKey, accessKey, clientSecret, …)the key namepassword: "hunter2" → password: "[REDACTED]"
Authorization: Bearer … / Basic …the scheme wordBearer eyJhbGc... → Bearer [REDACTED]
JWTs, anywhere in textn/aeyJhbGciOi...
Provider key prefixesn/aAWS AKIA…, GitHub ghp_/gho_/github_pat_, Slack xox*, OpenAI-style sk-, Razorpay rzp_live_/rzp_test_, Google AIza…
URLs with embedded credentialsthe usernamehttps://alice:hunter2@host → https://alice:[REDACTED]@host
Emailsfirst character + domainjsmith@example.com → j***@example.com
High-entropy strings (20+ mixed letters/digits)n/atokens and keys with no recognizable prefix

The email pattern always partially masks to x***@domain, independent of mask. Every other match, built-in or custom, is replaced with mask.

Custom patterns

Add your own patterns for anything the built-ins do not cover: internal ticket IDs, project-specific token formats, customer identifiers.

ts
redact: {  enabled: true,  patterns: [    'MYCO_[A-Z0-9]{8,}',   // internal token format    'CUST-\\d{6}',         // customer ID  ],}

Patterns are regex source strings, compiled with the g flag (case-sensitive). Unlike the partial built-ins, every custom match is replaced with the full mask text, with no surrounding context kept. A pattern that throws at match time is disabled for the rest of the run and logged once; the rest keep working.

Password-protect the PDF

Set pdfPassword to encrypt the generated PDF with AES-256, applied in-process: no qpdf or other system tool to install.

ts
reporter: [['@reportforge/playwright-pdf', {  pdfPassword: process.env.RF_PDF_PASSWORD,}]]

Source the password from an environment variable rather than committing it.

When a run has more failures than maxInlineFailures, the overflow is written to a sidecar JSON file next to the PDF. If pdfPassword is set, the sidecar is encrypted too, saved as {basename}-failures.json.enc instead of plain JSON. Decrypt it with the bundled CLI:

bash
npx @reportforge/playwright-pdf decrypt-failures reports/2026-04-28-report-failures.json.enc --password=$RF_PDF_PASSWORD# or set RF_PDF_PASSWORD in the environment and drop --password# --out=<path> chooses where the decrypted JSON is written (default: input path minus .enc)

Limitations

Screenshots are not redacted. redact operates on text; a screenshot is pixels, and a credential visible on screen (a filled-in password field, an API key pasted into a text box) stays visible in the image. Set includeScreenshots: false if your environment cannot tolerate that.

Redaction is best-effort. The built-in patterns and your own regexes catch known shapes; they cannot catch every secret format, and an unusual value can slip through. Treat redact as a second layer, not a substitute for controlling who can open the report in the first place.