Browser automation CLI — wraps cdpwave and bidiwave, no Node.js, no Chromium download
Project description
wavexis
Browser automation CLI — wraps cdpwave and bidiwave. No Node.js, no Chromium download. Uses your existing Chrome/Edge. 100+ commands across CDP and BiDi backends with full parity.
Why wavexis?
wavexis is a command-line tool for browser automation. It wraps the cdpwave (Chrome DevTools Protocol) and bidiwave (WebDriver BiDi) libraries, exposing their capabilities through a single unified CLI. You don't need Node.js, Playwright, or a separate Chromium download — wavexis launches your existing Chrome or Edge installation directly.
Core concepts
- Backend — The browser driver that executes commands. wavexis supports two backends with full feature parity: CDP (default, via cdpwave) and BiDi (via bidiwave). Both implement all 100+ methods, so you can switch with
--backend bidiwithout losing functionality. - Action — A single operation (screenshot, eval, click, etc.). Each action maps to a CLI command or a step in a multi-action YAML config.
- Multi-action — A YAML config that chains multiple actions in sequence on a single browser session. Avoids the overhead of launching a browser per action.
- Serve mode — An HTTP API server that exposes all wavexis commands as REST endpoints with WebSocket streaming for real-time events.
Install
pip install wavexis[cdp]
Docker
Serve mode in a container with Chromium pre-installed:
docker run -p 8080:8080 ghcr.io/mathiaspaulenko/wavexis:latest
curl -X POST http://localhost:8080/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' \
-o screenshot.png
Build locally:
docker build -t wavexis .
docker run -p 8080:8080 wavexis
Quick start
# Take a screenshot
wavexis screenshot https://example.com -o out.png
# Full-page screenshot
wavexis screenshot https://example.com -o full.png --full-page
# Screenshot of a specific element
wavexis screenshot https://example.com -o el.png --selector "h1"
# Generate a PDF
wavexis pdf https://example.com -o out.pdf --paper a4
# Evaluate JavaScript
wavexis eval https://example.com -e "document.title"
# Scrape page content
wavexis scrape https://example.com --selector "article"
# Emulate a device
wavexis device https://example.com --preset iphone-15 -o shot.png
REPL
Interactive REPL for live browser sessions. Launch a non-headless browser and execute commands in real time:
wavexis repl
Inside the REPL:
wavexis> navigate https://example.com
wavexis> screenshot
wavexis> eval document.title
wavexis> click #login-button
wavexis> type #username admin@example.com
wavexis> cookies
wavexis> url
wavexis> title
wavexis> wait 2
wavexis> back
wavexis> help
wavexis> exit
Supported commands: navigate, screenshot, eval, click, type, fill, hover, key, cookies, url, title, wait, back, forward, reload, help, exit/quit.
Init wizard
Generate a wavexis.yaml config interactively from predefined templates:
wavexis init
Or generate directly with flags:
wavexis init -t multi-step -u https://example.com -s "#login" --text "admin" -o config.yaml
List available templates:
wavexis init --list
Templates: screenshot, pdf, scrape, eval, multi-step, cookies, har.
CI assertions
Use --assert with eval to create CI gates that pass or fail based on the result:
# Equality check — exit 0 if title matches, 1 otherwise
wavexis eval https://example.com -e "document.title" --assert "== Expected Title"
# Inequality
wavexis eval https://example.com -e "document.title" --assert "!= Old Title"
# Substring
wavexis eval https://example.com -e "document.body.innerText" --assert "contains Welcome"
# Regex
wavexis eval https://example.com -e "document.title" --assert "matches Error \\d+"
Output includes assert:, result:, and status: PASS/FAIL. Exit code 0 on pass, 1 on fail.
Performance metrics
Capture Core Web Vitals and performance data:
# Key metrics (LCP, FCP, CLS, TTFB) with human-readable summary
wavexis perf https://example.com
# CPU trace
wavexis perf https://example.com -m trace -d 5000 -o trace.json
# CPU profile
wavexis perf https://example.com -m profile -o profile.json
# JS code coverage
wavexis perf https://example.com -m coverage -o coverage.json
# CSS coverage
wavexis perf https://example.com -m css-coverage -o css-coverage.json
# Heap snapshot
wavexis perf https://example.com -m heap-snapshot -o heap.json
Metrics: metrics (default), trace, profile, heap-snapshot, coverage, css-coverage.
Auth
Store and use browser credentials for authenticated scraping:
# Save credentials
wavexis auth save mysite --user admin --pass secret123
# Use saved credentials
wavexis auth use mysite --url https://example.com/login
# List saved profiles
wavexis auth list
# Delete a profile
wavexis auth delete mysite
Record & Replay
Record a browser session and replay it later:
# Record a session
wavexis record start https://example.com -o session.json
# Replay a recorded session
wavexis record replay session.json
# List recorded sessions
wavexis record list
Serve mode
HTTP API server powered by aiohttp with WebSocket streaming:
wavexis serve --host 0.0.0.0 --port 8080
curl -X POST http://localhost:8080/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' \
-o screenshot.png
WebSocket endpoint at /ws for real-time streaming of screenshots, console events, and navigation:
import aiohttp, json, asyncio
async def stream():
async with aiohttp.ClientSession() as s:
async with s.ws_connect("ws://localhost:8080/ws") as ws:
await ws.send_json({"url": "https://example.com", "events": ["screenshot"], "interval": 2.0})
async for msg in ws:
data = json.loads(msg.data)
if data["type"] == "screenshot":
print(f"Got frame ({len(data['data'])} bytes)")
asyncio.run(stream())
Multi-action
Create a YAML config and run multiple actions in sequence on a single browser session:
# actions.yml
actions:
- screenshot:
url: https://example.com
full_page: true
- eval:
url: https://example.com
expression: document.title
- pdf:
url: https://example.com
paper: a4
wavexis multi actions.yml
Watch mode
Re-execute the config automatically when the file changes. Useful for iterative config development:
wavexis multi actions.yml --watch
Dry run
Validate the config and show the planned actions without launching a browser:
wavexis multi actions.yml --dry-run
Supported action types
| Action | Key parameters |
|---|---|
screenshot |
url, full_page, format |
pdf |
url, paper, landscape |
eval |
url, expression, await_promise |
dom |
url, action, selector |
navigate |
url |
scrape |
urls, expression |
click |
url, selector |
type |
url, selector, text |
cookies |
url, action (get/set/delete/clear), cookie |
headers |
url, action (set-headers/set-user-agent), headers, user_agent |
Cookies and headers in multi
actions:
- cookies:
url: https://example.com
action: get
- headers:
url: https://example.com
action: set-headers
headers:
X-Custom-Header: my-value
- screenshot:
url: https://example.com
Backends
wavexis supports two backends with full feature parity:
- CDP (cdpwave) — default, Chrome DevTools Protocol.
pip install wavexis[cdp] - BiDi (bidiwave) — WebDriver BiDi protocol, uses BiDi native + JS workarounds + CDP bridge.
pip install wavexis[bidi]
Select with --backend:
wavexis --backend bidi screenshot https://example.com -o out.png
Feature parity (v1.7.0)
Both backends implement all methods. BiDi uses native BiDi commands, JS workarounds
(script.evaluate), or the CDP bridge (browser.cdp.sendCommand) when needed.
| Category | Methods | BiDi impl |
|---|---|---|
| Navigation | navigate, go_back, go_forward, reload, stop_loading, wait_for |
BiDi native |
| Screenshots | screenshot, screenshot_selector, pdf, screencast |
BiDi + CDP |
| Tabs | list_tabs, new_tab, close_tab, activate_tab |
BiDi native |
| DOM | dom_get, dom_query, dom_set_attr, dom_get_attr, dom_remove, dom_focus, dom_scroll, dom_snapshot |
BiDi + JS |
| Cookies | get_cookies, set_cookie, delete_cookie, clear_cookies |
BiDi native |
| Network | set_headers, set_user_agent, block_requests, throttle_network, set_cache_disabled, intercept_requests, mock_response |
BiDi + CDP |
| Emulation | emulate_device, set_viewport, set_geolocation, set_timezone, set_dark_mode, set_locale, set_touch_emulation, set_cpu_throttle, set_sensors |
BiDi + CDP |
| Browser | browser_version, eval, raw, capture_console, capture_logs |
BiDi native |
| Security | get_security_state, ignore_cert_errors |
CDP bridge |
| Contexts | new_context, list_contexts, close_context, get_window_bounds, set_window_bounds |
BiDi native |
| Input | click, type_text, fill, select_option, hover, key_press, drag, tap |
JS + BiDi |
| Storage | storage_get, storage_set, storage_clear, storage_list |
BiDi native |
| Dialogs | dialog_accept, dialog_dismiss, grant_permission, reset_permissions |
BiDi native |
| Performance | perf_metrics, perf_coverage, perf_css_coverage, perf_trace, perf_profile, perf_heap_snapshot |
CDP bridge |
| CSS | css_get_styles, css_get_computed, css_get_stylesheets, css_get_rules |
JS |
| Overlay | overlay_highlight, overlay_clear |
JS |
| Accessibility | a11y_tree, a11y_node, a11y_ancestors |
CDP bridge |
| Downloads | intercept_download |
CDP bridge |
| Debug | debug_set_breakpoint, debug_set_breakpoint_function, debug_remove_breakpoint, debug_step_over, debug_step_into, debug_step_out, debug_pause, debug_resume, debug_get_listeners |
CDP bridge |
| Cache Storage | cache_storage_list, cache_storage_entries, cache_storage_delete |
JS |
| IndexedDB | indexeddb_list, indexeddb_get_data, indexeddb_clear |
CDP bridge |
| Service Workers | sw_list, sw_unregister, sw_update |
JS |
| Animations | animation_list, animation_pause, animation_play, animation_seek |
JS |
| HAR | capture_har |
CDP bridge |
| WebAuthn | webauthn_add_virtual_authenticator, webauthn_remove_authenticator, webauthn_add_credential, webauthn_get_credentials |
CDP bridge |
| WebAudio | webaudio_get_contexts, webaudio_get_context |
CDP bridge |
| Media | media_get_players, media_get_messages |
CDP bridge |
| Cast | cast_list, cast_start_tab, cast_stop |
CDP bridge |
| Bluetooth | bluetooth_emulate, bluetooth_stop |
CDP bridge |
Commands
wavexis provides 100+ CLI commands organized into categories:
| Category | Commands |
|---|---|
| Capture | screenshot, pdf, screencast, scrape |
| Navigate | navigate, back, forward, reload, stop, tabs |
| Console | console (with --capture, --format), logs, har |
| Cookies | cookies (get/set/delete/clear) |
| Network | headers, user-agent, block, throttle, cache, intercept, mock |
| Browser | open, close, version |
| Emulation | device, viewport, geolocation, timezone, dark-mode |
| Input | click, type, fill, select, hover, key, drag, tap |
| CSS | css-styles, css-computed, css-rules |
| Debug | debug-break, debug-step, debug-pause, debug-resume |
| Performance | perf (metrics, trace, profile, coverage, heap-snapshot, css-coverage) |
| Storage | storage (get/set/clear/list), indexeddb |
| Advanced | sw, animation, record, replay, webauthn, cast, bluetooth |
| Auth | auth save, auth use, auth list, auth delete |
| Serve | serve (HTTP API server) |
| Interactive | repl (live browser REPL), init (config wizard) |
| Utility | multi (with --watch, --dry-run), raw, backends, install_check, completions |
Run wavexis --help for the full list.
Comparison
| Feature | wavexis | shot-scraper | Playwright |
|---|---|---|---|
| Language | Python | Python | Multi |
| Node.js required | No | Yes | Yes |
| Chromium download | No | Yes | Yes |
| CDP backend | Yes | Yes | Yes |
| BiDi backend | Yes | No | No |
| BiDi/CDP parity | Yes | N/A | No |
| CLI-first | Yes | Yes | No |
| Multi-action YAML | Yes | No | No |
| Device emulation | Yes | Yes | Yes |
| HAR capture | Yes | No | Yes |
| PDF generation | Yes | Yes | Yes |
| Network throttling | Yes | No | Yes |
| Cookie management | Yes | No | Yes |
| Session recording | Yes | No | No |
| Auth profiles | Yes | No | No |
| Serve mode (HTTP API) | Yes | No | No |
| Debug breakpoints | Yes | No | No |
| WebAuthn | Yes | No | No |
| Shell completions | Yes | No | No |
| Interactive REPL | Yes | No | No |
| Config wizard | Yes | No | No |
| CI assertions | Yes | No | No |
| Performance metrics | Yes | No | No |
| Watch mode | Yes | No | No |
Documentation
Full docs at mathiaspaulenko.github.io/wavexis.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 wavexis-2.2.0.tar.gz.
File metadata
- Download URL: wavexis-2.2.0.tar.gz
- Upload date:
- Size: 185.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ee504589ab836c849bb61214de9e60bc4811c3d1a19ac6629adf74199097c89
|
|
| MD5 |
14a06f1713f5486696bceab771f38eaf
|
|
| BLAKE2b-256 |
7f07e32b8634b36053b23ac6a1984cd30309d4ce6820ec6a6e734f9be80cd7e4
|
Provenance
The following attestation bundles were made for wavexis-2.2.0.tar.gz:
Publisher:
release.yml on MathiasPaulenko/wavexis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wavexis-2.2.0.tar.gz -
Subject digest:
5ee504589ab836c849bb61214de9e60bc4811c3d1a19ac6629adf74199097c89 - Sigstore transparency entry: 2092310648
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/wavexis@892080320f6790d39cd251e46e2758ddc76ce6fd -
Branch / Tag:
refs/tags/v2.2.0 - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@892080320f6790d39cd251e46e2758ddc76ce6fd -
Trigger Event:
push
-
Statement type:
File details
Details for the file wavexis-2.2.0-py3-none-any.whl.
File metadata
- Download URL: wavexis-2.2.0-py3-none-any.whl
- Upload date:
- Size: 142.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cef3ca90688a381f9859593e6e354369bcc1fd8261b81ba53bc943bcc455a20
|
|
| MD5 |
6a78d05fbf623d74c44ebc2a11a34d88
|
|
| BLAKE2b-256 |
a031fa53379d32f0b395229c14b7de6d1e5ce918029a2d0e56c74f983e614a85
|
Provenance
The following attestation bundles were made for wavexis-2.2.0-py3-none-any.whl:
Publisher:
release.yml on MathiasPaulenko/wavexis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wavexis-2.2.0-py3-none-any.whl -
Subject digest:
5cef3ca90688a381f9859593e6e354369bcc1fd8261b81ba53bc943bcc455a20 - Sigstore transparency entry: 2092310807
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/wavexis@892080320f6790d39cd251e46e2758ddc76ce6fd -
Branch / Tag:
refs/tags/v2.2.0 - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@892080320f6790d39cd251e46e2758ddc76ce6fd -
Trigger Event:
push
-
Statement type: