Claude-skill-registry dev-test-playwright
Playwright MCP browser testing. Headless E2E, cross-browser, CI/CD automation.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dev-test-playwright" ~/.claude/skills/majiayu000-claude-skill-registry-dev-test-playwright && rm -rf "$T"
skills/data/dev-test-playwright/SKILL.mdAnnounce: "I'm using dev-test-playwright for headless browser automation."
<EXTREMELY-IMPORTANT> ## Gate ReminderBefore taking screenshots or running E2E tests, you MUST complete all 6 gates from dev-tdd:
GATE 1: BUILD GATE 2: LAUNCH (with file-based logging) GATE 3: WAIT GATE 4: CHECK PROCESS GATE 5: READ LOGS ← MANDATORY, CANNOT SKIP GATE 6: VERIFY LOGS THEN: E2E tests/screenshots
You loaded dev-tdd earlier. Follow the gates now. </EXTREMELY-IMPORTANT>
Contents
- Tool Availability Gate
- When to Use Playwright MCP
- MCP Tools Overview
- Navigation
- Element Interaction
- Verification
- Form Handling
- Advanced Patterns
- Complete E2E Examples
Playwright MCP Browser Automation
<EXTREMELY-IMPORTANT> ## Tool Availability GateVerify Playwright MCP tools are available before proceeding.
Check for these MCP functions:
mcp__playwright__browser_navigatemcp__playwright__browser_snapshotmcp__playwright__browser_click
If MCP tools are not available:
STOP: Cannot proceed with Playwright automation. Missing: Playwright MCP server The Playwright MCP server must be configured and running. Check your Claude Code MCP configuration. Reply when configured and I'll continue testing.
This gate is non-negotiable. Missing tools = full stop. </EXTREMELY-IMPORTANT>
<EXTREMELY-IMPORTANT> ## When to Use Playwright MCPUSE Playwright MCP when you need:
- Headless browser automation (CI/CD)
- Cross-browser testing (Chromium, Firefox, WebKit)
- Test isolation (fresh browser state per test)
- Standard E2E test suite automation
- Network mocking/interception
- Parallel test execution
DO NOT use Playwright MCP when:
- Debugging console messages (use Chrome MCP)
- Inspecting network requests/responses (use Chrome MCP)
- Executing custom JavaScript in page (use Chrome MCP)
- Recording GIFs of interactions (use Chrome MCP)
- Interactive debugging with real browser (use Chrome MCP)
For debugging, use:
Read("${CLAUDE_PLUGIN_ROOT}/lib/skills/dev-test-chrome/SKILL.md")
Rationalization Prevention
| Thought | Reality |
|---|---|
| "Playwright can do everything" | NO. It cannot read console or network requests. |
| "I don't need console debugging" | You will. Start with Chrome MCP if unsure. |
| "I'll add console checks later" | You can't with Playwright. Choose the right tool now. |
| "Headless mode doesn't matter" | YES IT DOES for CI/CD. |
| "Chrome MCP works for CI" | NO. It requires visible browser. |
Capability Comparison
| Capability | Playwright MCP | Chrome MCP |
|---|---|---|
| Navigate/click/type | ✅ | ✅ |
| Accessibility tree | ✅ | ✅ |
| Screenshots | ✅ | ✅ |
| Headless mode | ✅ | ❌ |
| Cross-browser | ✅ | ❌ |
| Console messages | ❌ | ✅ |
| Network requests | ❌ | ✅ |
| JavaScript execution | ❌ | ✅ |
| GIF recording | ❌ | ✅ |
MCP Tools Overview
| Tool | Purpose |
|---|---|
| Navigate to URL |
| Get accessibility tree (page state) |
| Click elements |
| Type into inputs |
| Select dropdown options |
| Hover over elements |
| Wait for conditions |
| Visual capture |
| Press keys |
Navigation
Basic Navigation
mcp__playwright__browser_navigate(url="https://example.com")
Wait for Page Load
mcp__playwright__browser_navigate(url="https://example.com") mcp__playwright__browser_wait_for(state="networkidle")
Get Current State
mcp__playwright__browser_snapshot()
The snapshot returns the accessibility tree - a structured representation of all interactive elements on the page.
Element Interaction
Clicking Elements
# By visible text mcp__playwright__browser_click(element="Submit button") # By ref (from snapshot) mcp__playwright__browser_click(ref="button[type=submit]") # By role and name mcp__playwright__browser_click(element="Login", role="button")
Typing Text
# Into focused element mcp__playwright__browser_type(text="hello world") # Into specific element mcp__playwright__browser_click(element="Email input") mcp__playwright__browser_type(text="user@example.com") # Clear and type mcp__playwright__browser_click(element="Search box") mcp__playwright__browser_type(text="new search", clear=true)
Keyboard Shortcuts
# Press Enter mcp__playwright__browser_press(key="Enter") # Keyboard shortcuts mcp__playwright__browser_press(key="Control+a") mcp__playwright__browser_press(key="Control+c")
Verification
<EXTREMELY-IMPORTANT> ### The Iron Law of VerificationEVERY action must be VERIFIED. Taking action is not enough.
After clicking, typing, or navigating, you MUST:
- Wait for the expected result
- Take a snapshot to verify state
- Document the verification in LEARNINGS.md
| Action | Verification |
|---|---|
| Click submit | + snapshot |
| Navigate | + snapshot |
| Fill form | Snapshot shows filled values |
| Login | Snapshot shows dashboard/logged-in state |
"I clicked it" is not verification. Prove the click worked. </EXTREMELY-IMPORTANT>
Snapshot Verification
# 1. Perform action mcp__playwright__browser_click(element="Submit") # 2. Wait for result mcp__playwright__browser_wait_for(text="Success") # 3. Take snapshot to verify mcp__playwright__browser_snapshot() # Check snapshot contains expected elements
Wait Conditions
# Wait for text to appear mcp__playwright__browser_wait_for(text="Welcome back") # Wait for element mcp__playwright__browser_wait_for(selector="#success-message") # Wait for network idle mcp__playwright__browser_wait_for(state="networkidle") # Wait for navigation mcp__playwright__browser_wait_for(state="load")
Screenshots
# Full page mcp__playwright__browser_take_screenshot(path="/tmp/screenshot.png", fullPage=true) # Viewport only mcp__playwright__browser_take_screenshot(path="/tmp/viewport.png") # Specific element mcp__playwright__browser_take_screenshot( path="/tmp/element.png", selector="#main-content" )
Form Handling
Text Inputs
mcp__playwright__browser_click(element="Username") mcp__playwright__browser_type(text="john_doe") mcp__playwright__browser_click(element="Password") mcp__playwright__browser_type(text="secret123")
Dropdowns
mcp__playwright__browser_select_option( element="Country dropdown", value="US" ) # Or by label mcp__playwright__browser_select_option( element="Country", label="United States" )
Checkboxes and Radio Buttons
# Check checkbox mcp__playwright__browser_click(element="Accept terms checkbox") # Verify checked state (via snapshot) mcp__playwright__browser_snapshot() # Look for checked="true" in accessibility tree
File Upload
mcp__playwright__browser_set_input_files( selector="input[type=file]", files=["/path/to/file.pdf"] )
Advanced Patterns
Multi-Step Form
# Step 1 mcp__playwright__browser_click(element="Name input") mcp__playwright__browser_type(text="John Doe") mcp__playwright__browser_click(element="Next button") mcp__playwright__browser_wait_for(text="Step 2") # Step 2 mcp__playwright__browser_click(element="Email input") mcp__playwright__browser_type(text="john@example.com") mcp__playwright__browser_click(element="Next button") mcp__playwright__browser_wait_for(text="Step 3") # Step 3 - Submit mcp__playwright__browser_click(element="Submit button") mcp__playwright__browser_wait_for(text="Success")
Handling Modals
# Click to open modal mcp__playwright__browser_click(element="Open Dialog") mcp__playwright__browser_wait_for(text="Dialog Title") # Interact with modal mcp__playwright__browser_click(element="Confirm button") mcp__playwright__browser_wait_for(state="hidden", selector=".modal")
Iframes
# Switch to iframe mcp__playwright__browser_frame(name="payment-iframe") # Interact within iframe mcp__playwright__browser_click(element="Card number") mcp__playwright__browser_type(text="4111111111111111") # Switch back to main mcp__playwright__browser_main_frame()
Hover and Tooltips
mcp__playwright__browser_hover(element="Help icon") mcp__playwright__browser_wait_for(text="This is the tooltip text") mcp__playwright__browser_snapshot()
Complete E2E Examples
Login Flow
# 1. Navigate to login page mcp__playwright__browser_navigate(url="https://app.example.com/login") mcp__playwright__browser_wait_for(state="networkidle") # 2. Take initial snapshot mcp__playwright__browser_snapshot() # Verify: Login form is visible # 3. Fill credentials mcp__playwright__browser_click(element="Email") mcp__playwright__browser_type(text="user@example.com") mcp__playwright__browser_click(element="Password") mcp__playwright__browser_type(text="password123") # 4. Submit mcp__playwright__browser_click(element="Sign In") mcp__playwright__browser_wait_for(text="Dashboard") # 5. Verify success mcp__playwright__browser_snapshot() # Verify: Dashboard is visible, user name shown # 6. Screenshot for evidence mcp__playwright__browser_take_screenshot(path="/tmp/login_success.png")
E-Commerce Checkout
# 1. Navigate to product mcp__playwright__browser_navigate(url="https://shop.example.com/product/123") mcp__playwright__browser_wait_for(state="networkidle") # 2. Add to cart mcp__playwright__browser_click(element="Add to Cart") mcp__playwright__browser_wait_for(text="Added to cart") # 3. Go to cart mcp__playwright__browser_click(element="Cart icon") mcp__playwright__browser_wait_for(text="Your Cart") # 4. Verify cart mcp__playwright__browser_snapshot() # Verify: Product in cart, correct price # 5. Proceed to checkout mcp__playwright__browser_click(element="Checkout") mcp__playwright__browser_wait_for(text="Shipping Address") # 6. Fill shipping mcp__playwright__browser_click(element="Address") mcp__playwright__browser_type(text="123 Main St") mcp__playwright__browser_click(element="City") mcp__playwright__browser_type(text="New York") mcp__playwright__browser_select_option(element="State", value="NY") mcp__playwright__browser_click(element="Zip") mcp__playwright__browser_type(text="10001") # 7. Continue to payment mcp__playwright__browser_click(element="Continue to Payment") mcp__playwright__browser_wait_for(text="Payment Method") # 8. Verify order summary mcp__playwright__browser_snapshot() # Verify: Correct items, shipping address, total mcp__playwright__browser_take_screenshot(path="/tmp/checkout_complete.png")
Search and Filter
# 1. Navigate mcp__playwright__browser_navigate(url="https://search.example.com") # 2. Search mcp__playwright__browser_click(element="Search box") mcp__playwright__browser_type(text="laptop") mcp__playwright__browser_press(key="Enter") mcp__playwright__browser_wait_for(text="results") # 3. Apply filter mcp__playwright__browser_click(element="Price filter") mcp__playwright__browser_click(element="Under $1000") mcp__playwright__browser_wait_for(state="networkidle") # 4. Verify filtered results mcp__playwright__browser_snapshot() # Verify: Results shown, filter applied # 5. Click first result mcp__playwright__browser_click(element="First product link") mcp__playwright__browser_wait_for(text="Product Details") mcp__playwright__browser_take_screenshot(path="/tmp/search_result.png")
Error Handling
Retry Pattern
# Attempt action with retry for attempt in range(3): try: mcp__playwright__browser_click(element="Flaky Button") mcp__playwright__browser_wait_for(text="Success", timeout=5000) break # Success except: if attempt == 2: raise # Give up after 3 attempts time.sleep(1) # Wait before retry
Timeout Handling
# Set explicit timeout mcp__playwright__browser_wait_for( text="Slow loading content", timeout=30000 # 30 seconds )
Limitations
<EXTREMELY-IMPORTANT> ### What Playwright MCP Cannot Do| Need | Why Playwright Fails | Use Instead |
|---|---|---|
| Read console.log | No console access | Chrome MCP |
| Inspect API responses | No network access | Chrome MCP |
| Execute page JavaScript | No JS execution | Chrome MCP |
| Record GIF | No recording capability | Chrome MCP |
If you need debugging capabilities, switch to Chrome MCP. </EXTREMELY-IMPORTANT>
Integration
This skill is referenced by
dev-test for Playwright browser automation.
For debugging (console/network), use:
Read("${CLAUDE_PLUGIN_ROOT}/lib/skills/dev-test-chrome/SKILL.md")
For TDD protocol, see:
Skill(skill="workflows:dev-tdd")