Loading...
Loading...
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
npx skill4agent add sentimony/skills web-debugscripts/with_server.py--helpUser 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 <skill>/scripts/with_server.py --help
│ Then use the helper + write simplified Playwright script
│
└─ Yes → Reconnaissance-then-action:
0. Confirm the actual port from the server's startup logs — dev servers
silently move to the next port (3000 → 3004) when the default is taken
1. Navigate and wait for rendered content (see Waiting Strategy)
2. Take screenshot or inspect DOM
3. Identify selectors from rendered state
4. Execute actions with discovered selectors--helppython <skill>/scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.pyfrom playwright.sync_api import sync_playwright
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
with sync_playwright() as p:
browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode
page = browser.new_page()
page.on('console', lambda msg: print(f'[console.{msg.type}] {msg.text}')) # msg.type: log, debug, info, warning, error
page.on('pageerror', lambda err: print(f'[pageerror] {err}')) # Uncaught JS exceptions are not console events
page.on('requestfailed', lambda req: print(
f'[requestfailed] {req.url} {req.failure or "unknown"}')) # failure is Optional[str] in Python; hint only - see Interpreting Failures
page.on('response', lambda res: res.status >= 400 and print(f'[http {res.status}] {res.url}'))
page.goto('http://localhost:5173', wait_until='domcontentloaded') # Server already running and ready
try:
page.wait_for_function(
"document.body.innerText.trim().length > 0", timeout=5000) # Wait for the SPA to render
except PlaywrightTimeoutError:
pass # text-free page (canvas/WebGL) - proceed to screenshot recon
page.screenshot(path='recon.png') # Visual state check
# ... your automation logic
browser.close()playwrightpip install playwright && playwright install chromiumpage.goto(url, wait_until='domcontentloaded')wait_for_function#root#__nuxt#apppage.wait_for_selector()expect(locator)networkidlepage.wait_for_timeout(2000-3000)domcontentloadedpage.goto()ERR_ABORTEDgotoconsole.errorwarningpageerrorrequestfailedrequestfailedERR_ABORTEDpage.close()?v=curlpage.evaluate("fetch(...)")[vite] connecting...Unrecognized featureloading="lazy"sync_playwright()page.get_by_role()page.get_by_label()page.get_by_text()get_by_role('button', name=...).firstpage.wait_for_selector()expect(locator)--servershell=Truecd … && …element_discovery.pystatic_html_automation.pyconsole_logging.pyconsole_audit.py