← Back to verified page

Webapp Testing SKILL.md Source

Full source content for verification and traceability.

Web Application Testing

To test local web applications, write native Python Playwright scripts.

Helper Scripts Available:

  • scripts/with_server.py - Manages server lifecycle (supports multiple servers)

Always run scripts with --help first to see usage. Do not read helper script source unless customization is absolutely required.

Decision Tree: Choosing Your Approach

User task → Is it static HTML?
    ├─ Yes → Read HTML file directly to identify selectors
    │         ├─ Success → Write Playwright script using selectors
    │         └─ Fails/Incomplete → Treat as dynamic (below)
    │
    └─ No (dynamic webapp) → Is the server already running?
        ├─ No → Run: python scripts/with_server.py --help
        │        Then use helper + write simplified Playwright script
        │
        └─ Yes → Reconnaissance-then-action:
            1. Navigate and wait for networkidle
            2. Take screenshot or inspect DOM
            3. Identify selectors from rendered state
            4. Execute actions with discovered selectors

Example: Using with_server.py

Run help first, then execute:

Single server

python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py

Multiple servers

python scripts/with_server.py \
  --server "cd backend && python server.py" --port 3000 \
  --server "cd frontend && npm run dev" --port 5173 \
  -- python your_automation.py

Playwright Pattern

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:5173')
    page.wait_for_load_state('networkidle')
    # ... automation logic
    browser.close()

Reconnaissance-Then-Action

  1. Inspect rendered DOM
  2. Identify selectors from observed page state
  3. Execute actions with discovered selectors

Common Pitfall

  • Do not inspect dynamic app DOM before networkidle
  • Do wait for page.wait_for_load_state('networkidle') first

Best Practices

  • Use bundled scripts as black boxes
  • Use sync_playwright() for synchronous scripts
  • Always close browser sessions
  • Prefer descriptive selectors (text=, role=, CSS, IDs)
  • Add explicit waits where needed

Reference Files

  • examples/element_discovery.py
  • examples/static_html_automation.py
  • examples/console_logging.py