The test passes locally. It fails in CI. You have no browser to look at. No DevTools. No console. This is the most frustrating situation in test automation. But if you have set up your artifacts correctly, you have everything you need. Let me show you the debugging workflow.
Check the CI console output -- look at the error message and stack trace first
Download the HTML report artifact -- get the full picture of what passed and failed
Open with npx playwright show-report -- browse the interactive report
Click the failed test -- see the error, screenshot at failure point, and trace link
Download the trace artifact (test-results folder)
Open with npx playwright show-trace trace.zip -- replay the test step by step
Check the Actions tab, Network tab, and Console tab in trace viewer
Look for: timeout errors, element not found, wrong selectors, network failures, race conditions
| Pattern | Symptom | Root Cause | Fix |
|---|---|---|---|
| Timeout | Test times out waiting for element | Slower CI machine, element not rendering | Increase timeout or fix selector |
| Flaky pass/fail | Same test passes 70% of the time | Race condition, animation, network timing | Add proper waits, use waitForLoadState |
| All tests fail | Every test crashes at launch | Missing system dependencies | Use --with-deps flag or Docker image |
| Visual diff | Screenshot comparison fails | Different OS renders fonts differently | Update baseline for CI OS or use threshold |
| OOM crash | Runner exits without error | Too many workers, memory exhausted | Reduce workers to 50% or lower |
| Shard imbalance | One shard takes 3x longer | Large test files on same shard | Split large files into smaller ones |
The blob reporter produces a single binary file containing all test results, traces, and attachments. It is designed specifically for CI. Unlike the html reporter which produces browsable files, blob produces a compact format that can be merged and post-processed.
export default defineConfig({
reporter: process.env.CI
? [
// Blob for merging sharded results
['blob'],
// GitHub for PR annotations
['github'],
// List for console output in CI logs
['list'],
]
: [['html', { open: 'on-failure' }]],
});The trace viewer is your most powerful tool. When you open a trace file, you get:
# View a trace file locally
npx playwright show-trace test-results/my-test/trace.zip
# Or use the online viewer (no install needed)
# Visit: trace.playwright.dev
# Drag and drop the trace.zip file
# Merge and view sharded blob reports
npx playwright merge-reports --reporter html ./blob-reports
npx playwright show-reportIf the trace does not reveal the issue, reproduce the CI environment locally using Docker.
# Run tests in the same Docker image as CI
docker run --rm -v $(pwd):/app -w /app \
-e CI=true \
mcr.microsoft.com/playwright:v1.48.0-jammy \
bash -c "npm ci && npx playwright test tests/login.spec.ts --trace on"
# The trace file will be in test-results/ on your local machine
npx playwright show-trace test-results/login-test/trace.zipDo not ignore flaky tests. A test that fails 10% of the time in CI has a real bug -- either in the test or in the app. Track flaky tests, prioritize fixing them. Flaky tests erode trust in the entire test suite. Once people start ignoring CI failures, the pipeline becomes useless.
Q: A Playwright test passes locally but fails in CI. How do you debug it?
A: First, check the CI console for the error message. Then download the HTML report artifact and open it with npx playwright show-report. Click the failed test to see the screenshot and error. Download the trace artifact and open with npx playwright show-trace -- this shows every action, network request, and DOM snapshot step by step. Common causes: slower CI machines cause timeouts, missing system dependencies, different screen resolution, race conditions that are timing-sensitive. If the trace does not help, reproduce locally using the same Docker image as CI with docker run and the Playwright image.
Key Point: Trace viewer is your best friend for CI debugging. It shows every action, network request, console log, and DOM snapshot. Always configure trace: "on-first-retry" in CI.
Key Point: Download traces and HTML reports from CI artifacts. Use npx playwright show-trace to replay failed tests step by step.