| name | webapp-testing |
| description | Professional web application testing and automation using Playwright with support for multiple browsers, mobile emulation, screenshot capture, network interception, and comprehensive test assertions. Use for: (1) E2E testing across browsers, (2) UI automation, (3) Form testing and validation, (4) Visual regression testing, (5) API mocking and interception, (6) Mobile responsive testing |
Web Application Testing with Playwright
Overview
Playwright is a powerful framework for web testing and automation that supports all modern browsers (Chromium, Firefox, WebKit). It provides reliable, fast, and capable automation with auto-waiting, network control, and comprehensive testing capabilities.
Use this skill when you need to:
- Create end-to-end tests for web applications
- Automate browser interactions and workflows
- Test across multiple browsers and devices
- Verify UI/UX functionality and accessibility
- Mock APIs and intercept network requests
- Capture screenshots and videos for debugging
Core Capabilities
Multi-Browser Testing
- Chromium (Chrome, Edge, Brave)
- Firefox (Mozilla Firefox)
- WebKit (Safari engine)
- Cross-browser compatibility testing
- Parallel execution across browsers
Element Interaction
- Click, double-click, right-click
- Type text with realistic keyboard simulation
- Select dropdowns and checkboxes
- Hover and focus interactions
- Drag and drop operations
- File uploads and downloads
Assertions & Verification
- Element visibility and state checks
- Text content verification
- Attribute validation
- URL and navigation assertions
- Custom expect matchers
- Soft assertions for multiple checks
Screenshot & Video Capture
- Full page screenshots
- Element-specific captures
- Video recording of test sessions
- Visual comparison testing
- Trace files for debugging
Network Interception
- Mock API responses
- Intercept and modify requests
- Monitor network traffic
- Test offline scenarios
- Performance monitoring
Mobile Device Emulation
- 100+ device presets (iPhone, Pixel, iPad, etc.)
- Custom viewport configurations
- Touch event simulation
- Geolocation testing
- Orientation changes
Core Testing Workflow
1. Basic Test Setup
Create a simple test with Playwright's auto-waiting:
import pytest
from playwright.sync_api import Page, expect
def test_homepage_loads(page: Page):
"""Test that homepage loads successfully."""
page.goto("https://example.com")
expect(page).to_have_title("Example Domain")
expect(page.locator("h1")).to_contain_text("Example Domain")
def test_navigation(page: Page):
"""Test navigation between pages."""
page.goto("https://example.com")
page.click("text=More information")
expect(page).to_have_url("https://www.iana.org/domains/reserved")
2. Form Interactions
Test form filling, validation, and submission:
def test_login_form(page: Page):
"""Test login form submission."""
page.goto("https://example.com/login")
# Fill form fields
page.fill("#username", "testuser@example.com")
page.fill("#password", "SecurePassword123")
page.check("#remember-me")
# Submit and verify
page.click("button[type='submit']")
expect(page).to_have_url("https://example.com/dashboard")
expect(page.locator(".welcome-message")).to_be_visible()
3. API Mocking
Mock API responses for controlled testing:
def test_with_mocked_api(page: Page):
"""Test with mocked API response."""
# Mock API response
page.route("**/api/user", lambda route: route.fulfill(
status=200,
content_type="application/json",
body='{"name": "Test User", "premium": true}'
))
page.goto("https://example.com/profile")
expect(page.locator(".user-name")).to_contain_text("Test User")
4. Mobile Emulation
Test responsive designs on mobile devices:
@pytest.fixture
def mobile_page(playwright):
"""Create mobile browser context."""
iphone = playwright.devices['iPhone 12']
browser = playwright.chromium.launch()
context = browser.new_context(**iphone)
page = context.new_page()
yield page
context.close()
browser.close()
def test_mobile_menu(mobile_page: Page):
"""Test mobile navigation."""
mobile_page.goto("https://example.com")
expect(mobile_page.locator(".hamburger-menu")).to_be_visible()
mobile_page.click(".hamburger-menu")
expect(mobile_page.locator(".mobile-menu")).to_be_visible()
5. Visual Regression
Capture screenshots for visual comparison:
def test_homepage_screenshot(page: Page):
"""Capture homepage screenshot."""
page.goto("https://example.com")
# Full page screenshot
page.screenshot(path="screenshots/homepage.png", full_page=True)
# Element screenshot
page.locator("header").screenshot(path="screenshots/header.png")
# Screenshot with masks for dynamic content
page.screenshot(
path="screenshots/dashboard.png",
mask=[page.locator(".timestamp"), page.locator(".session-id")]
)
Key Testing Principles
Use Reliable Selectors
# ✅ GOOD: Test IDs and semantic selectors
page.click("[data-testid='submit-button']")
page.click("button:text('Submit')")
page.click("role=button[name='Submit']")
# ❌ BAD: Fragile structural selectors
page.click("div > div > button:nth-child(3)")
Leverage Auto-Waiting
# ✅ GOOD: Playwright auto-waits
page.click("button")
expect(page.locator(".result")).to_be_visible()
# ⚠️ Avoid: Manual waits
time.sleep(2) # Only when absolutely necessary
Ensure Test Isolation
# ✅ GOOD: Clean state between tests
@pytest.fixture(autouse=True)
def clear_state(page: Page):
yield
page.context.clear_cookies()
page.evaluate("localStorage.clear()")
Handle Flaky Tests
# ✅ GOOD: Wait for specific conditions
page.click("button")
page.wait_for_selector(".result")
result = page.locator(".result").text_content()
# ✅ GOOD: Use soft assertions
expect.soft(page.locator(".title")).to_be_visible()
expect.soft(page.locator(".price")).to_contain_text("$")
Page Object Model
Organize tests using the Page Object pattern for maintainability:
class LoginPage:
"""Login page object."""
def __init__(self, page: Page):
self.page = page
self.username_input = page.locator("#username")
self.password_input = page.locator("#password")
self.submit_button = page.locator("button[type='submit']")
def login(self, username: str, password: str):
"""Perform login."""
self.username_input.fill(username)
self.password_input.fill(password)
self.submit_button.click()
# Use in tests
def test_login(page: Page):
login_page = LoginPage(page)
login_page.login("test@example.com", "password123")
expect(page).to_have_url("/dashboard")
Common Test Patterns
Authentication
@pytest.fixture
def authenticated_page(page: Page):
"""Provide authenticated session."""
page.goto("https://example.com/login")
page.fill("#username", "test@example.com")
page.fill("#password", "password")
page.click("button[type='submit']")
page.wait_for_url("**/dashboard")
yield page
File Operations
# Upload
page.set_input_files("#file-input", "path/to/file.pdf")
# Download
with page.expect_download() as download_info:
page.click("a:text('Download')")
download = download_info.value
download.save_as("downloads/file.pdf")
Network Monitoring
requests = []
page.on("request", lambda req: requests.append(req))
page.goto("https://example.com")
# Verify API calls were made
api_requests = [r for r in requests if "/api/" in r.url]
assert len(api_requests) > 0
Running Tests
Basic Commands
# Install Playwright
pip install playwright pytest-playwright
playwright install
# Run all tests
pytest tests/
# Run specific browser
pytest --browser chromium --browser firefox
# Run in headed mode (see browser)
pytest --headed
# Debug mode
PWDEBUG=1 pytest tests/test_login.py
# Parallel execution
pytest -n auto
# Generate test code
playwright codegen https://example.com
Configuration
See references/setup-configuration.md for:
- Complete installation instructions
- Project structure setup
- pytest.ini configuration
- playwright.config.ts for TypeScript
- CI/CD integration examples
Quality Standards
Ensure tests meet these criteria:
- Tests are independent and can run in any order
- Selectors are reliable (test IDs, semantic selectors)
- Proper error handling and assertions
- Screenshots/videos captured on failure
- No hardcoded waits (use auto-waiting)
- Clean state management between tests
Additional Resources
Detailed Documentation
- Setup & Configuration - Installation, project structure, and configuration
- Best Practices - Selector strategies, wait patterns, flaky test prevention
- Common Pitfalls - Race conditions, selector brittleness, cleanup issues
- CI/CD Integration - GitHub Actions, Docker, deployment pipelines
Code Examples
- Login Testing - Authentication flows and session management
- Form Testing - Form validation, file uploads, dropdowns
- E-commerce Testing - Shopping cart, checkout flows, coupons
- API Mocking - Network interception, mocking, monitoring
- Mobile Testing - Device emulation, touch events, responsive design
- Page Object Model - POM pattern implementation
Helper Scripts
- Playwright Helper - Utility functions for common Playwright operations
- Test Examples - Complete test suite examples
External Resources
- Official Documentation: https://playwright.dev
- Python API: https://playwright.dev/python/docs/intro
- TypeScript API: https://playwright.dev/docs/intro
- Best Practices: https://playwright.dev/docs/best-practices
- Community Discord: https://aka.ms/playwright/discord
Troubleshooting
Tests are flaky:
- Use Playwright's auto-waiting instead of manual sleeps
- Ensure proper wait conditions (
wait_for_selector,wait_for_url) - Use
expect()assertions which auto-retry
Selectors not finding elements:
- Verify element exists with browser DevTools
- Use Playwright Inspector:
PWDEBUG=1 pytest test.py - Try multiple selector strategies (text, role, test-id)
Tests slow in CI:
- Enable parallel execution:
pytest -n auto - Use headed mode only for debugging
- Consider browser context reuse for related tests
For more troubleshooting tips, see Common Pitfalls.