@reportforge/playwright-pdf 0.24.0 → 0.26.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.
Files changed (31) hide show
  1. package/README.md +9 -6
  2. package/ci-templates/azure-devops/azure-pipelines.yml +58 -58
  3. package/ci-templates/github-actions/basic-workflow.yml +44 -44
  4. package/ci-templates/gitlab-ci/.gitlab-ci.yml +42 -42
  5. package/ci-templates/jenkins/Jenkinsfile +54 -54
  6. package/dist/cli/index.js +24 -1
  7. package/dist/index.d.mts +9 -3
  8. package/dist/index.d.ts +9 -3
  9. package/dist/index.js +407 -44
  10. package/dist/index.mjs +407 -44
  11. package/dist/templates/layouts/detailed.hbs +43 -41
  12. package/dist/templates/layouts/executive.hbs +43 -41
  13. package/dist/templates/layouts/minimal.hbs +43 -41
  14. package/dist/templates/partials/analysis-oneliner.hbs +3 -3
  15. package/dist/templates/partials/chart-summary-grid.hbs +40 -40
  16. package/dist/templates/partials/chart-trend-card.hbs +16 -16
  17. package/dist/templates/partials/charts.hbs +433 -433
  18. package/dist/templates/partials/ci-environment.hbs +56 -56
  19. package/dist/templates/partials/cover-page.hbs +48 -48
  20. package/dist/templates/partials/defect-log.hbs +79 -79
  21. package/dist/templates/partials/executive-hero-summary.hbs +66 -66
  22. package/dist/templates/partials/executive-summary.hbs +78 -78
  23. package/dist/templates/partials/failure-card.hbs +35 -35
  24. package/dist/templates/partials/head.hbs +17 -17
  25. package/dist/templates/partials/release-gate.hbs +84 -84
  26. package/dist/templates/partials/requirements-matrix.hbs +51 -51
  27. package/dist/templates/partials/run-diff.hbs +41 -0
  28. package/dist/templates/partials/suite-breakdown.hbs +89 -89
  29. package/dist/templates/partials/watermark.hbs +42 -42
  30. package/dist/templates/styles/base.css +19 -1
  31. package/package.json +1 -2
package/README.md CHANGED
@@ -58,6 +58,7 @@ Three templates, one reporter. Every PDF is fully offline: fonts, charts, and sc
58
58
  - **Notifications**: post pass/fail summaries to Slack, Teams, Discord, or email after each run; configurable trigger (`always` / `failure` / `success`) per channel; email and Discord support optional PDF attachment via `attachPdf`
59
59
  - **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)
60
60
  - **Pass-rate trend**: cross-run trend chart from stored history; opt-in `remoteHistory` keeps the trend alive on ephemeral CI runners by storing aggregate numbers only (pass rate, counts, duration, verdict; no test titles or error text, and the branch name never travels in plaintext), with no extra network calls
61
+ - **Run-over-run diff**: every report shows what changed since the previous run on the same branch: new failures, fixed tests, and still-failing tests, and the same summary rides along in Slack, Teams, Discord, and email notifications
61
62
  - **Offline failure analysis**: sorts each failure into one of 7 root-cause buckets and renders a root-cause chip under each failed test in the `detailed` PDF (dominant-cause one-liner in `executive`). No network, no AI service: a small embedded classifier with automatic updates; pin it any time. Full details at [reportforge.org/docs/advanced/failure-analysis](https://reportforge.org/docs/advanced/failure-analysis).
62
63
  - **On-device training**: teach the classifier your team's failures without any data leaving your machine. Label locally-collected samples (`npx @reportforge/playwright-pdf label-feedback`), then `train-model` trains and cross-validates a personal layer on-device; it activates only when it measurably beats the base model on your own labeled set (`evaluate-model` shows the comparison any time). Commit the model file to your repo via `failureAnalysis.localModelPath` to share it with CI. Training data, the trained model, and evaluation are all local files; the analysis code cannot even name a network primitive (enforced by an automated source audit).
63
64
  - `npx @reportforge/playwright-pdf export-feedback`: merges your locally-collected feedback (tokenized + redacted) into one CSV for review or moving between machines. Local file only; there is no upload.
@@ -213,14 +214,14 @@ All options are the second element of the reporter tuple.
213
214
  | `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). |
214
215
  | `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. |
215
216
  | `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. |
216
- | `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. Block toggles: `coverPage`, `analysisOneliner`, `releaseGate`, `summary`, `charts`, `trend`, `requirementsMatrix`, `ciEnvironment`, `suiteBreakdown`, `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`. Display modifiers: `passRate`, `fullEnvironment`, `retries`, `fullFailures`, `stackTraces`. See the Report Sections docs. |
217
+ | `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. 20 keys total. Block toggles: `coverPage`, `analysisOneliner`, `releaseGate`, `summary`, `charts`, `trend`, `requirementsMatrix`, `ciEnvironment`, `suiteBreakdown`, `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`, `runDiff`. 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. See the Report Sections docs. |
217
218
  <!-- AUTOGEN:options-table END -->
218
219
 
219
220
  Full reference: [reportforge.org/docs/configuration](https://reportforge.org/docs/configuration).
220
221
 
221
222
  ### Live Runs
222
223
 
223
- Watch a run as it happens. With `live` enabled, the reporter prints an unguessable watch link (boxed under a `Live Tracker` heading) to your CI logs at run start and streams per-test progress to a hosted dashboard while tests execute. All shards of one CI run converge on a single live view. Each test shows its steps and assertions as sub-lines beneath its row: each step once, as it settles, indented under its parent `test.step` in source order (Playwright's hooks, fixtures, and teardown are filtered out). The PDF is still generated at the end, unchanged.
224
+ Watch a run as it happens. With `live` enabled, the reporter prints an unguessable watch link (boxed under a `Live Tracker` heading) to your CI logs at run start and streams per-test progress to a hosted dashboard while tests execute. All shards of one CI run converge on a single live view. Tests are grouped by spec file and describe block into collapsible suites, failures first. While a test runs you see its steps settle live under the row; once it finishes, the row expands into the full step tree: your `test.step` names with the Playwright calls and assertions nested beneath them, and on failure the complete error message, code frame, and stack attached to the exact step that failed (Playwright's hooks, fixtures, and teardown are filtered out unless the failure happened inside one). The PDF is still generated at the end, unchanged.
224
225
 
225
226
  > The watch link is entitlement-gated. If you enable `live` but see no `Live Tracker` line, the reporter logs why (missing `RF_LICENSE_KEY`, or a cached token without the `live` entitlement; delete `~/.reportforge/license.json` to force re-activation).
226
227
 
@@ -239,13 +240,13 @@ reporter: [
239
240
  ],
240
241
  ```
241
242
 
242
- `steps: 'intent'` shows only your `test.step` names (plus any failing step): the cleanest, most readable trail. `'all'` adds every action and assertion beneath its parent step; `'failed'` (default) keeps intent + assertions + failures.
243
+ `steps: 'intent'` shows only your `test.step` names (plus any failing step): the cleanest, most readable trail. `'all'` adds every action and assertion beneath its parent step; `'failed'` (default) keeps intent + assertions + failures. The mode shapes only the live trail while a test is still running; the full step tree a finished test expands into is always sent.
243
244
 
244
245
  Sharded runs need no extra config: every shard of one CI run converges on the same live view automatically. Set `RF_LIVE_RUN_ID` to override when your CI is not auto-detected.
245
246
 
246
247
  Live streaming is best-effort and entitlement-gated: if the server is unreachable the run is unaffected, and an active subscription with the `live` feature is required. If you've configured Slack/Teams/Discord notifications, the watch link is also posted to those channels when the run starts.
247
248
 
248
- > **Security:** the watch link exposes test titles + statuses (and step titles when `steps` is on) to anyone holding it — no login needed, which is the point: share it with whoever should watch. The token is scoped to that one run, and rotating your license key never breaks an already-shared link. Leaving `console: false` is recommended: enabling it streams your tests' stdout/stderr to anyone holding the link. Full details at [reportforge.org/docs/advanced/live](https://reportforge.org/docs/advanced/live).
249
+ > **Security:** the watch link exposes test titles, statuses, step titles, and failure details (error messages, code frames, stacks) to anyone holding it — no login needed, which is the point: share it with whoever should watch. Your `redact` rules apply to everything on the link, error text included. The token is scoped to that one run, and rotating your license key never breaks an already-shared link. Leaving `console: false` is recommended: enabling it streams your tests' stdout/stderr to anyone holding the link. Full details at [reportforge.org/docs/advanced/live](https://reportforge.org/docs/advanced/live).
249
250
 
250
251
  ### Shard Merging
251
252
 
@@ -316,7 +317,7 @@ The `on` trigger controls when the message fires:
316
317
 
317
318
  **PDF attachment** (`attachPdf: true`) is available on `email` and `discord`: Slack and Teams webhooks cannot carry file uploads. On Discord the PDF is uploaded with the message; if the upload fails or the PDF exceeds Discord's file-size cap, the summary still posts without the attachment. With multiple templates, the first PDF is attached.
318
319
 
319
- 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).
320
+ The summary includes pass rate, test counts, duration, and the report filename. When a previous run on the same branch exists, the message also carries a run-over-run diff line: new failures, fixed tests, and tests still failing. Notifications require a valid license and fire after PDF generation (or after a PDF failure; you still get the ping).
320
321
 
