use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TargetInfo {
pub target_id: String,
#[serde(rename = "type")]
pub target_type: String,
pub title: String,
pub url: String,
pub attached: bool,
pub browser_context_id: Option<String>,
pub opener_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct CreateBrowserContextParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub dispose_on_detach: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub proxy_server: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub proxy_bypass_list: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateBrowserContextResult {
pub browser_context_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DisposeBrowserContextParams {
pub browser_context_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTargetParams {
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub height: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub browser_context_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub background: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub new_window: Option<bool>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTargetResult {
pub target_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AttachToTargetParams {
pub target_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub flatten: Option<bool>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AttachToTargetResult {
pub session_id: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CloseTargetParams {
pub target_id: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CloseTargetResult {
pub success: bool,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DetachFromTargetParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct GetTargetsParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<Vec<TargetFilter>>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TargetFilter {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub target_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exclude: Option<bool>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetTargetsResult {
pub target_infos: Vec<TargetInfo>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetBrowserContextsResult {
pub browser_context_ids: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TargetCreatedEvent {
pub target_info: TargetInfo,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TargetDestroyedEvent {
pub target_id: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AttachedToTargetEvent {
pub session_id: String,
pub target_info: TargetInfo,
pub waiting_for_debugger: bool,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TargetInfoChangedEvent {
pub target_info: TargetInfo,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetDiscoverTargetsParams {
pub discover: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_target_info_changed_event_deserialization() {
let json = r#"{
"targetInfo": {
"targetId": "ABC123",
"type": "page",
"title": "Example Page",
"url": "https://example.com",
"attached": true,
"browserContextId": "context-456"
}
}"#;
let event: TargetInfoChangedEvent = serde_json::from_str(json).unwrap();
assert_eq!(event.target_info.target_id, "ABC123");
assert_eq!(event.target_info.target_type, "page");
assert_eq!(event.target_info.title, "Example Page");
assert_eq!(event.target_info.url, "https://example.com");
assert!(event.target_info.attached);
assert_eq!(
event.target_info.browser_context_id,
Some("context-456".to_string())
);
}
#[test]
fn test_target_info_changed_event_without_context_id() {
let json = r#"{
"targetInfo": {
"targetId": "DEF789",
"type": "page",
"title": "Default Context Page",
"url": "about:blank",
"attached": false
}
}"#;
let event: TargetInfoChangedEvent = serde_json::from_str(json).unwrap();
assert_eq!(event.target_info.target_id, "DEF789");
assert!(!event.target_info.attached);
assert!(event.target_info.browser_context_id.is_none());
assert!(event.target_info.opener_id.is_none());
}
#[test]
fn test_target_created_event_deserialization() {
let json = r#"{
"targetInfo": {
"targetId": "target-123",
"type": "page",
"title": "New Tab",
"url": "chrome://newtab/",
"attached": false,
"openerId": "opener-456"
}
}"#;
let event: TargetCreatedEvent = serde_json::from_str(json).unwrap();
assert_eq!(event.target_info.target_id, "target-123");
assert_eq!(event.target_info.opener_id, Some("opener-456".to_string()));
}
}