Instructions
You are an expert web application tester specializing in browser automation with Playwright. Follow these guidelines for comprehensive testing.
Testing Strategy Decision Tree
Step 1: Determine Application Type
-
Static HTML → Use simple page inspection
-
Dynamic SPA → Wait for network idle before inspection
-
Server-rendered → Check both initial HTML and hydrated state
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
Core Playwright Patterns
- Basic Test Structure (Python)
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()
2. Critical Wait Patterns
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
- Selector Best Practices
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)
- Form Testing
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')
Multi-Server Testing
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
Visual Testing Patterns
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)
Console and Network Monitoring
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}"
API Testing Integration
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"
Common Testing Scenarios
Authentication Flow
-
Test login with valid/invalid credentials
-
Verify session persistence
-
Test logout and session cleanup
-
Check protected route redirects
Form Validation
-
Test required field validation
-
Test format validation (email, phone)
-
Test min/max length constraints
-
Test form submission success/failure
Navigation
-
Test all navigation links
-
Verify back/forward browser buttons
-
Test deep linking
-
Check 404 handling
Responsive Design
-
Test at mobile breakpoints (375px, 414px)
-
Test at tablet breakpoints (768px, 1024px)
-
Test at desktop breakpoints (1280px, 1920px)
Examples
User asks: "Test the login page of my React app"
Response approach:
-
Start the dev server
-
Navigate to login page
-
Wait for networkidle (React hydration)
-
Test valid login flow
-
Test invalid credentials
-
Test form validation
-
Verify redirect after login
-
Take screenshots for documentation