| Crates.io | viewpoint-cdp |
| lib.rs | viewpoint-cdp |
| version | 0.4.3 |
| created_at | 2025-12-26 15:54:35.552025+00 |
| updated_at | 2026-01-17 01:17:34.694649+00 |
| description | Low-level Chrome DevTools Protocol implementation over WebSocket |
| homepage | https://github.com/stephenstubbs/viewpoint |
| repository | https://github.com/stephenstubbs/viewpoint |
| max_upload_size | |
| id | 2005892 |
| size | 270,135 |
Low-level Chrome DevTools Protocol (CDP) implementation over WebSocket for Rust.
This crate provides the foundational CDP communication layer for the Viewpoint browser automation framework. It handles the WebSocket connection, message serialization, and protocol domain definitions.
Add to your Cargo.toml:
[dependencies]
viewpoint-cdp = "0.2"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use viewpoint_cdp::{CdpConnection, protocol::target_domain::GetTargetsParams};
#[tokio::main]
async fn main() -> Result<(), viewpoint_cdp::CdpError> {
// Connect to a running Chrome instance
let conn = CdpConnection::connect("ws://localhost:9222/devtools/browser/...").await?;
// Send a CDP command
let result: viewpoint_cdp::protocol::target_domain::GetTargetsResult =
conn.send_command("Target.getTargets", Some(GetTargetsParams::default()), None).await?;
for target in result.target_infos {
println!("Target: {} - {}", target.target_type, target.url);
}
Ok(())
}
Chrome exposes a JSON API for discovering the WebSocket URL:
use viewpoint_cdp::{discover_websocket_url, CdpConnectionOptions};
#[tokio::main]
async fn main() -> Result<(), viewpoint_cdp::CdpError> {
let options = CdpConnectionOptions::default();
let ws_url = discover_websocket_url("http://localhost:9222", &options).await?;
println!("WebSocket URL: {}", ws_url);
Ok(())
}
Commands are sent with optional session IDs for page-specific operations:
use viewpoint_cdp::CdpConnection;
use viewpoint_cdp::protocol::page::NavigateParams;
async fn example(conn: &CdpConnection, session_id: &str) -> Result<(), viewpoint_cdp::CdpError> {
// Browser-level command (no session)
let version: viewpoint_cdp::BrowserVersion = conn.send_command(
"Browser.getVersion",
None::<()>,
None // No session ID for browser-level commands
).await?;
// Page-level command (with session)
let result: viewpoint_cdp::protocol::page::NavigateResult = conn.send_command(
"Page.navigate",
Some(NavigateParams {
url: "https://example.com".to_string(),
referrer: None,
transition_type: None,
frame_id: None,
}),
Some(session_id) // Target a specific page
).await?;
Ok(())
}
Subscribe to CDP events using the event channel:
use viewpoint_cdp::CdpConnection;
async fn example(conn: &CdpConnection) -> Result<(), viewpoint_cdp::CdpError> {
let mut events = conn.subscribe_events();
// Process events in a loop
while let Ok(event) = events.recv().await {
match &event.method[..] {
"Page.loadEventFired" => {
println!("Page loaded!");
}
"Network.requestWillBeSent" => {
println!("Network request: {:?}", event.params);
}
_ => {}
}
}
Ok(())
}
Configure connection behavior with options:
use viewpoint_cdp::{CdpConnection, CdpConnectionOptions};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), viewpoint_cdp::CdpError> {
let options = CdpConnectionOptions::new()
.timeout(Duration::from_secs(30));
let conn = CdpConnection::connect_with_options(
"ws://localhost:9222/devtools/browser/...",
&options
).await?;
Ok(())
}
The protocol module contains typed definitions for CDP domains:
target_domain - Target management (pages, workers, service workers)page - Page navigation and lifecycleruntime - JavaScript executionnetwork - Network monitoring and interceptionfetch - Network request interceptiondom - DOM inspection and manipulationinput - Input device simulationemulation - Device and media emulationThe CdpError type covers all possible errors:
use viewpoint_cdp::{CdpConnection, CdpError};
async fn example() -> Result<(), CdpError> {
let result = CdpConnection::connect("ws://invalid:9999/...").await;
match result {
Ok(_conn) => println!("Connected!"),
Err(CdpError::ConnectionFailed(e)) => println!("Connection error: {}", e),
Err(CdpError::Protocol { code, message }) => {
println!("CDP error {}: {}", code, message);
}
Err(e) => println!("Other error: {}", e),
}
Ok(())
}
This crate is primarily used internally by viewpoint-core. For browser automation, use viewpoint-test or viewpoint-core instead, which provide a higher-level, more ergonomic API.
Use this crate directly if you need:
MIT