Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Playwright testing guide covering E2E, component, API, visual, accessibility, and security tests.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
debugging/debugging.md
1# Debugging & Troubleshooting23## Table of Contents451. [Debug Tools](#debug-tools)62. [Trace Viewer](#trace-viewer)73. [Identifying Flaky Tests](#identifying-flaky-tests)84. [Debugging Network Issues](#debugging-network-issues)95. [Debugging in CI](#debugging-in-ci)106. [Debugging Authentication](#debugging-authentication)117. [Debugging Screenshots](#debugging-screenshots)128. [Common Issues](#common-issues)139. [Logging](#logging)1415## Debug Tools1617### Playwright Inspector1819```bash20# Run with inspector21PWDEBUG=1 npx playwright test22# Or specific test23PWDEBUG=1 npx playwright test login.spec.ts24```2526Features:2728- Step through test actions29- Pick locators visually30- Inspect DOM state31- Edit and re-run3233### Headed Mode3435```bash36# Run with visible browser37npx playwright test --headed3839# Interactive debugging (headed, paused, step-through)40npx playwright test --debug41```4243You can also set `slowMo` to add an `N` ms delay per action, making test execution easier to follow while debugging.4445```typescript46// playwright.config.ts47export default defineConfig({48use: {49launchOptions: {50slowMo: 500,51},52},53});54```5556### UI Mode5758```bash59# Interactive test runner60npx playwright test --ui61```6263Features:6465- Watch mode66- Test timeline67- DOM snapshots68- Network logs69- Console logs7071### Debug in Code7273```typescript74test("debug example", async ({ page }) => {75await page.goto("/");7677// Pause and open inspector78await page.pause();7980// Continue test...81await page.click("button");82});83```8485## Trace Viewer8687### Enable Traces8889```typescript90// playwright.config.ts91export default defineConfig({92use: {93trace: "on-first-retry", // Record on retry94// trace: 'on', // Always record95// trace: 'retain-on-failure', // Keep only failures96},97});98```99100### View Traces101102```bash103# Open trace file104npx playwright show-trace trace.zip105106# From test-results107npx playwright show-trace test-results/test-name/trace.zip108```109110### Trace Contents111112- Screenshots at each action113- DOM snapshots114- Network requests/responses115- Console logs116- Action timeline117- Source code118119### Programmatic Traces120121```typescript122test("manual trace", async ({ page, context }) => {123await context.tracing.start({ screenshots: true, snapshots: true });124125await page.goto("/");126await page.click("button");127128await context.tracing.stop({ path: "trace.zip" });129});130```131132## Identifying Flaky Tests133134If a test fails intermittently, it's likely flaky. Quick checks:135136| Behavior | Likely Cause | Next Step |137| -------------------------------------- | ----------------------------- | -------------------------------------- |138| Fails sometimes, passes other times | Flaky - timing/race condition | [flaky-tests.md](flaky-tests.md) |139| Fails only with multiple workers | Flaky - parallelism/isolation | [flaky-tests.md](flaky-tests.md) |140| Fails only in CI | Environment difference | [CI Debugging](#debugging-in-ci) below |141| Always fails | Bug in test or app | Debug with tools above |142| Always passes locally, always fails CI | CI-specific issue | [ci-cd.md](../infrastructure-ci-cd/ci-cd.md) |143144> **For flaky test detection commands, root cause analysis, and fixing strategies**, see [flaky-tests.md](flaky-tests.md).145146## Debugging Network Issues147148### Monitor All Requests149150```typescript151test("debug network", async ({ page }) => {152const requests: string[] = [];153const failures: string[] = [];154155page.on("request", (req) => requests.push(`>> ${req.method()} ${req.url()}`));156page.on("requestfinished", (req) => {157const resp = req.response();158requests.push(`<< ${resp?.status()} ${req.url()}`);159});160page.on("requestfailed", (req) => {161failures.push(`FAILED: ${req.url()} - ${req.failure()?.errorText}`);162});163164await page.goto("/dashboard");165166// Log summary167console.log("Requests:", requests.length);168if (failures.length) console.log("Failures:", failures);169});170```171172### Wait for Specific API Response173174When debugging network-dependent issues, wait for specific API responses instead of arbitrary timeouts.175176```typescript177// Start waiting BEFORE triggering the request178const responsePromise = page.waitForResponse(179(resp) => resp.url().includes("/api/data") && resp.status() === 200,180);181await page.getByRole("button", { name: "Load" }).click();182const response = await responsePromise;183console.log("Status:", response.status());184```185186> **For comprehensive waiting patterns** (navigation, element state, network, polling), see [assertions-waiting.md](../core/assertions-waiting.md#waiting-strategies).187188### Debug Slow Requests189190```typescript191test("find slow requests", async ({ page }) => {192page.on("requestfinished", (request) => {193const timing = request.timing();194const total = timing.responseEnd - timing.requestStart;195if (total > 1000) {196console.log(`SLOW (${total}ms): ${request.url()}`);197}198});199200await page.goto("/");201});202```203204## Debugging in CI205206### Simulate CI Locally207208```bash209# Run in headless mode like CI210CI=true npx playwright test211212# Match CI browser versions213npx playwright install --with-deps214215# Run in Docker (same as CI)216docker run --rm -v $(pwd):/work -w /work \217mcr.microsoft.com/playwright:v1.40.0-jammy \218npx playwright test219```220221### CI-Specific Configuration222223```typescript224// playwright.config.ts225export default defineConfig({226// More artifacts in CI for debugging227use: {228trace: process.env.CI ? "on-first-retry" : "off",229video: process.env.CI ? "retain-on-failure" : "off",230screenshot: process.env.CI ? "only-on-failure" : "off",231},232233// More retries in CI (but investigate failures!)234retries: process.env.CI ? 2 : 0,235});236```237238### Debug CI Environment239240```typescript241test("CI environment check", async ({ page }, testInfo) => {242console.log("CI:", process.env.CI);243console.log("Project:", testInfo.project.name);244console.log("Worker:", testInfo.workerIndex);245console.log("Retry:", testInfo.retry);246console.log("Base URL:", testInfo.project.use.baseURL);247248// Check viewport249const viewport = page.viewportSize();250console.log("Viewport:", viewport);251});252```253254## Debugging Authentication255256```typescript257test("debug auth", async ({ page, context }) => {258// Inspect current storage state259const storage = await context.storageState();260console.log(261"Cookies:",262storage.cookies.map((c) => c.name),263);264265// Check if auth cookies are present266const cookies = await context.cookies();267const authCookie = cookies.find((c) => c.name.includes("session"));268console.log("Auth cookie:", authCookie ? "present" : "MISSING");269270await page.goto("/protected");271272// Check if redirected to login (auth failed)273if (page.url().includes("/login")) {274console.error("Auth failed - redirected to login");275// Save state for inspection276await context.storageState({ path: "debug-auth.json" });277}278});279```280281## Debugging Screenshots282283### Compare Visual State284285```typescript286test("visual debug", async ({ page }, testInfo) => {287await page.goto("/");288289// Screenshot before action290await page.screenshot({291path: testInfo.outputPath("before.png"),292fullPage: true,293});294295await page.getByRole("button", { name: "Open Menu" }).click();296297// Screenshot after action298await page.screenshot({299path: testInfo.outputPath("after.png"),300fullPage: true,301});302303// Attach to report304await testInfo.attach("before", {305path: testInfo.outputPath("before.png"),306contentType: "image/png",307});308});309```310311### Screenshot Specific Element312313```typescript314test("element screenshot", async ({ page }) => {315await page.goto("/");316317const element = page.getByTestId("problem-area");318319// Screenshot just the element320await element.screenshot({ path: "element-debug.png" });321322// Highlight element in full page screenshot323await element.evaluate((el) => (el.style.border = "3px solid red"));324await page.screenshot({ path: "highlighted.png" });325});326```327328## Common Issues329330### Element Not Found331332```typescript333// Debug: Check if element exists334console.log(await page.getByRole("button").count());335336// Debug: Log all buttons337const buttons = await page.getByRole("button").all();338for (const button of buttons) {339console.log(await button.textContent());340}341342// Debug: Screenshot before action343await page.screenshot({ path: "debug.png" });344await page.getByRole("button").click();345```346347### Timeout Issues348349```typescript350// Increase timeout for slow operations351await expect(page.getByText("Loaded")).toBeVisible({ timeout: 30000 });352353// Global timeout increase354test.setTimeout(60000);355356// Check what's blocking357test("debug timeout", async ({ page }) => {358await page.goto("/slow-page");359360// Log network activity361page.on("request", (request) => console.log(">>", request.url()));362page.on("response", (response) =>363console.log("<<", response.url(), response.status()),364);365});366```367368### Selector Issues369370```typescript371// Debug: Highlight element372await page.getByRole("button").highlight();373374// Debug: Evaluate selector in browser console375// Run in Inspector console:376// playwright.locator('button').first().highlight()377378// Debug: Get element info379const element = page.getByRole("button");380console.log("Count:", await element.count());381console.log("Visible:", await element.isVisible());382console.log("Enabled:", await element.isEnabled());383```384385### Frame Issues386387```typescript388// Debug: List all frames389for (const frame of page.frames()) {390console.log("Frame:", frame.url());391}392393// Debug: Check if element is in iframe394const frame = page.frameLocator("iframe").first();395console.log(await frame.getByRole("button").count());396```397398## Logging399400### Capture Browser Console401402```typescript403test("with logging", async ({ page }) => {404page.on("console", (msg) => console.log("Browser:", msg.text()));405page.on("pageerror", (error) => console.log("Page error:", error.message));406await page.goto("/");407});408```409410> **For comprehensive console error handling** (fail on errors, allowed patterns, fixtures), see [console-errors.md](console-errors.md).411412### Custom Test Attachments413414```typescript415test("with attachments", async ({ page }, testInfo) => {416// Attach screenshot to report417const screenshot = await page.screenshot();418await testInfo.attach("screenshot", {419body: screenshot,420contentType: "image/png",421});422423// Attach logs or data424await testInfo.attach("logs", {425body: "Custom log data",426contentType: "text/plain",427});428429// Use testInfo for output paths430const outputPath = testInfo.outputPath("debug-file.json");431});432```433434## Troubleshooting Checklist435436### By Symptom437438| Symptom | Common Causes | Quick Fixes | Reference |439| --------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------- | -------------------------------------------------------------------------- |440| **Element not found** | Wrong selector, element not visible, in iframe, timing issue | Check locator with Inspector, wait for visibility, use frameLocator | [locators.md](../core/locators.md), [assertions-waiting.md](../core/assertions-waiting.md) |441| **Timeout errors** | Slow network, heavy page load, waiting for wrong condition | Increase timeout, wait for specific response, check network tab | [assertions-waiting.md](../core/assertions-waiting.md) |442| **Flaky tests** | Race conditions, shared state, timing dependencies | See comprehensive flaky test guide | [flaky-tests.md](flaky-tests.md) |443| **Tests pass locally, fail in CI** | Environment differences, missing dependencies, timing | Simulate CI locally, check CI logs, verify environment vars | [ci-cd.md](../infrastructure-ci-cd/ci-cd.md), [flaky-tests.md](flaky-tests.md) |444| **Slow test execution** | Not parallelized, heavy network calls, unnecessary waits | Enable parallelization, mock APIs, optimize waits | [performance.md](../infrastructure-ci-cd/performance.md) |445| **Selector works in browser but not in test** | Element not attached, wrong context, dynamic content | Use auto-waiting, check iframe, verify element state | [locators.md](../core/locators.md) |446| **Test fails on retry** | Non-deterministic data, external dependencies | Use test data fixtures, mock external services | [fixtures-hooks.md](../core/fixtures-hooks.md) |447448### Step-by-Step Debugging Process4494501. **Reproduce the issue**451452```bash453# Run with trace enabled454npx playwright test tests/failing.spec.ts --trace on455456# If intermittent, run multiple times457npx playwright test --repeat-each=10458```4594602. **Inspect the failure**461462```bash463# View trace464npx playwright show-trace test-results/path-to-trace.zip465466# Run in headed mode to watch467npx playwright test --headed468469# Use inspector for step-by-step470PWDEBUG=1 npx playwright test471```4724733. **Isolate the problem**474475```typescript476// Add debugging points477await page.pause();478479// Log element state480console.log("Element count:", await page.getByRole("button").count());481console.log("Element visible:", await page.getByRole("button").isVisible());482483// Take screenshot at failure point484await page.screenshot({ path: "debug.png" });485```4864874. **Check related areas**488- Network requests: Are API calls completing? (see [Debugging Network Issues](#debugging-network-issues))489- Timing: Is auto-waiting working correctly?490- State: Is the test isolated? (see [flaky-tests.md](flaky-tests.md))491- Environment: Does it work locally but fail in CI? (see [Debugging in CI](#debugging-in-ci))4924935. **Apply fix and verify**494- Fix the root cause (not just symptoms)495- Run multiple times to confirm stability: `--repeat-each=10`496- Check related tests aren't affected497498## Related References499500- **Flaky tests**: See [flaky-tests.md](flaky-tests.md) for comprehensive flaky test guide501- **Locator issues**: See [locators.md](../core/locators.md) for selector strategies502- **Waiting problems**: See [assertions-waiting.md](../core/assertions-waiting.md) for waiting patterns503- **Test isolation**: See [fixtures-hooks.md](../core/fixtures-hooks.md) for fixtures and isolation504- **CI issues**: See [ci-cd.md](../infrastructure-ci-cd/ci-cd.md) for CI configuration505