# 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](core-commands.md) for basic CLI usage ## Quick Reference ```bash # 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 # 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 ```bash # 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: ```bash # 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 ## Console Monitoring View JavaScript console output from the page — essential for catching errors: ```bash # 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 ```bash 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: ```bash 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 ```bash 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: ```bash playwright-cli network ``` ### Watch Network in Real-Time ```bash 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 ```bash playwright-cli run-code "async page => { page.on('requestfailed', request => { console.log(\`FAILED: \${request.method()} \${request.url()} - \${request.failure()?.errorText}\`); }); }" ``` ### Inspect a Specific Response ```bash 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() }; }" ``` ## Debugging Strategies ### Strategy 1: Snapshot Before and After The simplest debugging approach — see what changed: ```bash 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: ```bash 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: ```bash # 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 ```bash # 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: ```bash # 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 ```bash 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 ```bash 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 ```bash 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: ```bash 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: ```bash 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: ```bash # Remove traces older than 7 days find .playwright-cli/traces -mtime +7 -delete ``` ### 4. Combine Techniques The most effective debugging combines multiple approaches: ```bash 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 ```