Integrations

Playwright MCP

Autonomous app verification and exploration

Playwright MCP Integration

Browser automation via Model Context Protocol for Claude Code.

Overview

Playwright MCP provides browser automation tools directly to Claude through the Model Context Protocol. The AI uses Playwright MCP to autonomously explore and verify application behavior - not just run scripts, but actively investigate and understand the app.

Key capabilities:

  • Autonomous verification - AI explores the app to understand failures
  • Control browsers conversationally
  • Take screenshots and inspect pages
  • Fill forms and click elements
  • Navigate and interact with web content

Auto-Installation

Triqual automatically installs Playwright MCP via .mcp.json:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

No manual setup required - the server starts automatically when needed.

Available Tools

Navigation

ToolDescription
browser_navigateNavigate to a URL
browser_navigate_backGo back in history
browser_tabsList, create, close, or select tabs

Interaction

ToolDescription
browser_clickClick on an element
browser_typeType text into an element
browser_fill_formFill multiple form fields
browser_select_optionSelect dropdown option
browser_hoverHover over element
browser_dragDrag and drop
browser_press_keyPress keyboard key

Inspection

ToolDescription
browser_snapshotGet accessibility tree (preferred)
browser_take_screenshotCapture visual screenshot
browser_console_messagesRead console logs
browser_network_requestsView network activity

Execution

ToolDescription
browser_evaluateExecute JavaScript on page
browser_run_codeRun Playwright code snippet
browser_wait_forWait for text or condition

File Operations

ToolDescription
browser_file_uploadUpload files
browser_handle_dialogHandle alerts/confirms

Playwright MCP vs Script Execution

When to Use Playwright MCP

  • Ad-hoc exploration: Quick page inspection
  • Conversational testing: "Click the login button"
  • Debugging: Inspect page state interactively
  • Form filling: Guided multi-step workflows
User: Check if the login page works
Claude: [Uses browser_navigate, browser_snapshot, browser_fill_form, browser_click]

When to Use Script Execution

  • Repeatable tests: Tests that run in CI/CD
  • Complex flows: Multi-page transactions
  • Performance testing: Consistent timing
  • Production test files: .spec.ts files
# Use /test for script-based testing
cd ${CLAUDE_PLUGIN_ROOT}/lib && node run.js /tmp/test.js

Integration with Triqual Skills

/test (Default Mode)

Uses Playwright MCP for exploration and script execution for:

  • Autonomous test generation
  • Running custom test code
  • Consistent, repeatable automation
  • Screenshot workflows
  • Local development testing

/test --explore

Uses Playwright MCP directly for:

  • Interactive browser exploration
  • Real-time debugging
  • Understanding UI before writing tests

/test --ticket

Uses script execution to:

  • Generate production test files
  • Follow project patterns
  • Create Page Objects
  • Integrate with CI/CD

Manual MCP Usage

For ad-hoc exploration, use MCP tools directly:

User: Navigate to localhost:3000 and take a screenshot

Claude: [Uses browser_navigate to localhost:3000]
        [Uses browser_take_screenshot]
        Here's the screenshot of your homepage...

Autonomous Verification

The most powerful use of Playwright MCP is autonomous app exploration for failure diagnosis.

Failure Investigation Workflow

When a test fails, the AI can autonomously:

  1. Navigate to the failing page:

    browser_navigate({ url: "http://localhost:3000/login" })
    
  2. Inspect the current state:

    browser_snapshot({})
    // See what elements are actually present
    
  3. Compare expected vs actual:

    • Is the element present but with different text?
    • Is the page in an unexpected state?
    • Are there error messages visible?
  4. Test the actual behavior:

    browser_fill_form({
      fields: [
        { name: "Email", type: "textbox", ref: "ref_1", value: "test@example.com" }
      ]
    })
    browser_click({ ref: "ref_2", element: "Submit button" })
    
  5. Verify the outcome:

    browser_snapshot({})
    // Did it navigate? Show error? Succeed?
    

Test Credentials

For authenticated flows, the AI uses test credentials to:

  • Log in as test users
  • Access protected pages
  • Verify user-specific behavior
  • Test permission boundaries

Note: Store test credentials in environment variables or Quoth patterns, not in code.

Integration with Failure Diagnosis

┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│   Test      │         │  Playwright │         │   Exolar    │
│  Failure    │────────▶│    MCP      │◀────────│  History    │
│             │         │  (Verify)   │         │  (Context)  │
└─────────────┘         └─────────────┘         └─────────────┘
        │                      │
        │                      ▼
        │               ┌─────────────┐
        └──────────────▶│ Diagnosis   │
                        │ (BUG/FLAKE) │
                        └─────────────┘
  1. Fetch history from Exolar - Is this a known issue?
  2. Explore with Playwright MCP - What's the actual state?
  3. Compare and classify - BUG, FLAKE, ENV, or TEST_ISSUE?
  4. Take action - Fix test or create ticket

Example: Debugging a Timeout

AI: The test failed with "Timeout waiting for selector '#submit-btn'"

Let me investigate...

[browser_navigate to the page]
[browser_snapshot to see current state]

I can see the page loaded, but the button has id="submitBtn" not "#submit-btn".
This appears to be a TEST_BUG - the selector is incorrect.

Recommendation: Update the test to use the correct selector.

Best Practices

Use Snapshots Over Screenshots

// Preferred - returns accessibility tree
browser_snapshot({})

// Visual only - harder for Claude to parse
browser_take_screenshot({ type: "png" })

Wait for Page Load

// Navigate then wait
browser_navigate({ url: "https://example.com" })
browser_wait_for({ text: "Welcome" })

Use Refs from Snapshots

// Get snapshot first
browser_snapshot({})
// Returns refs like "ref_1", "ref_2"

// Then interact using refs
browser_click({ ref: "ref_1", element: "Login button" })

Troubleshooting

IssueSolution
Browser not installedRun browser_install tool
MCP not connectedCheck /mcp and reconnect
Element not foundUse browser_snapshot to see available refs
Timeout errorsUse browser_wait_for before interactions

Comparison Table

FeaturePlaywright MCPScript Execution
SetupAuto-installedRequires npm install
InteractionConversationalProgrammatic
RepeatabilityAd-hocConsistent
CI/CDNot suitableProduction-ready
DebuggingInteractiveLog-based
Best forExplorationTest automation