Overview
The Web App Testing skill provides a comprehensive toolkit for testing local web applications using Playwright. It enables you to verify frontend functionality, debug UI behavior, capture browser screenshots, and analyze browser console logs.When to Use This Skill
Use the Web App Testing skill when you need to:- Test local web applications with automated browser interactions
- Verify frontend functionality and UI behavior
- Debug rendering issues or JavaScript errors
- Capture screenshots for visual verification
- Analyze browser console logs and network activity
- Test both static HTML and dynamic web applications
Core Approach
Write native Python Playwright scripts for all testing tasks. The skill provides helper scripts that manage complex workflows as black boxes.Always run scripts with
--help first to see usage before reading source code. These scripts can be very large and will pollute your context window. They’re designed to be called directly, not ingested.Decision Tree: Choosing Your Approach
Helper Scripts
Server Management: with_server.py
Manages server lifecycle for testing dynamic applications. Supports multiple concurrent servers.
Single server example:
How with_server.py Works
How with_server.py Works
The script:
- Starts all specified servers in the background
- Waits for each port to become available (health check)
- Runs your automation script
- Automatically cleans up and stops servers when done
Writing Automation Scripts
Basic Structure
Critical: Always use
headless=True for Chromium. When using with_server.py, servers are already running and ready—no startup code needed.Reconnaissance-Then-Action Pattern
For dynamic applications, follow this three-step pattern:Identify Selectors
Based on inspection results, identify the selectors you need:
- Text-based:
text=Submit - Role-based:
role=button[name="Submit"] - CSS selectors:
.submit-btn,#submit-button - IDs:
id=submit-btn
Common Patterns
Static HTML Testing
Element Discovery
Capturing Console Logs
Waiting Strategies
Best Practices
Use Bundled Scripts as Black Boxes
Use Bundled Scripts as Black Boxes
Before writing custom server management code:
- Check if a script exists in
scripts/ - Run it with
--helpto see usage - Invoke it directly without reading the source
Always Wait for networkidle
Always Wait for networkidle
Don’t inspect the DOM before waiting for ✅ Do this:
networkidle on dynamic apps:❌ Don’t do this:Use Descriptive Selectors
Use Descriptive Selectors
Prefer selectors that are resilient to changes:Good selectors:
text=Submit- Based on visible textrole=button[name="Submit"]- Based on accessibility role[data-testid="submit-btn"]- Based on test IDs
.MuiButton-root-123- Generated class namesdiv > div > button:nth-child(3)- Positional selectors
Synchronous vs Asynchronous
Synchronous vs Asynchronous
The skill examples use
sync_playwright() for synchronous scripts, which are simpler for most testing scenarios.For asynchronous testing (e.g., with async/await patterns), use async_playwright():Common Pitfalls
Common Mistake: Inspecting DOM before JavaScript finishes executingDynamic web apps often render content via JavaScript after initial page load. Always wait for
networkidle before inspecting or interacting with the page.Pitfall: Race Conditions
Pitfall: Not Closing Browser
Reference Files
The skill includes example files in theexamples/ directory:
- element_discovery.py - Discovering buttons, links, and inputs on a page
- static_html_automation.py - Using file:// URLs for local HTML
- console_logging.py - Capturing console logs during automation
Testing Checklist
Before running your automation:- Determined if the app is static or dynamic
- Identified if server management is needed
- Ran helper scripts with
--helpif needed - Set
headless=Truefor Chromium - Added
wait_for_load_state('networkidle')for dynamic apps - Used descriptive, resilient selectors
- Added appropriate waits for elements
- Included
browser.close()for cleanup - Captured console logs if debugging