@reportforge/playwright-pdf 0.23.0 → 0.25.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
@@ -220,7 +220,7 @@ Full reference: [reportforge.org/docs/configuration](https://reportforge.org/doc
220
220
 
221
221
  ### Live Runs
222
222
 
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.
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. 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
224
 
225
225
  > 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
226
 
@@ -239,13 +239,13 @@ reporter: [
239
239
  ],
240
240
  ```
241
241
 
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.
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. 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
243
 
244
244
  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
245
 
246
246
  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
247
 
248
- > **Security:** the watch link exposes test titles + statuses (and step titles when `steps` is on). 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).
248
+ > **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
249
 
250
250
  ### Shard Merging
251
251
 
@@ -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
File without changes
package/dist/index.d.mts CHANGED
@@ -552,9 +552,12 @@ declare class PdfReporter implements Reporter {
552
552
  * Announces the watch link once the run is confirmed live-entitled. Gating on
553
553
  * the SAME resolved entitlement the streamer requires (`jwt` + the `'live'`
554
554
  * feature) guarantees the link is never printed or posted for a run that will
555
- * never stream — no dead links. The chat ping fires from the primary shard only
556
- * (unsharded, or `shard.current === 1`) so an N-way matrix posts one message,
557
- * not N. The banner still prints from every shard's own log.
555
+ * never stream — no dead links. The link's token is the server-ISSUED one from
556
+ * the announce handshake (random, key-independent a key rotation can never
557
+ * kill the link); the key-derived HMAC is minted only as a fallback when the
558
+ * handshake fails (network blip, older server). The chat ping fires from the
559
+ * primary shard only (unsharded, or `shard.current === 1`) so an N-way matrix
560
+ * posts one message, not N. The banner still prints from every shard's own log.
558
561
  */
559
562
  private announceLive;
560
563
  private resolveProjectName;
package/dist/index.d.ts CHANGED
@@ -552,9 +552,12 @@ declare class PdfReporter implements Reporter {
552
552
  * Announces the watch link once the run is confirmed live-entitled. Gating on
553
553
  * the SAME resolved entitlement the streamer requires (`jwt` + the `'live'`
554
554
  * feature) guarantees the link is never printed or posted for a run that will
555
- * never stream — no dead links. The chat ping fires from the primary shard only
556
- * (unsharded, or `shard.current === 1`) so an N-way matrix posts one message,
557
- * not N. The banner still prints from every shard's own log.
555
+ * never stream — no dead links. The link's token is the server-ISSUED one from
556
+ * the announce handshake (random, key-independent a key rotation can never
557
+ * kill the link); the key-derived HMAC is minted only as a fallback when the
558
+ * handshake fails (network blip, older server). The chat ping fires from the
559
+ * primary shard only (unsharded, or `shard.current === 1`) so an N-way matrix
560
+ * posts one message, not N. The banner still prints from every shard's own log.
558
561
  */
559
562
  private announceLive;
560
563
  private resolveProjectName;