diff --git a/README.md b/README.md index 5e86f55..9289f65 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,7 @@ async fn main() -> Result<(), Box> { let created = capture.create_session(Some(&CreateSessionOptions { max_ttl_seconds: Some(300), - proxy: None, - bypass_bot_detection: None, + ..Default::default() })).await?; let session_id = created["session"]["id"] .as_str() @@ -89,6 +88,40 @@ async fn main() -> Result<(), Box> { } ``` +#### CDP Sessions + +Set `cdp` to create a session that exposes a Chrome DevTools Protocol connect URL. +The API returns this as `connectUrl`; Rust code commonly stores it as `connect_url`. +CDP sessions cannot be combined with `proxy` or `bypassBotDetection`. + +```rust +use capture_rust::{Capture, CreateSessionOptions}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let capture = Capture::new("your_api_key".to_string(), "your_api_secret".to_string()); + + let created = capture.create_session(Some(&CreateSessionOptions { + cdp: Some(true), + max_ttl_seconds: Some(300), + ..Default::default() + })).await?; + + let session_id = created["session"]["id"] + .as_str() + .expect("session id"); + let connect_url = created["session"]["connectUrl"] + .as_str() + .expect("CDP connectUrl"); + + println!("CDP connect URL: {connect_url}"); + + capture.close_session(session_id).await?; + + Ok(()) +} +``` + ### Image Capture ```rust diff --git a/examples/cdp_session.rs b/examples/cdp_session.rs new file mode 100644 index 0000000..99fa19f --- /dev/null +++ b/examples/cdp_session.rs @@ -0,0 +1,33 @@ +use capture_rust::{Capture, CreateSessionOptions}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let api_key = + std::env::var("CAPTURE_KEY").expect("CAPTURE_KEY environment variable is required"); + let api_secret = + std::env::var("CAPTURE_SECRET").expect("CAPTURE_SECRET environment variable is required"); + + let capture = Capture::new(api_key, api_secret); + + let created = capture + .create_session(Some(&CreateSessionOptions { + cdp: Some(true), + max_ttl_seconds: Some(300), + ..Default::default() + })) + .await?; + + let session_id = created["session"]["id"] + .as_str() + .expect("created session id"); + let connect_url = created["session"]["connectUrl"] + .as_str() + .expect("CDP connectUrl"); + + println!("Session ID: {session_id}"); + println!("CDP connect URL: {connect_url}"); + + capture.close_session(session_id).await?; + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 8b42576..53e1e5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -495,6 +495,8 @@ pub struct CreateSessionOptions { pub proxy: Option, #[serde(rename = "bypassBotDetection", skip_serializing_if = "Option::is_none")] pub bypass_bot_detection: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub cdp: Option, } #[derive(Debug, Serialize)] @@ -1015,8 +1017,9 @@ mod tests { fn test_create_session_options_serialization() { let options = CreateSessionOptions { max_ttl_seconds: Some(300), - proxy: Some(true), + proxy: None, bypass_bot_detection: None, + cdp: Some(true), }; let value = serde_json::to_value(options).unwrap(); @@ -1024,8 +1027,16 @@ mod tests { value, serde_json::json!({ "maxTtlSeconds": 300, - "proxy": true + "cdp": true }) ); } + + #[test] + fn test_create_session_options_omit_empty_serialization() { + let options = CreateSessionOptions::default(); + + let value = serde_json::to_value(options).unwrap(); + assert_eq!(value, serde_json::json!({})); + } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index b61b562..b9f43c9 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -145,6 +145,7 @@ async fn test_live_session_screenshot_example_dot_com() { max_ttl_seconds: Some(120), proxy: None, bypass_bot_detection: None, + cdp: None, })) .await .expect("create session");