home / skills / dyad-sh / dyad / debug-with-playwright

debug-with-playwright skill

/.claude/skills/debug-with-playwright

This skill helps you debug E2E tests by capturing targeted Playwright screenshots to visually inspect app state during failures.

npx playbooks add skill dyad-sh/dyad --skill debug-with-playwright

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.3 KB
---
name: dyad:debug-with-playwright
description: Debug E2E tests by taking screenshots at key points to visually inspect application state.
---

# Debug with Playwright Screenshots

Debug E2E tests by taking screenshots at key points to visually inspect application state.

## Arguments

- `$ARGUMENTS`: (Optional) Specific E2E test file to debug (e.g., `main.spec.ts` or `e2e-tests/main.spec.ts`). If not provided, will ask the user which test to debug.

## Background

Dyad uses Electron + Playwright for E2E tests. Because Playwright's built-in `screenshot: "on"` option does NOT work with Electron (see https://github.com/microsoft/playwright/issues/8208), you must take screenshots manually via `page.screenshot()`.

The test fixtures in `e2e-tests/helpers/fixtures.ts` already auto-capture a screenshot on test failure and attach it to the test report. But for debugging, you often need screenshots at specific points during test execution.

## Instructions

1. **Identify the test to debug:**

   If `$ARGUMENTS` is empty, ask the user which test file they want to debug.
   - If provided without the `e2e-tests/` prefix, add it
   - If provided without the `.spec.ts` suffix, add it

2. **Read the test file:**

   Read the test file to understand what it does and where it might be failing.

3. **Add debug screenshots to the test:**

   Add `page.screenshot()` calls at key points in the test to capture visual state. Access the page from the `po` fixture:

   ```typescript
   // Get the page from the electronApp fixture
   const page = await electronApp.firstWindow();

   // Or if you only have `po`, access the page directly:
   // po is a PageObject which has a `page` property
   ```

   **Screenshot patterns for debugging:**

   ```typescript
   import * as fs from "fs";
   import * as path from "path";

   // Create a debug screenshots directory
   const debugDir = path.join(__dirname, "debug-screenshots");
   if (!fs.existsSync(debugDir)) {
     fs.mkdirSync(debugDir, { recursive: true });
   }

   // Take a full-page screenshot
   await page.screenshot({
     path: path.join(debugDir, "01-before-action.png"),
   });

   // Take a screenshot of a specific element
   const element = page.locator('[data-testid="chat-input"]');
   await element.screenshot({
     path: path.join(debugDir, "02-chat-input.png"),
   });

   // Take a screenshot after some action
   await po.sendPrompt("hi");
   await page.screenshot({
     path: path.join(debugDir, "03-after-send.png"),
   });
   ```

   **Important:** The test fixture signature provides `{ electronApp, po }`. To get the page:
   - Use `await electronApp.firstWindow()` to get the page
   - Or use `po.page` if PageObject exposes it

   Add screenshots before and after the failing step to understand what the UI looks like at that point.

4. **Build the app (if needed):**

   E2E tests run against the built binary. If you made any application code changes:

   ```
   npm run build
   ```

   If you only changed test files, you can skip this step.

5. **Run the test:**

   ```
   PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_HTML_OPEN=never npm run e2e -- e2e-tests/<testfile>.spec.ts
   ```

6. **View the screenshots:**

   Use the Read tool to view the captured PNG screenshots. Claude Code can read and display images directly:

   ```
   Read the PNG files in e2e-tests/debug-screenshots/
   ```

   Analyze the screenshots to understand:
   - Is the expected UI element visible?
   - Is there an error dialog or unexpected state?
   - Is a loading spinner still showing?
   - Is the layout correct?

7. **Check the Playwright trace (for additional context):**

   The Playwright config has `trace: "retain-on-failure"`. If the test failed, a trace file will be in `test-results/`. You can reference this for additional debugging context.

8. **Iterate:**

   Based on what you see in the screenshots:
   - Add more targeted screenshots if needed
   - Fix the issue in the test or application code
   - Re-run to verify

9. **Clean up:**

   After debugging is complete, remove the debug screenshots and any temporary screenshot code you added to the test:

   ```
   rm -rf e2e-tests/debug-screenshots/
   ```

   Remove any `page.screenshot()` calls you added for debugging purposes.

10. **Report findings:**

    Tell the user:
    - What the screenshots revealed about the test failure
    - What fix was applied (if any)
    - Whether the test now passes

Overview

This skill helps debug end-to-end Playwright tests by inserting manual screenshots at strategic points so you can visually inspect application state. It guides adding page.screenshot() calls, running the test, viewing images, and iterating until the failure is understood and resolved. It focuses on Electron + Playwright specifics where automatic screenshot capture may not work.

How this skill works

The skill inspects the specified E2E test file, suggests where to add manual screenshots, and provides code snippets to create a debug-screenshots directory and call page.screenshot() or element.screenshot(). It explains how to obtain the Playwright page from the test fixtures (electronApp.firstWindow() or po.page), run the built test binary, and review the generated PNG files and Playwright trace for context.

When to use it

  • A flaky or failing E2E test where logs don’t reveal the UI state
  • When Playwright’s built-in screenshot-on-failure isn’t available for Electron
  • To capture UI before and after a specific action to compare states
  • During iterative debugging of layout, visibility, or spinner/loading issues
  • When you need visual evidence to report a bug or confirm a fix

Best practices

  • Always get the page via electronApp.firstWindow() or use po.page when available
  • Create a dedicated debug-screenshots directory under the test folder and commit nothing from it
  • Capture screenshots before and after the suspected failing step to compare states
  • Prefer element.screenshot() for focused debugging and full-page screenshots for overall layout
  • Remove debug screenshots and screenshot calls after the issue is resolved to keep tests clean

Example use cases

  • Debug a chat input that appears empty after sending a message by capturing before-send and after-send screenshots
  • Investigate a modal that blocks interactions by capturing the page when the modal should be closed
  • Verify layout regressions across screen sizes by saving full-page screenshots during the test
  • Diagnose a spinner that never disappears by capturing the element and surrounding UI at several timestamps
  • Provide visual evidence of a failing flow when filing an issue or code review

FAQ

What if the test fixture doesn’t expose electronApp or po?

Confirm the test uses the expected fixtures. If not, add or adapt a fixture to obtain the Electron page or create a page handle via the Playwright API available in your test environment.

Do I need to rebuild the app after adding screenshots?

Only if you changed application code. Adding or removing test-only screenshot calls does not require rebuilding the app binary.