321
322
  ### Data Protection
322
323
 
@@ -364,6 +365,8 @@ Full details at [reportforge.org/docs/advanced/security](https://reportforge.org
364
365
 
365
366
  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.
366
367
 
368
+ **Since Last Run**: every report also gets a section (`runDiff`, on by default in all three templates) comparing the current run against the previous run on the same branch: new failures, fixed tests, and tests still failing, with the same summary line carried into Slack, Teams, Discord, and email notifications. The first run after upgrading has no comparable prior run to diff against, so the section starts appearing from the second run onward. It reads only the local history file, so test names never leave your machine; see the ephemeral-CI note below for keeping that file around between runs. Like the flakiness table, it rides history tracking (`showTrend`, on by default), and the notification line follows history availability rather than the `runDiff` section toggle.
369
+
367
370
  **Local dev (zero config)**: history is written automatically to `~/.reportforge/{projectKey}/history.json`. The sparkline appears once two or more runs have been recorded.
368
371
 
369
372
  **CI with ephemeral runners (recommended)**: enable the server-side trend store; the local file is wiped with the workspace, leaving the chart stuck at one data point:
@@ -375,7 +378,7 @@ reporter: [['@reportforge/playwright-pdf', {
375
378
  }]]
376
379
  ```
377
380
 
378
- One small authenticated request per run, carrying aggregate numbers only (pass rate, counts, duration, verdict; no test titles, no error text, and the branch name never travels in plaintext). The server keeps roughly the last 100 runs per project + branch, expiring after 180 days, and returns them for the chart; any failure falls back to the local file. The flakiness table stays local-only by design (it needs test titles, which never leave your machine). Bitbucket Pipelines users especially: Bitbucket caches are immutable once written, so `remoteHistory` is the practical path there.
381
+ One small authenticated request per run, carrying aggregate numbers only (pass rate, counts, duration, verdict; no test titles, no error text, and the branch name never travels in plaintext). The server keeps roughly the last 100 runs per project + branch, expiring after 180 days, and returns them for the chart; any failure falls back to the local file. This feeds the trend chart only: the flakiness table and the Since Last Run diff both stay local-only by design (they need test titles, which never leave your machine); to keep either alive on ephemeral runners, use the CI caching alternative below to persist `historyFile` instead. Bitbucket Pipelines users especially: Bitbucket caches are immutable once written, so `remoteHistory` is the practical path for the trend chart there.
379
382
 
380
383
  **CI caching alternative** (keeps even aggregate numbers off the server): set `historyFile` to a project-relative path and cache it between runs:
381
384
 
@@ -1,58 +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
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
@@ -1,44 +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 }}
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 }}
@@ -1,42 +1,42 @@
1
- # Add this job to your .gitlab-ci.yml
2
- # Uses the official Playwright Docker image which includes Chromium
3
-
4
- variables:
5
- RF_LICENSE_KEY: $REPORTFORGE_LICENSE # Set in GitLab CI/CD Settings > Variables
6
-
7
- playwright-tests:
8
- image: mcr.microsoft.com/playwright:v1.49.0-jammy
9
- stage: test
10
- script:
11
- - npm ci
12
- - npx playwright test
13
- artifacts:
14
- name: "playwright-pdf-${CI_COMMIT_SHORT_SHA}"
15
- paths:
16
- - playwright-report/*.pdf
17
- expire_in: 30 days
18
- when: always
19
- expose_as: 'Playwright PDF Report'
20
- variables:
21
- PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium-browser
22
- rules:
23
- - if: $CI_MERGE_REQUEST_ID
24
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
25
-
26
- # Optional: Post merge request note with report link
27
- notify-mr:
28
- stage: .post
29
- image: alpine:latest
30
- script:
31
- - |
32
- if [ -n "$CI_MERGE_REQUEST_IID" ]; then
33
- curl -s --request POST \
34
- --header "PRIVATE-TOKEN: $CI_API_TOKEN" \
35
- --header "Content-Type: application/json" \
36
- --data "{\"body\": \"📄 Playwright PDF report available: [Download](${CI_JOB_URL}/artifacts/download)\"}" \
37
- "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"
38
- fi
39
- rules:
40
- - if: $CI_MERGE_REQUEST_ID
41
- when: always
42
- needs: [playwright-tests]
1
+ # Add this job to your .gitlab-ci.yml
2
+ # Uses the official Playwright Docker image which includes Chromium
3
+
4
+ variables:
5
+ RF_LICENSE_KEY: $REPORTFORGE_LICENSE # Set in GitLab CI/CD Settings > Variables
6
+
7
+ playwright-tests:
8
+ image: mcr.microsoft.com/playwright:v1.49.0-jammy
9
+ stage: test
10
+ script:
11
+ - npm ci
12
+ - npx playwright test
13
+ artifacts:
14
+ name: "playwright-pdf-${CI_COMMIT_SHORT_SHA}"
15
+ paths:
16
+ - playwright-report/*.pdf
17
+ expire_in: 30 days
18
+ when: always
19
+ expose_as: 'Playwright PDF Report'
20
+ variables:
21
+ PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium-browser
22
+ rules:
23
+ - if: $CI_MERGE_REQUEST_ID
24
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
25
+
26
+ # Optional: Post merge request note with report link
27
+ notify-mr:
28
+ stage: .post
29
+ image: alpine:latest
30
+ script:
31
+ - |
32
+ if [ -n "$CI_MERGE_REQUEST_IID" ]; then
33
+ curl -s --request POST \
34
+ --header "PRIVATE-TOKEN: $CI_API_TOKEN" \
35
+ --header "Content-Type: application/json" \
36
+ --data "{\"body\": \"📄 Playwright PDF report available: [Download](${CI_JOB_URL}/artifacts/download)\"}" \
37
+ "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"
38
+ fi
39
+ rules:
40
+ - if: $CI_MERGE_REQUEST_ID
41
+ when: always
42
+ needs: [playwright-tests]
@@ -1,54 +1,54 @@
1
- // Add this stage to your existing Jenkinsfile
2
- // Requires: Node.js tool configured, Chrome/Chromium installed on agent
3
-
4
- pipeline {
5
- agent { label 'linux' }
6
-
7
- environment {
8
- RF_LICENSE_KEY = credentials('reportforge-license-key')
9
- }
10
-
11
- stages {
12
- stage('Install') {
13
- steps {
14
- sh 'npm ci'
15
- sh 'npx playwright install chromium'
16
- }
17
- }
18
-
19
- stage('Playwright Tests + PDF Report') {
20
- steps {
21
- sh 'npx playwright test'
22
- }
23
- post {
24
- always {
25
- // Archive the PDF report as a build artifact
26
- archiveArtifacts(
27
- artifacts: 'playwright-report/*.pdf',
28
- allowEmptyArchive: true,
29
- fingerprint: true
30
- )
31
- // Publish HTML alongside (optional)
32
- publishHTML(target: [
33
- allowMissing: true,
34
- alwaysLinkToLastBuild: true,
35
- keepAll: true,
36
- reportDir: 'playwright-report',
37
- reportFiles: '*.pdf',
38
- reportName: 'Playwright PDF Report'
39
- ])
40
- }
41
- }
42
- }
43
- }
44
-
45
- post {
46
- failure {
47
- emailext(
48
- subject: "FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
49
- body: "Build failed. PDF report: ${env.BUILD_URL}artifact/playwright-report/",
50
- recipientProviders: [[$class: 'DevelopersRecipientProvider']]
51
- )
52
- }
53
- }
54
- }
1
+ // Add this stage to your existing Jenkinsfile
2
+ // Requires: Node.js tool configured, Chrome/Chromium installed on agent
3
+
4
+ pipeline {
5
+ agent { label 'linux' }
6
+
7
+ environment {
8
+ RF_LICENSE_KEY = credentials('reportforge-license-key')
9
+ }
10
+
11
+ stages {
12
+ stage('Install') {
13
+ steps {
14
+ sh 'npm ci'
15
+ sh 'npx playwright install chromium'
16
+ }
17
+ }
18
+
19
+ stage('Playwright Tests + PDF Report') {
20
+ steps {
21
+ sh 'npx playwright test'
22
+ }
23
+ post {
24
+ always {
25
+ // Archive the PDF report as a build artifact
26
+ archiveArtifacts(
27
+ artifacts: 'playwright-report/*.pdf',
28
+ allowEmptyArchive: true,
29
+ fingerprint: true
30
+ )
31
+ // Publish HTML alongside (optional)
32
+ publishHTML(target: [
33
+ allowMissing: true,
34
+ alwaysLinkToLastBuild: true,
35
+ keepAll: true,
36
+ reportDir: 'playwright-report',
37
+ reportFiles: '*.pdf',
38
+ reportName: 'Playwright PDF Report'
39
+ ])
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ post {
46
+ failure {
47
+ emailext(
48
+ subject: "FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
49
+ body: "Build failed. PDF report: ${env.BUILD_URL}artifact/playwright-report/",
50
+ recipientProviders: [[$class: 'DevelopersRecipientProvider']]
51
+ )
52
+ }
53
+ }
54
+ }
package/dist/cli/index.js CHANGED
@@ -311,6 +311,24 @@ function buildDemoCharts(passed, failed, skipped, flaky, total) {
311
311
  ]
312
312
  };
313
313
  }
314
+ function buildDemoRunDiff() {
315
+ return {
316
+ newFailures: [
317
+ { id: "auth-5", title: "should block brute-force attempts after 5 tries" },
318
+ { id: "cat-7", title: "should lazy-load images on scroll" }
319
+ ],
320
+ stillFailing: [
321
+ { id: "co-3", title: "should reject expired promo code" }
322
+ ],
323
+ fixed: [
324
+ { id: "co-5", title: "should complete Stripe checkout" }
325
+ ],
326
+ noLongerRun: [],
327
+ baselineRunId: "demo-1d",
328
+ baselineTimestamp: DEMO_BASE_TS - 864e5,
329
+ baselineTruncated: false
330
+ };
331
+ }
314
332
  function buildDemoReportData(template = "detailed") {
315
333
  const projects = [
316
334
  makeProject("chromium", [
@@ -362,7 +380,8 @@ function buildDemoReportData(template = "detailed") {
362
380
  projectCount: 2,
363
381
  workerCount: 4
364
382
  },
365
- charts
383
+ charts,
384
+ runDiff: buildDemoRunDiff()
366
385
  };
367
386
  }
368
387
  var DEMO_BASE_TS, DEMO_LICENSE_INFO, DEMO_AUTH_TESTS, DEMO_CHECKOUT_TESTS, DEMO_CATALOG_TESTS;
@@ -6498,6 +6517,7 @@ var init_sections = __esm({
6498
6517
  "slowTests",
6499
6518
  "defectLog",
6500
6519
  "briefBand",
6520
+ "runDiff",
6501
6521
  // display modifiers
6502
6522
  "passRate",
6503
6523
  "fullEnvironment",
@@ -6521,6 +6541,7 @@ var init_sections = __esm({
6521
6541
  slowTests: false,
6522
6542
  defectLog: false,
6523
6543
  briefBand: false,
6544
+ runDiff: true,
6524
6545
  passRate: true,
6525
6546
  fullEnvironment: false,
6526
6547
  retries: true,
@@ -6542,6 +6563,7 @@ var init_sections = __esm({
6542
6563
  slowTests: true,
6543
6564
  defectLog: true,
6544
6565
  briefBand: false,
6566
+ runDiff: true,
6545
6567
  passRate: true,
6546
6568
  fullEnvironment: true,
6547
6569
  retries: true,
@@ -6568,6 +6590,7 @@ var init_sections = __esm({
6568
6590
  slowTests: true,
6569
6591
  defectLog: false,
6570
6592
  briefBand: true,
6593
+ runDiff: true,
6571
6594
  passRate: true,
6572
6595
  fullEnvironment: false,
6573
6596
  retries: false,
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Reporter, FullConfig, Suite, TestCase, TestResult, TestStep, FullResult } from '@playwright/test/reporter';
2
2
 
3
3
  /**
4
- * Canonical section catalog. 14 block toggles (section present/absent) followed
4
+ * Canonical section catalog. 15 block toggles (section present/absent) followed
5
5
  * by 5 display modifiers (tweak a section that is on). Single source of truth —
6
6
  * the Zod schema in src/config/schema.ts builds its flag shape from this array.
7
7
  */
8
- declare const SECTION_KEYS: readonly ["coverPage", "analysisOneliner", "releaseGate", "summary", "charts", "trend", "requirementsMatrix", "ciEnvironment", "suiteBreakdown", "failureDeepDive", "failureAnalysis", "slowTests", "defectLog", "briefBand", "passRate", "fullEnvironment", "retries", "fullFailures", "stackTraces"];
8
+ declare const SECTION_KEYS: readonly ["coverPage", "analysisOneliner", "releaseGate", "summary", "charts", "trend", "requirementsMatrix", "ciEnvironment", "suiteBreakdown", "failureDeepDive", "failureAnalysis", "slowTests", "defectLog", "briefBand", "runDiff", "passRate", "fullEnvironment", "retries", "fullFailures", "stackTraces"];
9
9
  type SectionKey = (typeof SECTION_KEYS)[number];
10
10
  /** A partial map of section flags — used both as the flat baseline and per-template. */
11
11
  type SectionFlags = Partial<Record<SectionKey, boolean>>;
@@ -406,12 +406,18 @@ interface ReporterOptions {
406
406
  * every chosen template; per-template keys (`minimal` / `detailed` /
407
407
  * `executive`) override the baseline for that template only.
408
408
  *
409
+ * 20 keys total: 15 block toggles, 5 display modifiers.
410
+ *
409
411
  * Block toggles: `coverPage`, `analysisOneliner`, `releaseGate`, `summary`,
410
412
  * `charts`, `trend`, `requirementsMatrix`, `ciEnvironment`, `suiteBreakdown`,
411
- * `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`.
413
+ * `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`,
414
+ * `runDiff`.
412
415
  * Display modifiers: `passRate`, `fullEnvironment`, `retries`, `fullFailures`,
413
416
  * `stackTraces`.
414
417
  *
418
+ * `runDiff` shows new failures, fixed tests, and still-failing tests against
419
+ * the previous run on the same branch; on by default in all three templates.
420
+ *
415
421
  * `trend` renders only when `charts` is also on and history data exists (`showTrend` enabled). Sections gated on data
416
422
  * (`failureAnalysis`, `requirementsMatrix`, `slowTests`, `defectLog`) appear
417
423
  * only when matching data exists — this option never changes data collection.
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Reporter, FullConfig, Suite, TestCase, TestResult, TestStep, FullResult } from '@playwright/test/reporter';
2
2
 
3
3
  /**
4
- * Canonical section catalog. 14 block toggles (section present/absent) followed
4
+ * Canonical section catalog. 15 block toggles (section present/absent) followed
5
5
  * by 5 display modifiers (tweak a section that is on). Single source of truth —
6
6
  * the Zod schema in src/config/schema.ts builds its flag shape from this array.
7
7
  */
8
- declare const SECTION_KEYS: readonly ["coverPage", "analysisOneliner", "releaseGate", "summary", "charts", "trend", "requirementsMatrix", "ciEnvironment", "suiteBreakdown", "failureDeepDive", "failureAnalysis", "slowTests", "defectLog", "briefBand", "passRate", "fullEnvironment", "retries", "fullFailures", "stackTraces"];
8
+ declare const SECTION_KEYS: readonly ["coverPage", "analysisOneliner", "releaseGate", "summary", "charts", "trend", "requirementsMatrix", "ciEnvironment", "suiteBreakdown", "failureDeepDive", "failureAnalysis", "slowTests", "defectLog", "briefBand", "runDiff", "passRate", "fullEnvironment", "retries", "fullFailures", "stackTraces"];
9
9
  type SectionKey = (typeof SECTION_KEYS)[number];
10
10
  /** A partial map of section flags — used both as the flat baseline and per-template. */
11
11
  type SectionFlags = Partial<Record<SectionKey, boolean>>;
@@ -406,12 +406,18 @@ interface ReporterOptions {
406
406
  * every chosen template; per-template keys (`minimal` / `detailed` /
407
407
  * `executive`) override the baseline for that template only.
408
408
  *
409
+ * 20 keys total: 15 block toggles, 5 display modifiers.
410
+ *
409
411
  * Block toggles: `coverPage`, `analysisOneliner`, `releaseGate`, `summary`,
410
412
  * `charts`, `trend`, `requirementsMatrix`, `ciEnvironment`, `suiteBreakdown`,
411
- * `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`.
413
+ * `failureDeepDive`, `failureAnalysis`, `slowTests`, `defectLog`, `briefBand`,
414
+ * `runDiff`.
412
415
  * Display modifiers: `passRate`, `fullEnvironment`, `retries`, `fullFailures`,
413
416
  * `stackTraces`.
414
417
  *
418
+ * `runDiff` shows new failures, fixed tests, and still-failing tests against
419
+ * the previous run on the same branch; on by default in all three templates.
420
+ *
415
421
  * `trend` renders only when `charts` is also on and history data exists (`showTrend` enabled). Sections gated on data
416
422
  * (`failureAnalysis`, `requirementsMatrix`, `slowTests`, `defectLog`) appear
417
423
  * only when matching data exists — this option never changes data collection.