browser_commander/browser/
raw_cdp.rs1use std::borrow::Cow;
12
13use anyhow::{Context, Result};
14use async_trait::async_trait;
15use chromiumoxide::types::MethodId;
16use chromiumoxide::{Command, Method};
17use serde::{Serialize, Serializer};
18use serde_json::Value;
19
20use crate::browser::chromiumoxide_adapter::ChromiumoxidePage;
21use crate::fingerprint::apply::CdpTransport;
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct RawCdpCommand {
26 method: String,
27 params: Value,
28}
29
30impl RawCdpCommand {
31 pub fn new(method: impl Into<String>, params: Value) -> Self {
33 Self {
34 method: method.into(),
35 params,
36 }
37 }
38}
39
40impl Serialize for RawCdpCommand {
41 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
42 self.params.serialize(serializer)
46 }
47}
48
49impl Method for RawCdpCommand {
50 fn identifier(&self) -> MethodId {
51 Cow::Owned(self.method.clone())
52 }
53}
54
55impl Command for RawCdpCommand {
56 type Response = Value;
59}
60
61#[async_trait]
62impl CdpTransport for ChromiumoxidePage {
63 async fn send(&self, method: &str, params: Value) -> Result<Value> {
64 let response = self
65 .raw_page()
66 .execute(RawCdpCommand::new(method, params))
67 .await
68 .with_context(|| format!("{method} failed"))?;
69 Ok(response.result)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use serde_json::json;
77
78 #[test]
79 fn carries_the_method_name_out_of_band() {
80 let command = RawCdpCommand::new("Emulation.setLocaleOverride", json!({ "locale": "de" }));
81
82 assert_eq!(command.identifier(), "Emulation.setLocaleOverride");
83 assert_eq!(command.domain_name(), "Emulation");
84 }
85
86 #[test]
87 fn serializes_to_the_params_object_alone() {
88 let command = RawCdpCommand::new("Page.enable", json!({}));
91
92 assert_eq!(
93 serde_json::to_value(&command).expect("serialize"),
94 json!({})
95 );
96 }
97
98 #[test]
99 fn keeps_the_params_exactly_as_given() {
100 let params = json!({ "source": "globalThis.x = 1;", "nested": { "a": [1, 2] } });
101 let command = RawCdpCommand::new("Page.addScriptToEvaluateOnNewDocument", params.clone());
102
103 assert_eq!(serde_json::to_value(&command).expect("serialize"), params);
104 }
105}