Chrome automation from the command line
Project description
Rodney: Chrome automation from the command line
A Go CLI tool that drives a persistent headless Chrome instance using the rod browser automation library. Each command connects to the same long-running Chrome process, making it easy to script multi-step browser interactions from shell scripts or interactive use.
Architecture
rodney start → launches Chrome (headless, persists after CLI exits)
saves WebSocket debug URL to ~/.rodney/state.json
rodney open URL → connects to running Chrome via WebSocket
navigates the active tab, disconnects
rodney js EXPR → connects, evaluates JS, prints result, disconnects
rodney stop → connects and shuts down Chrome, cleans up state
Each CLI invocation is a short-lived process. Chrome runs independently and tabs persist between commands.
Building
go build -o rodney .
Requires:
- Go 1.21+
- Google Chrome or Chromium installed (or set
ROD_CHROME_BIN=/path/to/chrome)
Usage
Start/stop the browser
rodney start # Launch headless Chrome
rodney status # Show browser info and active page
rodney stop # Shut down Chrome
Navigate
rodney open https://example.com # Navigate to URL
rodney open example.com # http:// prefix added automatically
rodney back # Go back
rodney forward # Go forward
rodney reload # Reload page
Extract information
rodney url # Print current URL
rodney title # Print page title
rodney text "h1" # Print text content of element
rodney html "div.content" # Print outer HTML of element
rodney html # Print full page HTML
rodney attr "a#link" href # Print attribute value
rodney pdf output.pdf # Save page as PDF
Run JavaScript
rodney js document.title # Evaluate expression
rodney js "1 + 2" # Math
rodney js 'document.querySelector("h1").textContent' # DOM queries
rodney js '[1,2,3].map(x => x * 2)' # Returns pretty-printed JSON
rodney js 'document.querySelectorAll("a").length' # Count elements
The expression is automatically wrapped in () => { return (expr); }.
Interact with elements
rodney click "button#submit" # Click element
rodney input "#search" "query" # Type into input field
rodney clear "#search" # Clear input field
rodney select "#dropdown" "value" # Select dropdown by value
rodney submit "form#login" # Submit a form
rodney hover ".menu-item" # Hover over element
rodney focus "#email" # Focus element
Wait for conditions
rodney wait ".loaded" # Wait for element to appear and be visible
rodney waitload # Wait for page load event
rodney waitstable # Wait for DOM to stop changing
rodney waitidle # Wait for network to be idle
rodney sleep 2.5 # Sleep for N seconds
Screenshots
rodney screenshot # Save as screenshot.png
rodney screenshot page.png # Save to specific file
rodney screenshot-el ".chart" chart.png # Screenshot specific element
Manage tabs
rodney pages # List all tabs (* marks active)
rodney newpage https://... # Open URL in new tab
rodney page 1 # Switch to tab by index
rodney closepage 1 # Close tab by index
rodney closepage # Close active tab
Query elements
rodney exists ".loading" # Exit 0 if exists, exit 1 if not
rodney count "li.item" # Print number of matching elements
rodney visible "#modal" # Exit 0 if visible, exit 1 if not
Shell scripting examples
# Wait for page to load and extract data
rodney start
rodney open https://example.com
rodney waitstable
title=$(rodney title)
echo "Page: $title"
# Conditional logic based on element presence
if rodney exists ".error-message"; then
rodney text ".error-message"
fi
# Loop through pages
for url in page1 page2 page3; do
rodney open "https://example.com/$url"
rodney waitstable
rodney screenshot "${url}.png"
done
rodney stop
Configuration
| Environment Variable | Default | Description |
|---|---|---|
ROD_CHROME_BIN |
/usr/bin/google-chrome |
Path to Chrome/Chromium binary |
ROD_TIMEOUT |
30 |
Default timeout in seconds for element queries |
HTTPS_PROXY / HTTP_PROXY |
(none) | Authenticated proxy auto-detected on start |
State is stored in ~/.rodney/state.json. Chrome user data is stored in ~/.rodney/chrome-data/.
Proxy support
In environments with authenticated HTTP proxies (e.g., HTTPS_PROXY=http://user:pass@host:port), rodney start automatically:
- Detects the proxy credentials from environment variables
- Launches a local forwarding proxy that injects
Proxy-Authorizationheaders into CONNECT requests - Configures Chrome to use the local proxy
This is necessary because Chrome cannot natively authenticate to proxies during HTTPS tunnel (CONNECT) establishment. The local proxy runs as a background process and is automatically cleaned up by rodney stop.
See claude-code-chrome-proxy.md for detailed technical notes.
How it works
The tool uses the rod Go library which communicates with Chrome via the DevTools Protocol (CDP) over WebSocket. Key implementation details:
startuses rod'slauncherpackage to start Chrome withLeakless(false)so Chrome survives after the CLI exits- Proxy auth handled via a local forwarding proxy that bridges Chrome to authenticated upstream proxies
- State persistence via a JSON file containing the WebSocket debug URL and Chrome PID
- Each command creates a new rod
Browserconnection to the same Chrome instance, executes the operation, and disconnects - Element queries use rod's built-in auto-wait with a configurable timeout (default 30s)
- JS evaluation wraps user expressions in arrow functions as required by rod's
Eval
Dependencies
- github.com/go-rod/rod v0.116.2 - Chrome DevTools Protocol automation
Commands reference
| Command | Arguments | Description |
|---|---|---|
start |
Launch headless Chrome | |
stop |
Shut down Chrome | |
status |
Show browser status | |
open |
<url> |
Navigate to URL |
back |
Go back in history | |
forward |
Go forward in history | |
reload |
Reload current page | |
url |
Print current URL | |
title |
Print page title | |
html |
[selector] |
Print HTML (page or element) |
text |
<selector> |
Print element text content |
attr |
<selector> <name> |
Print attribute value |
pdf |
[file] |
Save page as PDF |
js |
<expression> |
Evaluate JavaScript |
click |
<selector> |
Click element |
input |
<selector> <text> |
Type into input |
clear |
<selector> |
Clear input |
select |
<selector> <value> |
Select dropdown value |
submit |
<selector> |
Submit form |
hover |
<selector> |
Hover over element |
focus |
<selector> |
Focus element |
wait |
<selector> |
Wait for element to appear |
waitload |
Wait for page load | |
waitstable |
Wait for DOM stability | |
waitidle |
Wait for network idle | |
sleep |
<seconds> |
Sleep N seconds |
screenshot |
[file] |
Page screenshot |
screenshot-el |
<selector> [file] |
Element screenshot |
pages |
List tabs | |
page |
<index> |
Switch tab |
newpage |
[url] |
Open new tab |
closepage |
[index] |
Close tab |
exists |
<selector> |
Check element exists (exit code) |
count |
<selector> |
Count matching elements |
visible |
<selector> |
Check element visible (exit code) |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 11.4 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9e3d5cbff79cd12a9aeb67b2d6f7cbe8a5178b5a0c1d7852e7bcaae8c505ba2
|
|
| MD5 |
f7e0f16dbaac084e37e10e19466a6d7d
|
|
| BLAKE2b-256 |
86042ba484bc2c954d293c99a85fd847bce9f7c475870d1fd4ed91d06f53ad8f
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
b9e3d5cbff79cd12a9aeb67b2d6f7cbe8a5178b5a0c1d7852e7bcaae8c505ba2 - Sigstore transparency entry: 934253336
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 11.0 MB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2494cbf4752b68949b1b41aee37c3fa877719a452c4dfb9b3c420487421e4c99
|
|
| MD5 |
2454fb9ec0f6bd292cb0ef6f34201c16
|
|
| BLAKE2b-256 |
fcf7937d78a480da64845a9fb7097ec98877026d4bd0bf7b56c99b0625663b0e
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
2494cbf4752b68949b1b41aee37c3fa877719a452c4dfb9b3c420487421e4c99 - Sigstore transparency entry: 934253311
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 11.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a84ba7ab09832b33ec0b08e02d72910ae1058d27201a423654b151220980ed40
|
|
| MD5 |
4ef7917261e03b53162784f7ddd3b537
|
|
| BLAKE2b-256 |
d503931c4c64f149d77f3975d43b1cc5f18b804f6d5df6f78738de2fbed66006
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl -
Subject digest:
a84ba7ab09832b33ec0b08e02d72910ae1058d27201a423654b151220980ed40 - Sigstore transparency entry: 934253140
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 11.0 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7826e3380ec620e42580a77bf9b3b156410f83956291164231fe0a958ad97e8
|
|
| MD5 |
bc6ec6f1f15e17b846f0fb8f4897ec8a
|
|
| BLAKE2b-256 |
221e58158f3bbed0f1c89c386b7b94c6e6efa452fa1a93ead785a72088b7c619
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl -
Subject digest:
c7826e3380ec620e42580a77bf9b3b156410f83956291164231fe0a958ad97e8 - Sigstore transparency entry: 934253382
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file rodney-0.1.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 11.5 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b08ccd342262ce995d87af26798b827ca53c9d69393e9743c6477b162dbd1d5
|
|
| MD5 |
fe1c2e37c3c81097b87245de802eb281
|
|
| BLAKE2b-256 |
e8d85583ed7b825a169a8886699df8dda216f0e48a1d42e37e101c7ff994468b
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
9b08ccd342262ce995d87af26798b827ca53c9d69393e9743c6477b162dbd1d5 - Sigstore transparency entry: 934253197
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl.
File metadata
- Download URL: rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl
- Upload date:
- Size: 11.9 MB
- Tags: Python 3, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37a56f1fd2e0f79bad65600e5b68c1c55e5674646785aefa47f68d44a7cb57c5
|
|
| MD5 |
d7ef2398635fe1d073a4451f1d274643
|
|
| BLAKE2b-256 |
155500b5a38ecc6be0eadc70b4fc640658ccc1ea8612c0a2dde428056d1d3376
|
Provenance
The following attestation bundles were made for rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl:
Publisher:
publish.yml on simonw/rodney
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl -
Subject digest:
37a56f1fd2e0f79bad65600e5b68c1c55e5674646785aefa47f68d44a7cb57c5 - Sigstore transparency entry: 934253257
- Sigstore integration time:
-
Permalink:
simonw/rodney@a15de2e7336554b037076376fa389ae9d888ef7c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a15de2e7336554b037076376fa389ae9d888ef7c -
Trigger Event:
release
-
Statement type: