4.2Essential Artifact Types
Test Reports
Test reports are the primary artifacts. They tell you what passed, what failed, and provide details for each failure.
| Format | Best For | Consumed By |
|---|---|---|
| JUnit XML | Universal standard; every CI platform can parse it | GitHub Actions annotations, GitLab MR widgets, Jenkins test results |
| HTML reports | Human-readable, shareable with non-technical stakeholders | Browsers, Slack links |
| Allure reports | Rich interactive reports with history and trends | Allure server, static hosting |
| JSON results | Programmatic analysis, custom dashboards | Scripts, Grafana, custom tools |
# Generate JUnit XML for CI platform integration
- run: npx playwright test --reporter=junit
env:
PLAYWRIGHT_JUNIT_OUTPUT_NAME: results.xml
# Generate HTML for human consumption
- run: npx playwright test --reporter=html
# Generate both
- run: npx playwright test --reporter=junit,html
Pro tip: Configure your test runner to produce JUnit XML by default (for the CI platform to parse) and HTML reports on demand (for manual investigation).
Screenshots and Videos
Browser test failures are almost impossible to diagnose without visual evidence. Configure your test framework to capture screenshots on failure and optionally record video.
// playwright.config.ts
export default defineConfig({
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
},
});
Playwright traces are especially valuable. A trace captures a timeline of every action, network request, DOM snapshot, and console log. You can open them in the Trace Viewer and step through the test execution like a debugger.
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-traces
path: test-results/
retention-days: 14
Coverage Reports
Coverage reports track which lines of code were exercised during testing. They are useful for:
- Identifying untested code paths
- Tracking coverage trends over time
- Verifying that new code has tests
- run: npm run test:unit -- --coverage --coverageReporters=lcov --coverageReporters=text
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-report
path: coverage/
Important: Track coverage trends, not absolute numbers. A coverage threshold of 80% is meaningless if the uncovered 20% contains the most critical business logic. Better: require that new code is covered, not that the entire codebase meets a threshold.
Logs
Application logs from test containers, browser console logs, and network HAR files provide context that test reports alone cannot.
# Capture Docker container logs
- name: Capture service logs
if: failure()
run: |
docker logs test-db > postgres.log 2>&1
docker logs test-app > application.log 2>&1
- uses: actions/upload-artifact@v4
if: failure()
with:
name: service-logs
path: |
postgres.log
application.log
HAR Files (Network Traffic)
HAR (HTTP Archive) files capture every network request and response during a test. They are invaluable for debugging API-related test failures.
// Capture HAR file in Playwright
const context = await browser.newContext({
recordHar: { path: 'test-results/network.har' }
});
// ... run tests ...
await context.close(); // HAR file is saved on close