level 07 / reporting-and-artifacts
Reporting & Artifact Management
Configure Playwright reporters and manage test artifacts in CI pipelines.
Built-In Reporters
// playwright.config.ts
export default defineConfig({
reporter: [
['html', { outputFolder: 'playwright-report', open: 'on-failure' }],
['junit', { outputFile: 'test-results/results.xml' }],
['json', { outputFile: 'test-results/results.json' }],
['line'], // compact console output
['dot'], // minimal dots per test
],
});
Mix reporters: reporter: [['html'], ['junit']]
HTML Reporter
The HTML reporter produces a self-contained index.html with:
- Pass/fail counts per file and test
- Error messages with stack traces
- Screenshots on failure (if configured)
- Video recordings (if configured)
- Traces (if configured — opens in Trace Viewer)
# View report locally
npx playwright show-report playwright-report/
# Generate for specific test run
npx playwright test --reporter=html
Trace Viewer
Traces capture the full test execution — DOM snapshots, network calls, console logs, screenshots at each action:
// playwright.config.ts
use: {
trace: 'on-first-retry', // capture on first retry
// 'on' // always capture
// 'off' // never capture
// 'retain-on-failure' // keep only on failure
}
# Open a trace file
npx playwright show-trace test-results/auth-login/trace.zip
Allure Reporter
Rich third-party reporter with history, trends, and categories:
npm install --save-dev allure-playwright
reporter: [['allure-playwright', {
detail: true,
outputFolder: 'allure-results',
suiteTitle: false,
}]],
# Generate and open Allure report
npx allure generate allure-results --clean
npx allure open
CI Artifact Management
GitHub Actions
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-${{ github.run_id }}
path: |
playwright-report/
test-results/**/*.zip # traces
retention-days: 30
Artifact Naming Strategy
playwright-report-<run-id>/ # unique per run — no collisions
test-results-shard-1/ # per shard on matrix runs
allure-report-<branch>-<sha>/ # branch + commit for traceability
Custom Reporter
// reporters/slack-reporter.ts
import { Reporter, TestCase, TestResult } from '@playwright/test/reporter';
class SlackReporter implements Reporter {
private failed: string[] = [];
onTestEnd(test: TestCase, result: TestResult) {
if (result.status === 'failed') {
this.failed.push(test.title);
}
}
async onEnd() {
if (this.failed.length > 0) {
await fetch(process.env.SLACK_WEBHOOK!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `❌ ${this.failed.length} test(s) failed:\n${this.failed.join('\n')}`,
}),
});
}
}
}
export default SlackReporter;
// playwright.config.ts
reporter: [['html'], ['./reporters/slack-reporter.ts']],
Reporter Selection by Environment
reporter: process.env.CI
? [
['blob'], // for shard merging
['github'], // PR annotations
['junit', { outputFile: 'results.xml' }],
]
: [
['html', { open: 'on-failure' }], // opens browser on failure
['line'], // compact console
],