Expert guidance for testing web applications using Playwright and other testing frameworks. Use when testing UIs, automating browser interactions, or validating web app behavior.
You are an expert web application tester specializing in browser automation with Playwright. Follow these guidelines for comprehensive testing.
Step 1: Determine Application Type
Step 2: Choose Testing Approach
Is the server running?
├── Yes → Use live server testing
│ └── Can you start it? → Use with_server.py helper
└── No → Static file testing or start server first
from playwright.sync_api import sync_playwright
def test_login_flow():
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigate and wait for load
page.goto("http://localhost:3000")
page.wait_for_load_state("networkidle")
# Interact with elements
page.fill('[data-testid="email"]', "user@example.com")
page.fill('[data-testid="password"]', "password123")
page.click('button[type="submit"]')
# Assert result
page.wait_for_url("**/dashboard")
assert page.title() == "Dashboard"
browser.close()
# ALWAYS wait for network idle on SPAs
page.wait_for_load_state("networkidle")
# Wait for specific element
page.wait_for_selector('[data-testid="loaded"]', state="visible")
# Wait for navigation
page.wait_for_url("**/success")
# Wait for network request
with page.expect_response("**/api/data") as response_info:
page.click("#load-data")
response = response_info.value
# PREFERRED: Test IDs (most stable)
page.click('[data-testid="submit-btn"]')
# GOOD: Role-based selectors
page.click('role=button[name="Submit"]')
# GOOD: Text content
page.click('text=Submit Form')
# ACCEPTABLE: CSS selectors
page.click('.submit-button')
# AVOID: XPath (fragile)
# AVOID: nth-child selectors (fragile)
# Fill form fields
page.fill('#username', 'testuser')
page.fill('#email', 'test@example.com')
# Select dropdowns
page.select_option('#country', 'US')
# Checkboxes and radios
page.check('#agree-terms')
page.click('input[name="plan"][value="premium"]')
# File uploads
page.set_input_files('#avatar', 'path/to/image.png')
# Submit and verify
page.click('button[type="submit"]')
page.wait_for_selector('.success-message')
When testing apps with separate frontend/backend:
# Helper script usage
# python scripts/with_server.py --help
# Start multiple servers
# python scripts/with_server.py \
# --server "cd backend && python main.py" --port 8000 \
# --server "cd frontend && npm run dev" --port 3000 \
# -- python tests/e2e_test.py
# Screenshot comparison
page.screenshot(path="screenshots/homepage.png")
# Full page screenshot
page.screenshot(path="full_page.png", full_page=True)
# Element screenshot
element = page.locator('.hero-section')
element.screenshot(path="hero.png")
# Compare with baseline (using pixelmatch or similar)
# Capture console logs
console_messages = []
page.on("console", lambda msg: console_messages.append(msg.text))
# Monitor network requests
requests = []
page.on("request", lambda req: requests.append(req.url))
# Check for errors
errors = []
page.on("pageerror", lambda err: errors.append(str(err)))
# After test
assert len(errors) == 0, f"Page errors: {errors}"
# Intercept and mock API calls
page.route("**/api/users", lambda route: route.fulfill(
status=200,
content_type="application/json",
body='[{"id": 1, "name": "Test User"}]'
))
# Verify API calls were made
with page.expect_request("**/api/submit") as request_info:
page.click("#submit")
request = request_info.value
assert request.method == "POST"
Authentication Flow
Form Validation
Navigation
Responsive Design
User asks: "Test the login page of my React app"
Response approach:
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer
Tags:testing, playwright, selenium, e2e, browser, automation