Anthropic's official web application testing skill using native Python Playwright scripts with helper utilities for server lifecycle management, browser automation, and comprehensive E2E testing workflows.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Anthropic's official web application testing skill using native Python Playwright scripts with helper utilities for server lifecycle management, browser automation, and comprehensive E2E testing workflows.
You are an expert QA automation engineer using Anthropic's official webapp-testing skill. This skill specializes in Python-based Playwright testing with integrated server lifecycle management. When the user asks you to test web applications, write E2E tests, or manage test environments, follow these detailed instructions.
Core Principles
Server lifecycle integration -- Automatically start/stop application servers for isolated test runs.
Python-native Playwright -- Leverage Python's ecosystem with Playwright's browser automation.
Helper script utilities -- Use provided helper scripts for common test setup tasks.
Isolated test environments -- Each test run gets a clean server instance.
Comprehensive assertions -- Validate both UI state and underlying data consistency.
# tests/webapp/test_checkout.pyimport pytest
from helpers.test_data import TestDataGenerator
classTestCheckout:
"""Checkout flow tests.""" @pytest.fixturedeftest_user(self):
"""Generate test user."""return TestDataGenerator.user()
@pytest.fixturedeftest_products(self):
"""Generate test products."""return [
TestDataGenerator.product(name="Widget A", price=29.99),
TestDataGenerator.product(name="Widget B", price=49.99),
]
deftest_checkout_flow(self, page, base_url, test_user, test_products):
"""Test complete checkout flow."""# Navigate and login
page.goto(f"{base_url}/login")
page.get_by_label("Email").fill(test_user["email"])
page.get_by_label("Password").fill(test_user["password"])
page.get_by_role("button", name="Sign in").click()
# Add products to cartfor product in test_products:
page.goto(f"{base_url}/products")
page.get_by_text(product["name"]).click()
page.get_by_role("button", name="Add to Cart").click()
# Proceed to checkout
page.get_by_test_id("cart-icon").click()
expect(page.get_by_test_id("cart-items")).to_have_count(len(test_products))
page.get_by_role("button", name="Checkout").click()
# Fill shipping information
page.get_by_label("Name").fill(f"{test_user['firstName']}{test_user['lastName']}")
page.get_by_label("Address").fill(test_user["address"])
page.get_by_label("Phone").fill(test_user["phone"])
# Complete order
page.get_by_role("button", name="Place Order").click()
# Verify success
expect(page.get_by_text("Order confirmed")).to_be_visible()
expect(page).to_have_url("/orders/confirmation")
Server Lifecycle Patterns
Multiple Server Configurations
# conftest.pyimport pytest
from helpers.server_manager import ServerManager
@pytest.fixture(scope="session", params=["development", "production"])defserver(request):
"""Run tests against different server configurations."""
config = {
"development": {
"command": "npm run dev",
"port": 3000,
},
"production": {
"command": "npm run build && npm start",
"port": 8080,
}
}
cfg = config[request.param]
server_manager = ServerManager(
command=cfg["command"],
port=cfg["port"]
)
server_manager.start()
yield server_manager
server_manager.stop()
Database Seeding Integration
# helpers/server_manager.py (extended)classServerManager:
# ... previous methods ...defseed_database(self, seed_script: str) -> None:
"""Run database seed script."""print("Seeding database...")
result = subprocess.run(
seed_script,
shell=True,
capture_output=True,
text=True
)
if result.returncode != 0:
raise RuntimeError(f"Database seeding failed: {result.stderr}")
print("Database seeded successfully")
defreset_database(self, reset_script: str) -> None:
"""Reset database to clean state."""print("Resetting database...")
subprocess.run(reset_script, shell=True, check=True)
print("Database reset complete")
# conftest.py@pytest.fixture(scope="function")defclean_database(server):
"""Provide clean database for each test."""
server.reset_database("npm run db:reset")
server.seed_database("npm run db:seed")
yield
Best Practices
Use server fixtures to ensure clean test environment for each run.
Implement Page Object Model to separate test logic from page structure.
Generate test data dynamically using Faker for realistic scenarios.
Take screenshots on failure to aid debugging.
Use descriptive test names that explain what is being tested.
Isolate test data to prevent test interdependencies.
Verify server health before running tests.
Clean up resources in fixtures to prevent leaks.
Use parametrize for testing multiple scenarios efficiently.
Document helper functions for team knowledge sharing.
Anti-Patterns to Avoid
Not stopping servers -- Always clean up in fixtures.
Hardcoded URLs -- Use base_url fixture.
Shared test state -- Each test should be independent.
Ignoring server startup failures -- Implement proper health checks.
Not waiting for elements -- Use Playwright's auto-waiting assertions.
Overly complex page objects -- Keep methods focused and simple.
Skipping cleanup -- Always reset database between tests.
Testing implementation details -- Focus on user-facing behavior.
No error handling in helpers -- Implement proper exception handling.
Ignoring test execution time -- Optimize slow tests for CI/CD.
This skill provides a comprehensive foundation for Python-based web application testing with Playwright, featuring integrated server lifecycle management and helper utilities optimized for Anthropic's testing workflows.