New core/trace-analysis.md: agent-native debugging of trace.zip reports with the npx playwright trace CLI (1.59+) - full command reference, agent debug loop with decision trees, failure playbooks, and security trust boundary for trace contents. Playwright 1.61 updates across guides: - WebAuthn passkey testing via context.credentials (auth-flows) - page.localStorage / page.sessionStorage Web Storage API (browser-apis) - New video retention modes matching trace modes (configuration, ci) - expect.soft.poll() (assertions-and-waiting) - WebSockets now included in HAR and trace recordings (websockets, trace-analysis) - apiResponse.securityDetails() / serverAddr() (api-testing) - -G shorthand for --grep-invert (test-organization) - Fix deprecated webError.location() fields lineNumber/columnNumber -> line/column (debugging) Bump skill version to 2.4.0, update coverage claims to 1.61. Co-authored-by: prat3ik <pratikquora@gmail.com>
15 KiB
Tracing and Debugging
When to use: Debugging failing actions, analyzing performance bottlenecks, capturing execution evidence, understanding why an interaction didn't work, or inspecting network and console activity during automation. Prerequisites: core-commands.md for basic CLI usage
Quick Reference
# Trace a session
playwright-cli tracing-start
playwright-cli open https://example.com
playwright-cli click e4
playwright-cli fill e7 "test"
playwright-cli tracing-stop
# Attach to a paused Playwright test (Playwright 1.59+)
npx playwright test --debug=cli
playwright-cli attach my-session
playwright-cli --session=my-session step-over
# Inspect traces from the terminal (Playwright 1.59+)
npx playwright trace open traces/trace.zip
npx playwright trace actions
npx playwright trace action 9
npx playwright trace snapshot 9 --name after
npx playwright trace close
# View console messages
playwright-cli console # All levels
playwright-cli console error # Errors only
playwright-cli console warning # Warnings only
# View network activity
playwright-cli network
Tracing
Traces capture everything — DOM snapshots, screenshots, network activity, console logs, and timing — for every action during a session.
Basic Usage
# Start recording before the flow you want to debug
playwright-cli tracing-start
# Perform actions
playwright-cli open https://example.com
playwright-cli snapshot
playwright-cli click e4
playwright-cli fill e7 "test data"
playwright-cli click e9
# Stop and save the trace
playwright-cli tracing-stop
What Traces Capture
| Category | Details |
|---|---|
| Actions | Every click, fill, hover, keyboard input, navigation — with timing |
| DOM Snapshots | Full DOM state before and after each action |
| Screenshots | Visual state at each step |
| Network | All HTTP requests, responses, headers, bodies, timing |
| Console | All console.log, console.warn, console.error messages |
| Timing | Precise duration for each operation |
| Source | Which command triggered each action |
Trace Output Files
When tracing is active, Playwright creates a traces/ directory:
trace-{timestamp}.trace — Main trace file containing:
- Action log with DOM snapshots
- Screenshots at each step
- Timing information
- Console messages
trace-{timestamp}.network — Network activity:
- All HTTP requests and responses
- Request/response headers and bodies
- DNS, connect, TLS, TTFB, download timing
- Resource sizes and failed requests
resources/ — Cached assets for trace replay:
- Images, fonts, stylesheets, scripts
- Response bodies for offline replay
Viewing Traces
Open traces in Playwright's Trace Viewer — a rich GUI for step-by-step debugging:
# Open trace in the Trace Viewer web app
npx playwright show-trace traces/trace-123456.trace
# Or use the online Trace Viewer
# Upload trace file to: https://trace.playwright.dev
The Trace Viewer shows:
- Timeline: Step-by-step actions with screenshots
- DOM Snapshot: Inspect elements at each step (like DevTools)
- Network: Waterfall view of all requests
- Console: Log messages with timestamps
- Source: The code that triggered each action
CLI Trace Analysis (Playwright 1.59+)
When you are working over SSH, inside an agent loop, or on a machine without a GUI, the npx playwright trace commands let you inspect traces directly from the terminal.
# Open a trace archive
npx playwright trace open test-results/checkout-chromium/trace.zip
# List recorded actions
npx playwright trace actions
npx playwright trace actions --grep="expect"
# Inspect one action in detail
npx playwright trace action 9
# Render the before/after snapshot for a specific action
npx playwright trace snapshot 9 --name before
npx playwright trace snapshot 9 --name after
# Close the current trace session
npx playwright trace close
Use the GUI Trace Viewer when you want the richest visual timeline. Use the CLI trace tools when you need quick answers in a terminal-first workflow.
For the full
npx playwright tracecommand surface (requests,console,errors,attachments,screenshot), agent decision trees, and failure-type playbooks for debugging atrace.zippost-mortem, see core/trace-analysis.md.
Agent Debugging With --debug=cli (Playwright 1.59+)
Playwright 1.59 adds a debugger flow designed for coding agents and terminal-based debugging. Start the test runner with --debug=cli, attach with playwright-cli, and then step through the paused test from the command line.
# Terminal 1: launch the paused test
npx playwright test --debug=cli
# Terminal 2: attach using the session id printed by Playwright
playwright-cli attach tw-87b59e
playwright-cli --session=tw-87b59e snapshot
playwright-cli --session=tw-87b59e step-over
playwright-cli --session=tw-87b59e console error
This is especially useful when an agent needs to inspect a paused browser, try locators, or compare page state without opening the full inspector UI.
Console Monitoring
View JavaScript console output from the page — essential for catching errors:
# Show all console messages
playwright-cli console
# Filter by severity level
playwright-cli console error # Only errors
playwright-cli console warning # Only warnings
playwright-cli console info # Only info messages
playwright-cli console log # Only log messages
Common Debugging Pattern
playwright-cli open https://app.example.com
playwright-cli snapshot
playwright-cli click e5 # Something unexpected happens
# Check if there were JavaScript errors
playwright-cli console error
# Output might show:
# [error] TypeError: Cannot read properties of undefined (reading 'map')
# [error] Uncaught ReferenceError: processData is not defined
Watch Console During Interaction
Use run-code to set up continuous console monitoring:
playwright-cli run-code "async page => {
page.on('console', msg => {
if (msg.type() === 'error' || msg.type() === 'warning') {
console.log(\`[\${msg.type()}] \${msg.text()}\`);
}
});
}"
# Now interact — errors and warnings will print as they occur
playwright-cli click e5
playwright-cli fill e3 "test"
Capture Uncaught Exceptions
playwright-cli run-code "async page => {
page.on('pageerror', error => {
console.log('Uncaught exception:', error.message);
});
}"
Network Monitoring
View all network requests made by the page:
playwright-cli network
Watch Network in Real-Time
playwright-cli run-code "async page => {
page.on('request', request => {
console.log(\`>> \${request.method()} \${request.url()}\`);
});
page.on('response', response => {
console.log(\`<< \${response.status()} \${response.url()}\`);
});
}"
# Now interact — requests will print as they happen
playwright-cli click e5
Monitor Failed Requests
playwright-cli run-code "async page => {
page.on('requestfailed', request => {
console.log(\`FAILED: \${request.method()} \${request.url()} - \${request.failure()?.errorText}\`);
});
}"
Inspect a Specific Response
playwright-cli run-code "async page => {
const response = await page.waitForResponse('**/api/users');
return {
status: response.status(),
statusText: response.statusText(),
headers: response.headers(),
body: await response.json()
};
}"
Capture Scoped HAR via Tracing (Playwright 1.60+)
When you want a HAR file for just one portion of a flow — not the whole session — use the 1.60 tracing.startHar() / tracing.stopHar() API from run-code. It records network traffic to a HAR file on demand and accepts the same content, mode, and urlFilter options as context-level recordHar.
# Start scoped HAR recording for the API calls in the next step
playwright-cli run-code "async page => {
await page.context().tracing.startHar({
path: 'traces/checkout.har',
urlFilter: '**/api/**',
content: 'embed',
});
}"
playwright-cli click e5 # the flow you want captured
# Stop and flush the HAR
playwright-cli run-code "async page => {
await page.context().tracing.stopHar();
}"
Inside the Playwright test runner the same API supports await using for automatic cleanup — see core/network-mocking.md.
Debugging Strategies
Strategy 1: Snapshot Before and After
The simplest debugging approach — see what changed:
playwright-cli snapshot --filename=before.yaml
playwright-cli click e5
playwright-cli snapshot --filename=after.yaml
# Compare the two snapshots to understand what changed
Strategy 2: Trace the Failing Flow
Start tracing before the step that fails:
playwright-cli tracing-start
# Reproduce the issue
playwright-cli goto https://app.example.com/checkout
playwright-cli fill e1 "Jane Doe"
playwright-cli click e5 # This step fails
playwright-cli tracing-stop
# Open trace to see DOM state when the click was attempted
Strategy 3: Check Element State
When an interaction fails, check what state the element is actually in:
# Is the element visible?
playwright-cli eval "el => window.getComputedStyle(el).display" e5
playwright-cli eval "el => window.getComputedStyle(el).visibility" e5
playwright-cli eval "el => el.getBoundingClientRect()" e5
# Is it covered by another element?
playwright-cli eval "el => {
const rect = el.getBoundingClientRect();
const topEl = document.elementFromPoint(rect.x + rect.width/2, rect.y + rect.height/2);
return topEl === el ? 'Element is on top' : 'Covered by: ' + topEl?.tagName + '.' + topEl?.className;
}" e5
# Is it disabled?
playwright-cli eval "el => el.disabled" e5
playwright-cli eval "el => el.getAttribute('aria-disabled')" e5
Strategy 4: Console + Network Combined
# Set up monitoring for both console and network
playwright-cli run-code "async page => {
page.on('console', msg => {
if (msg.type() === 'error') console.log('[CONSOLE]', msg.text());
});
page.on('requestfailed', req => {
console.log('[NETWORK]', req.method(), req.url(), req.failure()?.errorText);
});
page.on('response', resp => {
if (resp.status() >= 400) {
console.log('[HTTP ERROR]', resp.status(), resp.url());
}
});
}"
# Now interact and watch for errors
playwright-cli click e5
playwright-cli fill e3 "test"
Strategy 5: Wait and Retry
If actions fail due to timing, add explicit waits:
# Wait for element to be actionable
playwright-cli run-code "async page => {
await page.locator('#dynamic-button').waitFor({ state: 'visible', timeout: 10000 });
}"
playwright-cli snapshot
playwright-cli click e5
# Wait for page to settle
playwright-cli run-code "async page => {
await page.waitForLoadState('networkidle');
}"
playwright-cli snapshot
Performance Analysis
Measure Page Load Time
playwright-cli run-code "async page => {
const timing = await page.evaluate(() => {
const t = performance.timing;
return {
dns: t.domainLookupEnd - t.domainLookupStart,
tcp: t.connectEnd - t.connectStart,
ttfb: t.responseStart - t.requestStart,
download: t.responseEnd - t.responseStart,
domParsing: t.domInteractive - t.domLoading,
domComplete: t.domComplete - t.domLoading,
total: t.loadEventEnd - t.navigationStart
};
});
return timing;
}"
Analyze with Navigation Timing API
playwright-cli run-code "async page => {
const entries = await page.evaluate(() => {
return performance.getEntriesByType('navigation').map(e => ({
type: e.type,
redirectTime: e.redirectEnd - e.redirectStart,
dnsTime: e.domainLookupEnd - e.domainLookupStart,
connectTime: e.connectEnd - e.connectStart,
tlsTime: e.secureConnectionStart > 0 ? e.connectEnd - e.secureConnectionStart : 0,
requestTime: e.responseStart - e.requestStart,
responseTime: e.responseEnd - e.responseStart,
domProcessing: e.domComplete - e.domInteractive,
loadTime: e.loadEventEnd - e.loadEventStart,
totalTime: e.loadEventEnd - e.startTime
}));
});
return entries;
}"
List Slow Resources
playwright-cli run-code "async page => {
const resources = await page.evaluate(() => {
return performance.getEntriesByType('resource')
.map(r => ({ name: r.name.split('/').pop(), duration: Math.round(r.duration), size: r.transferSize }))
.sort((a, b) => b.duration - a.duration)
.slice(0, 10);
});
return resources;
}"
Trace vs Video vs Screenshot
Choose the right capture method:
| Feature | Trace | Video | Screenshot |
|---|---|---|---|
| Format | .trace file |
.webm video |
.png image |
| DOM inspection | Yes | No | No |
| Network details | Yes | No | No |
| Step-by-step replay | Yes | Continuous | Single frame |
| Console logs | Yes | No | No |
| File size | Medium | Large | Small |
| Best for | Debugging | Demos, documentation | Quick capture |
Decision Guide
- Something failed and you don't know why → Trace
- Need to show a flow to someone → Video
- Need to verify visual state → Screenshot
- Need to analyze performance → Trace (has network waterfall)
- CI artifact for failed test → Trace + Screenshot
Best Practices
1. Start Tracing BEFORE the Problem
Trace the entire flow leading up to the failure, not just the failing step:
playwright-cli tracing-start
# Reproduce the full flow from the beginning
playwright-cli open https://app.example.com
playwright-cli fill e1 "user@example.com"
playwright-cli click e3
# ... all steps leading to the failure ...
playwright-cli tracing-stop
2. Use Console Monitoring Proactively
Start console monitoring at the beginning of any debugging session:
playwright-cli run-code "async page => {
page.on('console', msg => console.log(\`[\${msg.type()}] \${msg.text()}\`));
page.on('pageerror', err => console.log('[EXCEPTION]', err.message));
}"
3. Clean Up Old Traces
Traces consume significant disk space:
# Remove traces older than 7 days
find .playwright-cli/traces -mtime +7 -delete
4. Combine Techniques
The most effective debugging combines multiple approaches:
playwright-cli tracing-start # Capture everything
playwright-cli console error # Watch for JS errors
playwright-cli network # Watch for failed requests
playwright-cli snapshot # See current state
# ... interact and debug ...
playwright-cli tracing-stop # Save trace for detailed analysis