use std::sync::Arc;
use http::Method;
use serde_json::{Value, json};
use super::Transport;
use crate::common::command::FormatRequestData;
use crate::common::requestdata::RequestData;
use crate::common::types::SessionId;
use crate::error::WebDriverResult;
use crate::session::handle::SessionHandle;
#[derive(Debug, Clone)]
pub(crate) struct HttpTransport {
pub(crate) handle: Arc<SessionHandle>,
}
impl HttpTransport {
pub(crate) fn new(handle: Arc<SessionHandle>) -> Self {
Self {
handle,
}
}
pub(crate) fn handle(&self) -> &Arc<SessionHandle> {
&self.handle
}
}
impl Transport for HttpTransport {
async fn send_raw(&self, method: &str, params: Value) -> WebDriverResult<Value> {
let params = if params.is_null() {
json!({})
} else {
params
};
let cmd = ExecuteCdp {
method: method.to_string(),
params,
};
let response = self.handle.cmd(cmd).await?;
response.value_json()
}
}
#[derive(Debug)]
struct ExecuteCdp {
method: String,
params: Value,
}
impl FormatRequestData for ExecuteCdp {
fn format_request(&self, session_id: &SessionId) -> RequestData {
RequestData::new(Method::POST, format!("/session/{}/goog/cdp/execute", session_id))
.add_body(json!({
"cmd": self.method,
"params": self.params,
}))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::common::types::SessionId;
fn body_of(cmd: &ExecuteCdp) -> Value {
let session = SessionId::from("S1".to_string());
cmd.format_request(&session).body.clone().unwrap_or(Value::Null)
}
#[test]
fn format_request_routes_to_goog_cdp_execute() {
let session = SessionId::from("XYZ".to_string());
let cmd = ExecuteCdp {
method: "Browser.getVersion".to_string(),
params: json!({}),
};
let req = cmd.format_request(&session);
assert_eq!(&*req.uri, "/session/XYZ/goog/cdp/execute");
}
#[test]
fn format_request_carries_cmd_and_params() {
let cmd = ExecuteCdp {
method: "Network.setExtraHTTPHeaders".to_string(),
params: json!({"headers": {"X": "Y"}}),
};
let body = body_of(&cmd);
assert_eq!(body["cmd"], "Network.setExtraHTTPHeaders");
assert_eq!(body["params"]["headers"]["X"], "Y");
}
#[test]
fn format_request_does_not_mutate_null_params_at_format_time() {
let cmd = ExecuteCdp {
method: "X.y".to_string(),
params: Value::Null,
};
let body = body_of(&cmd);
assert!(body["params"].is_null());
}
}