| name | agent-browser |
| description | Automates browser and Electron app interactions for user-flow validation. |
Browser Automation with agent-browser
One-time setup (fresh machines)
If you see an error like "Executable doesn't exist ... chrome-headless-shell", install the bundled Chromium:
agent-browser install
Quick start
agent-browser open <url>
agent-browser snapshot -i
agent-browser click @e1
agent-browser fill @e2 "text"
agent-browser close
Core workflow
- Navigate:
agent-browser open <url>
- Snapshot:
agent-browser snapshot -i (returns elements with refs like @e1, @e2)
- Interact using refs from the snapshot
- Re-snapshot after navigation or significant DOM changes
Command chaining
Commands can be chained with && in a single shell invocation. The browser persists between commands via a background daemon, so chaining is safe and more efficient than separate calls.
agent-browser open https://example.com && agent-browser wait --load networkidle && agent-browser snapshot -i
agent-browser fill @e1 "user@example.com" && agent-browser fill @e2 "password123" && agent-browser click @e3
agent-browser open https://example.com && agent-browser wait --load networkidle && agent-browser screenshot page.png
When to chain: Use && when you don't need to read the output of an intermediate command before proceeding (e.g., open + wait + screenshot). Run commands separately when you need to parse the output first (e.g., snapshot to discover refs, then interact using those refs).
Commands
Navigation
agent-browser open <url>
agent-browser back
agent-browser forward
agent-browser reload
agent-browser close
agent-browser connect 9222
Snapshot (page analysis)
agent-browser snapshot
agent-browser snapshot -i
agent-browser snapshot -i -C
agent-browser snapshot -c
agent-browser snapshot -d 3
agent-browser snapshot -s "#main"
Interactions (use @refs from snapshot)
agent-browser click @e1
agent-browser click @e1 --new-tab
agent-browser dblclick @e1
agent-browser focus @e1
agent-browser fill @e2 "text"
agent-browser type @e2 "text"
agent-browser press Enter
agent-browser press Control+a
agent-browser keydown Shift
agent-browser keyup Shift
agent-browser hover @e1
agent-browser check @e1
agent-browser uncheck @e1
agent-browser select @e1 "value"
agent-browser select @e1 "a" "b"
agent-browser scroll down 500
agent-browser scrollintoview @e1
agent-browser drag @e1 @e2
agent-browser upload @e1 file.pdf
Get information
agent-browser get text @e1
agent-browser get text body > page.txt
agent-browser get html @e1
agent-browser get value @e1
agent-browser get attr @e1 href
agent-browser get title
agent-browser get url
agent-browser get count ".item"
agent-browser get box @e1
agent-browser get styles @e1
Check state
agent-browser is visible @e1
agent-browser is enabled @e1
agent-browser is checked @e1
Screenshots & PDF
agent-browser screenshot
agent-browser screenshot path.png
agent-browser screenshot --full
agent-browser screenshot --annotate
agent-browser pdf output.pdf
Video recording
agent-browser record start ./demo.webm
agent-browser click @e1
agent-browser record stop
agent-browser record restart ./take2.webm
Recording creates a fresh context but preserves cookies/storage from your session. If no URL is provided, it
automatically returns to your current page. For smooth demos, explore first, then start recording.
Diff (compare page states)
agent-browser diff snapshot
agent-browser diff snapshot --baseline before.txt
agent-browser diff screenshot --baseline before.png
agent-browser diff url <url1> <url2>
agent-browser diff url <url1> <url2> --wait-until networkidle
agent-browser diff url <url1> <url2> --selector "#main"
Use diff snapshot after performing an action to verify it had the intended effect. This compares the current accessibility tree against the last snapshot taken in the session.
agent-browser snapshot -i
agent-browser click @e2
agent-browser diff snapshot
diff snapshot output uses + for additions and - for removals, similar to git diff. diff screenshot produces a diff image with changed pixels highlighted in red, plus a mismatch percentage.
Wait
agent-browser wait @e1
agent-browser wait 2000
agent-browser wait --text "Success"
agent-browser wait --url "**/dashboard"
agent-browser wait --load networkidle
agent-browser wait --fn "window.ready"
Mouse control
agent-browser mouse move 100 200
agent-browser mouse down left
agent-browser mouse up left
agent-browser mouse wheel 100
Semantic locators (alternative to refs)
When refs are unavailable or unreliable, use semantic locators:
agent-browser find role button click --name "Submit"
agent-browser find text "Sign In" click
agent-browser find text "Sign In" click --exact
agent-browser find label "Email" fill "user@test.com"
agent-browser find placeholder "Search" type "query"
agent-browser find alt "Logo" click
agent-browser find title "Close" click
agent-browser find testid "submit-btn" click
agent-browser find first ".item" click
agent-browser find last ".item" click
agent-browser find nth 2 "a" hover
Browser settings
agent-browser set viewport 1920 1080
agent-browser set device "iPhone 14"
agent-browser set geo 37.7749 -122.4194
agent-browser set offline on
agent-browser set headers '{"X-Key":"v"}'
agent-browser set credentials user pass
agent-browser set media dark
agent-browser set media light reduced-motion
Cookies & Storage
agent-browser cookies
agent-browser cookies set name value
agent-browser cookies clear
agent-browser storage local
agent-browser storage local key
agent-browser storage local set k v
agent-browser storage local clear
Network
agent-browser network route <url>
agent-browser network route <url> --abort
agent-browser network route <url> --body '{}'
agent-browser network unroute [url]
agent-browser network requests
agent-browser network requests --filter api
Tabs & Windows
agent-browser tab
agent-browser tab new [url]
agent-browser tab 2
agent-browser tab close
agent-browser tab close 2
agent-browser window new
Frames
agent-browser frame "#iframe"
agent-browser frame main
Dialogs
agent-browser dialog accept [text]
agent-browser dialog dismiss
JavaScript (eval)
Use eval to run JavaScript in the browser context. Shell quoting can corrupt complex expressions -- use --stdin or -b to avoid issues.
agent-browser eval 'document.title'
agent-browser eval 'document.querySelectorAll("img").length'
agent-browser eval --stdin <<'EVALEOF'
JSON.stringify(
Array.from(document.querySelectorAll("img"))
.filter(i => !i.alt)
.map(i => ({ src: i.src.split("/").pop(), width: i.width }))
)
EVALEOF
agent-browser eval -b "$(echo -n 'Array.from(document.querySelectorAll("a")).map(a => a.href)' | base64)"
Rules of thumb:
- Single-line, no nested quotes -> regular
eval 'expression' with single quotes is fine
- Nested quotes, arrow functions, template literals, or multiline -> use
eval --stdin <<'EVALEOF'
- Programmatic/generated scripts -> use
eval -b with base64
Profiling
agent-browser profiler start
agent-browser profiler stop trace.json
Global options
agent-browser --session <name> ...
agent-browser --session-name <name> ...
agent-browser --json ...
agent-browser --headed ...
agent-browser --full ...
agent-browser --cdp <port> ...
agent-browser --auto-connect ...
agent-browser -p <provider> ...
agent-browser --proxy <url> ...
agent-browser --headers <json> ...
agent-browser --executable-path <p>
agent-browser --extension <path> ...
agent-browser --allow-file-access ...
agent-browser --ignore-https-errors ...
agent-browser --config <path> ...
agent-browser --help
agent-browser --version
agent-browser <command> --help
Proxy support
agent-browser --proxy http://proxy.com:8080 open example.com
agent-browser --proxy http://user:pass@proxy.com:8080 open example.com
agent-browser --proxy socks5://proxy.com:1080 open example.com
Environment variables
AGENT_BROWSER_SESSION="mysession"
AGENT_BROWSER_EXECUTABLE_PATH="/path/chrome"
AGENT_BROWSER_EXTENSIONS="/ext1,/ext2"
AGENT_BROWSER_PROVIDER="your-cloud-browser-provider"
AGENT_BROWSER_STREAM_PORT="9223"
AGENT_BROWSER_HOME="/path/to/agent-browser"
AGENT_BROWSER_ENCRYPTION_KEY="<hex>"
AGENT_BROWSER_CONFIG="/path/to/config.json"
Configuration file
Create agent-browser.json in the project root for persistent settings:
{
"headed": true,
"proxy": "http://localhost:8080",
"profile": "./browser-data"
}
Priority (lowest to highest): ~/.agent-browser/config.json < ./agent-browser.json < env vars < CLI flags. Use --config <path> or AGENT_BROWSER_CONFIG env var for a custom config file. All CLI options map to camelCase keys (e.g., --executable-path -> "executablePath"). Boolean flags accept true/false values. Extensions from user and project configs are merged, not replaced.
Ref lifecycle (important)
Refs (@e1, @e2, etc.) are invalidated when the page changes. Always re-snapshot after:
- Clicking links or buttons that navigate
- Form submissions
- Dynamic content loading (dropdowns, modals)
agent-browser click @e5
agent-browser snapshot -i
agent-browser click @e1
Annotated screenshots (vision mode)
Use --annotate to take a screenshot with numbered labels overlaid on interactive elements. Each label [N] maps to ref @eN. This also caches refs, so you can interact with elements immediately without a separate snapshot.
agent-browser screenshot --annotate
agent-browser click @e2
Use annotated screenshots when:
- The page has unlabeled icon buttons or visual-only elements
- You need to verify visual layout or styling
- Canvas or chart elements are present (invisible to text snapshots)
- You need spatial reasoning about element positions
Timeouts and slow pages
The default Playwright timeout is 60 seconds for local browsers. For slow websites or large pages, use explicit waits instead of relying on the default timeout:
agent-browser wait --load networkidle
agent-browser wait "#content"
agent-browser wait @e1
agent-browser wait --url "**/dashboard"
agent-browser wait --fn "document.readyState === 'complete'"
agent-browser wait 5000
When dealing with consistently slow websites, use wait --load networkidle after open to ensure the page is fully loaded before taking a snapshot.
Example: Form submission
agent-browser open https://example.com/form
agent-browser snapshot -i
agent-browser fill @e1 "user@example.com"
agent-browser fill @e2 "password123"
agent-browser click @e3
agent-browser wait --load networkidle
agent-browser snapshot -i
Example: Authentication with saved state
agent-browser open https://app.example.com/login
agent-browser snapshot -i
agent-browser fill @e1 "username"
agent-browser fill @e2 "password"
agent-browser click @e3
agent-browser wait --url "**/dashboard"
agent-browser state save auth.json
agent-browser state load auth.json
agent-browser open https://app.example.com/dashboard
Session persistence
agent-browser --session-name myapp open https://app.example.com/login
agent-browser close
agent-browser --session-name myapp open https://app.example.com/dashboard
export AGENT_BROWSER_ENCRYPTION_KEY=$(openssl rand -hex 32)
agent-browser --session-name secure open https://app.example.com
agent-browser state list
agent-browser state show myapp-default.json
agent-browser state clear myapp
agent-browser state clean --older-than 7
Sessions (parallel browsers)
agent-browser --session test1 open site-a.com
agent-browser --session test2 open site-b.com
agent-browser session list
Always close your browser session when done to avoid leaked processes:
agent-browser close
agent-browser --session test1 close
If a previous session was not closed properly, the daemon may still be running. Use agent-browser close to clean it up before starting new work.
Data extraction
agent-browser open https://example.com/products
agent-browser snapshot -i
agent-browser get text @e5
agent-browser get text body > page.txt
agent-browser snapshot -i --json
agent-browser get text @e1 --json
Connect to existing Chrome
agent-browser --auto-connect open https://example.com
agent-browser --auto-connect snapshot
agent-browser --cdp 9222 snapshot
Local files (PDFs, HTML)
agent-browser --allow-file-access open file:///path/to/document.pdf
agent-browser --allow-file-access open file:///path/to/page.html
agent-browser screenshot output.png
iOS Simulator (Mobile Safari)
agent-browser device list
agent-browser -p ios --device "iPhone 16 Pro" open https://example.com
agent-browser -p ios snapshot -i
agent-browser -p ios tap @e1
agent-browser -p ios fill @e2 "text"
agent-browser -p ios swipe up
agent-browser -p ios screenshot mobile.png
agent-browser -p ios close
Requirements: macOS with Xcode, Appium (npm install -g appium && appium driver install xcuitest)
Real devices: Works with physical iOS devices if pre-configured. Use --device "<UDID>" where UDID is from xcrun xctrace list devices.
Debugging
agent-browser --headed open example.com
agent-browser --cdp 9222 snapshot
agent-browser connect 9222
agent-browser console
agent-browser console --clear
agent-browser errors
agent-browser errors --clear
agent-browser highlight @e1
agent-browser trace start
agent-browser trace stop trace.zip
agent-browser record start ./debug.webm
agent-browser record stop
agent-browser profiler start
agent-browser profiler stop trace.json
HTTPS Certificate Errors
For sites with self-signed or invalid certificates:
agent-browser open https://localhost:8443 --ignore-https-errors
Electron App Automation
Automate any Electron desktop app using agent-browser. Electron apps are built on Chromium and expose a Chrome DevTools Protocol (CDP) port that agent-browser can connect to, enabling the same snapshot-interact workflow used for web pages.
Core Workflow
- Launch the Electron app with remote debugging enabled
- Connect agent-browser to the CDP port
- Snapshot to discover interactive elements
- Interact using element refs
- Re-snapshot after navigation or state changes
open -a "Slack" --args --remote-debugging-port=9222
agent-browser connect 9222
agent-browser snapshot -i
agent-browser click @e5
agent-browser screenshot slack-desktop.png
Launching Electron Apps with CDP
Every Electron app supports the --remote-debugging-port flag since it's built into Chromium.
macOS
open -a "Slack" --args --remote-debugging-port=9222
open -a "Visual Studio Code" --args --remote-debugging-port=9223
open -a "Discord" --args --remote-debugging-port=9224
open -a "Figma" --args --remote-debugging-port=9225
open -a "Notion" --args --remote-debugging-port=9226
open -a "Spotify" --args --remote-debugging-port=9227
Linux
slack --remote-debugging-port=9222
code --remote-debugging-port=9223
discord --remote-debugging-port=9224
Windows
"C:\Users\%USERNAME%\AppData\Local\slack\slack.exe" --remote-debugging-port=9222
"C:\Users\%USERNAME%\AppData\Local\Programs\Microsoft VS Code\Code.exe" --remote-debugging-port=9223
Important: If the app is already running, quit it first, then relaunch with the flag. The --remote-debugging-port flag must be present at launch time.
Connecting to Electron Apps
agent-browser connect 9222
agent-browser --cdp 9222 snapshot -i
agent-browser --auto-connect snapshot -i
After connect, all subsequent commands target the connected app without needing --cdp.
Tab Management
Electron apps often have multiple windows or webviews. Use tab commands to list and switch between them:
agent-browser tab
agent-browser tab 2
agent-browser tab --url "*settings*"
Common Electron Patterns
Inspect and Navigate an App
open -a "Slack" --args --remote-debugging-port=9222
sleep 3
agent-browser connect 9222
agent-browser snapshot -i
agent-browser click @e10
agent-browser snapshot -i
Take Screenshots of Desktop Apps
agent-browser connect 9222
agent-browser screenshot app-state.png
agent-browser screenshot --full full-app.png
agent-browser screenshot --annotate annotated-app.png
Extract Data from a Desktop App
agent-browser connect 9222
agent-browser snapshot -i
agent-browser get text @e5
agent-browser snapshot --json > app-state.json
Fill Forms in Desktop Apps
agent-browser connect 9222
agent-browser snapshot -i
agent-browser fill @e3 "search query"
agent-browser press Enter
agent-browser wait 1000
agent-browser snapshot -i
Run Multiple Apps Simultaneously
Use named sessions only when you need to control multiple Electron apps at the same time. Each session spawns a separate Chromium process (~300MB RAM), so only create multiple sessions when explicitly required and close each one when done.
agent-browser --session slack connect 9222
agent-browser --session vscode connect 9223
agent-browser --session slack snapshot -i
agent-browser --session vscode snapshot -i
agent-browser --session slack close
agent-browser --session vscode close
Color Scheme
Playwright overrides the color scheme to light by default when connecting via CDP. To preserve dark mode:
agent-browser connect 9222
agent-browser --color-scheme dark snapshot -i
Or set it globally:
AGENT_BROWSER_COLOR_SCHEME=dark agent-browser connect 9222
Electron Troubleshooting
"Connection refused" or "Cannot connect"
- Make sure the app was launched with
--remote-debugging-port=NNNN
- If the app was already running, quit and relaunch with the flag
- Check that the port isn't in use by another process:
lsof -i :9222
App launches but connect fails
- Wait a few seconds after launch before connecting (
sleep 3)
- Some apps take time to initialize their webview
Elements not appearing in snapshot
- The app may use multiple webviews. Use
agent-browser tab to list targets and switch to the right one
- Use
agent-browser snapshot -i -C to include cursor-interactive elements (divs with onclick handlers)
Cannot type in input fields
- Try
agent-browser keyboard type "text" to type at the current focus without a selector
- Some Electron apps use custom input components; use
agent-browser keyboard inserttext "text" to bypass key events
CRITICAL:
- Screenshots are required for UI testing. Text snapshots do not catch layout issues, styling problems, alignment, z-index issues, etc. Always use
agent-browser screenshot --annotate to get numbered element labels overlaid on the screenshot, which enables both visual verification and immediate interaction via refs.
- Use a single browser session. Do not create multiple
--session names — each spawns a separate Chromium process (~300MB RAM). Use one session and call agent-browser open <new-url> to navigate between pages within it. If you must create a new session, close the previous one first with agent-browser --session <name> close. Exception: When controlling multiple Electron apps simultaneously on different CDP ports, multiple named sessions are acceptable — but only when the user explicitly needs it, and each session must be closed when no longer needed.
- When done, close your browser with
agent-browser close (or agent-browser --session <name> close) to free resources.
- Electron apps: quit first. If the Electron app is already running, you must quit it completely before relaunching with
--remote-debugging-port. The flag only takes effect at launch time.