README

Tests and automates local web applications using Playwright. Verifies frontend functionality, captures screenshots, reads browser console logs, and interacts with UI elements programmatically.

Prerequisites

DependencyInstallPurpose
Node.js 18+requiredTypeScript scripts via npx tsx
Playwright (Node.js)npx playwright install chromiumbrowser automation (TypeScript)
Python 3.9+optionalPython Playwright scripts
Playwright (Python)pip install playwright && playwright install chromiumbrowser automation (Python)

TypeScript is the default runtime. Python is used when the project prefers it or python3 is available.

Scripts

FilePurpose
scripts/ts/with-server.tsManages server lifecycle before running automation (TypeScript)
scripts/python/with_server.pySame as above — Python variant

Run with --help before reading source to see all options.

Quick Start

# Install Playwright browsers (do this once)
npx playwright install chromium

# Start a dev server and run an automation script
npx tsx scripts/ts/with-server.ts --server "npm run dev" --port 5173 -- node your_automation.js

# Multiple servers (e.g., backend + frontend)
npx tsx scripts/ts/with-server.ts \
  --server "node server.js" --port 3000 \
  --server "npm run dev" --port 5173 \
  -- node your_automation.js

Writing Automation Scripts

Your automation script handles only Playwright logic. Server lifecycle is managed by with-server.ts:

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.screenshot(path="screenshot.png")
    browser.close()

Always launch Chromium in headless mode in automation scripts.


SKILL.md

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

When to Activate

  • User wants to test, verify, or automate a local web application
  • User needs a browser screenshot of a running app
  • User wants to check browser console logs or network requests
  • User needs to interact with UI elements programmatically

Skip When

  • User wants collaborative local-HTML inspect (see what they click) — use codi-html-live-inspect
  • User wants to design a new UI from scratch — use codi-frontend-design
  • User wants generative / algorithmic art — use codi-algorithmic-art
  • User wants multi-phase QA sweep across the whole app — use codi-guided-qa-testing
  • User wants to audit the full Codi installation (contributor-only) — use codi-dev-e2e-testing

Helper Scripts Available (TypeScript and Python — use whichever runtime is available):

  • TypeScript: ${CLAUDE_SKILL_DIR}[[/scripts/ts/with-server.ts]] — Manages server lifecycle (supports multiple servers)
  • Python: ${CLAUDE_SKILL_DIR}[[/scripts/python/with_server.py]] — Same functionality, Python variant

Use TypeScript by default (npx tsx). Use Python when python3 is available and the project prefers it.

Always run scripts with --help first to see usage. DO NOT read the source until you try running the script first and find that a customized solution is absolutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window.

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: npx tsx ${CLAUDE_SKILL_DIR}[[/scripts/ts/with-server.ts]] --help
        │        Then use the 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

To start a server, run --help first, then use the helper:

Single server (TypeScript):

npx tsx ${CLAUDE_SKILL_DIR}[[/scripts/ts/with-server.ts]] --server "npm run dev" --port 5173 -- node your_automation.js

Single server (Python):

python3 ${CLAUDE_SKILL_DIR}[[/scripts/python/with_server.py]] --server "npm run dev" --port 5173 -- python3 your_automation.py

Multiple servers (e.g., backend + frontend):

npx tsx ${CLAUDE_SKILL_DIR}[[/scripts/ts/with-server.ts]] \\
  --server "cd backend && node server.js" --port 3000 \\
  --server "cd frontend && npm run dev" --port 5173 \\
  -- node your_automation.js

To create an automation script, include only Playwright logic (servers are managed automatically):

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode
    page = browser.new_page()
    page.goto('http://localhost:5173') # Server already running and ready
    page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
    # ... your automation logic
    browser.close()

Reconnaissance-Then-Action Pattern

  1. Inspect rendered DOM:

    page.screenshot(path='/tmp/inspect.png', full_page=True)
    content = page.content()
    page.locator('button').all()
  2. Identify selectors from inspection results

  3. Execute actions using discovered selectors

Common Pitfall

  • Don’t inspect the DOM before waiting for networkidle on dynamic apps
  • Do wait for page.wait_for_load_state('networkidle') before inspection

Best Practices

  • Use bundled scripts as black boxes - To accomplish a task, consider whether one of the scripts available in scripts/ can help. These scripts handle common, complex workflows reliably without cluttering the context window. Use --help to see usage, then invoke directly.
  • Use sync_playwright() for synchronous scripts
  • Always close the browser when done
  • Use descriptive selectors: text=, role=, CSS selectors, or IDs
  • Add appropriate waits: page.wait_for_selector() or page.wait_for_timeout()

Reference Files

  • references/ - Examples showing common patterns:
    • ${CLAUDE_SKILL_DIR}[[/references/element_discovery.py]] - Discovering buttons, links, and inputs on a page
    • ${CLAUDE_SKILL_DIR}[[/references/static_html_automation.py]] - Using file:// URLs for local HTML
    • ${CLAUDE_SKILL_DIR}[[/references/console_logging.py]] - Capturing console logs during automation

Available Agents

For test generation from webapp testing results, delegate to this agent:

  • codi-test-generator — Generate automated tests from webapp testing findings. Prompt at ${CLAUDE_SKILL_DIR}[[/agents/test-generator.md]]