--- name: browse preamble-tier: 1 version: 1.1.0 description: | Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with elements, verify page state, diff before/after actions, take annotated screenshots, check responsive layouts, test forms and uploads, handle dialogs, and assert element states. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. Use when asked to "open in browser", "test the site", "take a screenshot", or "dogfood this". (gstack) triggers: - browse a page - headless browser - take page screenshot allowed-tools: - Bash - Read - AskUserQuestion --- {{PREAMBLE}} # browse: QA Testing & Dogfooding Persistent headless Chromium. First call auto-starts (~3s), then ~100ms per command. State persists between calls (cookies, tabs, login sessions). {{BROWSE_SETUP}} ## Core QA Patterns ### 1. Verify a page loads correctly ```bash $B goto https://yourapp.com $B text # content loads? $B console # JS errors? $B network # failed requests? $B is visible ".main-content" # key elements present? ``` ### 2. Test a user flow ```bash $B goto https://app.com/login $B snapshot -i # see all interactive elements $B fill @e3 "user@test.com" $B fill @e4 "password" $B click @e5 # submit $B snapshot -D # diff: what changed after submit? $B is visible ".dashboard" # success state present? ``` ### 3. Verify an action worked ```bash $B snapshot # baseline $B click @e3 # do something $B snapshot -D # unified diff shows exactly what changed ``` ### 4. Visual evidence for bug reports ```bash $B snapshot -i -a -o /tmp/annotated.png # labeled screenshot $B screenshot /tmp/bug.png # plain screenshot $B console # error log ``` ### 5. Find all clickable elements (including non-ARIA) ```bash $B snapshot -C # finds divs with cursor:pointer, onclick, tabindex $B click @c1 # interact with them ``` ### 6. Assert element states ```bash $B is visible ".modal" $B is enabled "#submit-btn" $B is disabled "#submit-btn" $B is checked "#agree-checkbox" $B is editable "#name-field" $B is focused "#search-input" $B js "document.body.textContent.includes('Success')" ``` ### 7. Test responsive layouts ```bash $B responsive /tmp/layout # mobile + tablet + desktop screenshots $B viewport 375x812 # or set specific viewport $B screenshot /tmp/mobile.png ``` ### 8. Test file uploads ```bash $B upload "#file-input" /path/to/file.pdf $B is visible ".upload-success" ``` ### 9. Test dialogs ```bash $B dialog-accept "yes" # set up handler $B click "#delete-button" # trigger dialog $B dialog # see what appeared $B snapshot -D # verify deletion happened ``` ### 10. Compare environments ```bash $B diff https://staging.app.com https://prod.app.com ``` ### 11. Show screenshots to the user After `$B screenshot`, `$B snapshot -a -o`, or `$B responsive`, always use the Read tool on the output PNG(s) so the user can see them. Without this, screenshots are invisible. ### 12. Render local HTML (no HTTP server needed) Two paths, pick the cleaner one: ```bash # HTML file on disk → goto file:// (absolute, or cwd-relative) $B goto file:///tmp/report.html $B goto file://./docs/page.html # cwd-relative $B goto file://~/Documents/page.html # home-relative # HTML generated in memory → load-html reads the file into setContent echo '
hello
' > /tmp/tweet.html $B load-html /tmp/tweet.html ``` `goto file://...` is usually cleaner (URL is saved in state, relative asset URLs resolve against the file's dir, scale changes replay naturally). `load-html` uses `page.setContent()` — URL stays `about:blank`, but the content survives `viewport --scale` via in-memory replay. Both are scoped to files under cwd or `$TMPDIR`. ### 13. Retina screenshots (deviceScaleFactor) ```bash $B viewport 480x600 --scale 2 # 2x deviceScaleFactor $B load-html /tmp/tweet.html # or: $B goto file://./tweet.html $B screenshot /tmp/out.png --selector .tweet-card # → /tmp/out.png is 2x the pixel dimensions of the element ``` Scale must be 1-3 (gstack policy cap). Changing `--scale` recreates the browser context; refs from `snapshot` are invalidated (rerun `snapshot`), but `load-html` content is replayed automatically. Not supported in headed mode. ## Puppeteer → browse cheatsheet Migrating from Puppeteer? Here's the 1:1 mapping for the core workflow: | Puppeteer | browse | |---|---| | `await page.goto(url)` | `$B goto ` | | `await page.setContent(html)` | `$B load-html ` (or `$B goto file://`) | | `await page.setViewport({width, height})` | `$B viewport WxH` | | `await page.setViewport({width, height, deviceScaleFactor: 2})` | `$B viewport WxH --scale 2` | | `await (await page.$('.x')).screenshot({path})` | `$B screenshot --selector .x` | | `await page.screenshot({fullPage: true, path})` | `$B screenshot ` (full page default) | | `await page.screenshot({clip: {x, y, w, h}, path})` | `$B screenshot --clip x,y,w,h` | Worked example (the tweet-renderer flow — Puppeteer → browse): ```bash # Generate HTML in memory, render at 2x scale, screenshot the tweet card. echo '
hello
' > /tmp/tweet.html $B viewport 480x600 --scale 2 $B load-html /tmp/tweet.html $B screenshot /tmp/out.png --selector .tweet-card # /tmp/out.png is 800x400 px, crisp (2x deviceScaleFactor). ``` Aliases: typing `setcontent` or `set-content` routes to `load-html` automatically. Typing a typo (`load-htm`) returns `Did you mean 'load-html'?`. ## User Handoff When you hit something you can't handle in headless mode (CAPTCHA, complex auth, multi-factor login), hand off to the user: ```bash # 1. Open a visible Chrome at the current page $B handoff "Stuck on CAPTCHA at login page" # 2. Tell the user what happened (via AskUserQuestion) # "I've opened Chrome at the login page. Please solve the CAPTCHA # and let me know when you're done." # 3. When user says "done", re-snapshot and continue $B resume ``` **When to use handoff:** - CAPTCHAs or bot detection - Multi-factor authentication (SMS, authenticator app) - OAuth flows that require user interaction - Complex interactions the AI can't handle after 3 attempts The browser preserves all state (cookies, localStorage, tabs) across the handoff. After `resume`, you get a fresh snapshot of wherever the user left off. ## Snapshot Flags {{SNAPSHOT_FLAGS}} ## CSS Inspector & Style Modification ### Inspect element CSS ```bash $B inspect .header # full CSS cascade for selector $B inspect # latest picked element from sidebar $B inspect --all # include user-agent stylesheet rules $B inspect --history # show modification history ``` ### Modify styles live ```bash $B style .header background-color #1a1a1a # modify CSS property $B style --undo # revert last change $B style --undo 2 # revert specific change ``` ### Clean screenshots ```bash $B cleanup --all # remove ads, cookies, sticky, social $B cleanup --ads --cookies # selective cleanup $B prettyscreenshot --cleanup --scroll-to ".pricing" --width 1440 ~/Desktop/hero.png ``` ## Full Command List {{COMMAND_REFERENCE}}