use serde::Deserialize;
use url::Url;
use super::http::HttpClient;
use crate::error::WebDriverErrorInner;
use crate::{
Capabilities, SessionId, TimeoutConfiguration,
common::{
command::{Command, FormatRequestData},
config::WebDriverConfig,
},
prelude::WebDriverResult,
session::http::run_webdriver_cmd,
};
#[derive(Debug)]
pub struct StartedSession {
pub session_id: SessionId,
pub capabilities: Capabilities,
}
pub async fn start_session(
http_client: &dyn HttpClient,
server_url: &Url,
config: &WebDriverConfig,
capabilities: Capabilities,
) -> WebDriverResult<StartedSession> {
let request_data = Command::NewSession(capabilities.into()).format_request(&SessionId::null());
let v = match run_webdriver_cmd(http_client, &request_data, server_url, config).await {
Ok(x) => Ok(x),
Err(e) => {
if let WebDriverErrorInner::UnknownError(x) = &*e {
if x.status == 500 {
run_webdriver_cmd(http_client, &request_data, server_url, config).await
} else {
Err(e)
}
} else {
Err(e)
}
}
}?;
#[derive(Debug, Deserialize)]
struct ConnectionData {
#[serde(default, rename(deserialize = "sessionId"))]
session_id: String,
#[serde(default)]
capabilities: serde_json::Value,
}
#[derive(Debug, Deserialize)]
struct ConnectionResp {
#[serde(default, rename(deserialize = "sessionId"))]
session_id: String,
value: ConnectionData,
}
let resp: ConnectionResp = serde_json::from_value(v.body)?;
let data = resp.value;
let session_id = SessionId::from(if resp.session_id.is_empty() {
data.session_id
} else {
resp.session_id
});
let capabilities = match data.capabilities {
serde_json::Value::Object(map) => Capabilities::from(map),
_ => Capabilities::new(),
};
let request_data =
Command::SetTimeouts(TimeoutConfiguration::default()).format_request(&session_id);
run_webdriver_cmd(http_client, &request_data, server_url, config).await?;
Ok(StartedSession {
session_id,
capabilities,
})
}