Spaces:
Runtime error
Runtime error
ToolStore Agent
feat: all 26 toolsets β complete skill-to-toolset conversion, published to HF Space
2163b34 webapp-testing
name: webapp-testing description: Test local web applications using browser automation (Playwright) β verify functionality, debug UI behavior, capture screenshots, and view browser logs. Use when the user wants to test a web app, verify frontend behavior, debug UI issues, or automate browser interactions.
Web Application Testing
Test local web applications using Playwright browser automation.
Overview
This skill provides patterns and helpers for testing web applications β verifying functionality, debugging UI issues, capturing browser state, and automating browser interactions.
Decision Tree
User task β Is it static HTML?
ββ Yes β Read HTML file directly to identify selectors
β ββ Success β Write Playwright script using selectors
β ββ Incomplete β Treat as dynamic webapp (below)
β
ββ No (dynamic webapp) β Is the server already running?
ββ No β Start the server first, then test
β
ββ Yes β Reconnaissance-then-action:
1. Navigate and wait for network idle
2. Take screenshot or inspect DOM
3. Identify selectors from rendered state
4. Execute actions with discovered selectors
Instructions
1. Start the Server (if needed)
If the webapp isn't running, start it first. Use a helper script or start the server directly:
# Single server
cd /path/to/project && npm run dev &
# Or use a process manager
Wait for the server to be ready before proceeding.
2. Reconnaissance (for dynamic apps)
Before writing automation, understand what's on the page:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigate and wait for JS to execute
page.goto('http://localhost:PORT')
page.wait_for_load_state('networkidle') # CRITICAL for dynamic apps
# Inspect the rendered page
page.screenshot(path='/tmp/inspect.png', full_page=True)
# Discover available elements
buttons = page.locator('button').all()
inputs = page.locator('input').all()
links = page.locator('a').all()
browser.close()
3. Write the Test/Automation Script
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('http://localhost:PORT')
page.wait_for_load_state('networkidle')
# Your automation logic:
# - Click buttons
# - Fill forms
# - Verify text/content
# - Take screenshots at key moments
# - Check console logs
page.screenshot(path='/tmp/result.png', full_page=True)
browser.close()
4. Verify Results
- Take screenshots at key interaction points
- Check page content and element states
- Capture console logs for debugging
- Verify network requests if relevant
Common Patterns
Form Testing
# Fill a form
page.fill('#name', 'Test User')
page.fill('#email', 'test@example.com')
page.click('button[type="submit"]')
# Wait for success message
page.wait_for_selector('.success-message')
Multi-Step Flow
# Step 1: Navigate
page.goto('http://localhost:PORT/login')
page.wait_for_load_state('networkidle')
# Step 2: Login
page.fill('#username', 'admin')
page.fill('#password', 'password')
page.click('button[type="submit"]')
page.wait_for_url('**/dashboard')
# Step 3: Verify dashboard loaded
assert page.locator('h1').text_content() == 'Dashboard'
Debugging
# Capture console logs
page.on('console', lambda msg: print(f'CONSOLE: {msg.text}'))
# Take screenshots at failures
try:
page.wait_for_selector('.expected-element', timeout=5000)
except:
page.screenshot(path='/tmp/debug-failure.png')
raise
Best Practices
- Always wait for
networkidleon dynamic apps before inspection - Use descriptive selectors:
text=,role=, CSS selectors, IDs - Add appropriate waits:
wait_for_selector(),wait_for_timeout() - Use
sync_playwright()for synchronous scripts - Always close the browser when done
- Take screenshots at key moments for debugging
Guidelines
- Test in headless mode:
headless=Truefor automation - Handle timeouts: Set appropriate timeouts; don't hang indefinitely
- Clean up: Close browser even on failures (use try/finally)
- One assertion per test: Keep test scripts focused
- Use data-testid: Prefer
data-testidattributes over CSS classes for test selectors