Skip to main content

Chrome automation from the command line

Project description

Rodney: Chrome automation from the command line

PyPI Changelog Tests License

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:

  1. Detects the proxy credentials from environment variables
  2. Launches a local forwarding proxy that injects Proxy-Authorization headers into CONNECT requests
  3. 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:

  • start uses rod's launcher package to start Chrome with Leakless(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 Browser connection 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

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

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl (11.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl (11.0 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl (11.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl (11.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

rodney-0.1.0-py3-none-macosx_11_0_arm64.whl (11.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl (11.9 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b9e3d5cbff79cd12a9aeb67b2d6f7cbe8a5178b5a0c1d7852e7bcaae8c505ba2
MD5 f7e0f16dbaac084e37e10e19466a6d7d
BLAKE2b-256 86042ba484bc2c954d293c99a85fd847bce9f7c475870d1fd4ed91d06f53ad8f

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2494cbf4752b68949b1b41aee37c3fa877719a452c4dfb9b3c420487421e4c99
MD5 2454fb9ec0f6bd292cb0ef6f34201c16
BLAKE2b-256 fcf7937d78a480da64845a9fb7097ec98877026d4bd0bf7b56c99b0625663b0e

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 a84ba7ab09832b33ec0b08e02d72910ae1058d27201a423654b151220980ed40
MD5 4ef7917261e03b53162784f7ddd3b537
BLAKE2b-256 d503931c4c64f149d77f3975d43b1cc5f18b804f6d5df6f78738de2fbed66006

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 c7826e3380ec620e42580a77bf9b3b156410f83956291164231fe0a958ad97e8
MD5 bc6ec6f1f15e17b846f0fb8f4897ec8a
BLAKE2b-256 221e58158f3bbed0f1c89c386b7b94c6e6efa452fa1a93ead785a72088b7c619

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rodney-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9b08ccd342262ce995d87af26798b827ca53c9d69393e9743c6477b162dbd1d5
MD5 fe1c2e37c3c81097b87245de802eb281
BLAKE2b-256 e8d85583ed7b825a169a8886699df8dda216f0e48a1d42e37e101c7ff994468b

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for rodney-0.1.0-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 37a56f1fd2e0f79bad65600e5b68c1c55e5674646785aefa47f68d44a7cb57c5
MD5 d7ef2398635fe1d073a4451f1d274643
BLAKE2b-256 155500b5a38ecc6be0eadc70b4fc640658ccc1ea8612c0a2dde428056d1d3376

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page