Automated webapp testing with Playwright. Server management, UI testing, visual debugging, and reconnaissance-first approach.
Core Principle: Reconnaissance Before Action
Automated webapp testing using Playwright with a focus on verifying system state (server status, page load, element presence) before taking any action. This ensures reliable, debuggable tests that fail for clear reasons.
Key capabilities:
Not suitable for: Unit testing (use Jest/pytest), load testing, or API-only testing.
RECONNAISSANCE BEFORE ACTION
Never execute test actions without first:
lsof -i :PORT and curl checkspage.wait_for_load_state('networkidle')Why: Tests fail mysteriously when servers aren't ready, selectors break when DOM is still building, and 5 seconds of reconnaissance saves 30 minutes of debugging.
lsof -i :3000 -sTCP:LISTEN # Check server listening
curl -f http://localhost:3000/health # Test response
# Single server
python scripts/with_server.py --server "npm run dev" --port 5173 -- python test.py
# Multiple servers (backend + frontend)
python scripts/with_server.py \
--server "cd backend && python server.py" --port 3000 \
--server "cd frontend && npm run dev" --port 5173 \
-- python test.py
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# 1. Navigate and wait
page.goto('http://localhost:5173')
page.wait_for_load_state('networkidle') # CRITICAL
# 2. Reconnaissance
page.screenshot(path='/tmp/before.png', full_page=True)
buttons = page.locator('button').all()
print(f"Found {len(buttons)} buttons")
# 3. Execute
page.click('button.submit')
# 4. Verify
page.wait_for_selector('.success-message')
page.screenshot(path='/tmp/after.png', full_page=True)
browser.close()
Review console output, check for errors, verify state changes, examine screenshots.
Server Management - Check → Start → Wait → Test → Cleanup
with_server.py for automatic lifecycle managementlsof, test with curlReconnaissance - Inspect → Understand → Act → Verify
Wait Strategy - Load → Idle → Element → Action
networkidle on dynamic appsSelector Priority - data-testid > role > text > CSS > XPath
[data-testid="submit"] - most stablerole=button[name="Submit"] - semantictext=Submit - readablebutton.submit - acceptable❌ Testing without server verification - Always check lsof and curl first
❌ Ignoring timeout errors - TimeoutError means something is wrong, investigate
❌ Not waiting for networkidle - Dynamic apps need full page load
❌ Poor selector strategies - Use data-testid for stability
❌ Missing network verification - Check API responses complete
❌ Incomplete cleanup - Close browsers, stop servers properly
playwright-patterns.md - Complete Playwright reference Selectors, waits, interactions, assertions, test organization, network interception, screenshots, debugging
server-management.md - Server lifecycle and operations with_server.py usage, manual management, port management, process control, environment config, health checks
reconnaissance-pattern.md - Philosophy and practice Why reconnaissance first, complete process, server checks, network diagnostics, DOM inspection, log analysis
decision-tree.md - Flowcharts for every scenario New test decisions, server state paths, test failure diagnosis, debugging flows, selector/wait strategies
troubleshooting.md - Solutions to common problems Timeout issues, selector problems, server crashes, network errors, environment config, debugging workflow
Examples (examples/ directory):
element_discovery.py - Discovering page elementsstatic_html_automation.py - Testing local HTML filesconsole_logging.py - Capturing console outputScripts (scripts/ directory):
with_server.py - Server lifecycle management (run with --help first)Mandatory: verification-before-completion Recommended: systematic-debugging, test-driven-development Related: playwright-testing, selenium-automation
The reconnaissance-then-action pattern is not optional - it's the foundation of reliable webapp testing.
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer