use std::marker::PhantomData;
use std::sync::{Arc, Mutex};
use log::error;
use serde::Serialize;
use serde_json::Value;
use crate::common::config::WebDriverConfig;
use crate::http::connection_sync::{HttpClientCreateParams, WebDriverHttpClientSync};
use crate::http::reqwest_sync::ReqwestDriverSync;
use crate::webdrivercommands::{start_session, WebDriverCommands};
use crate::{common::command::Command, error::WebDriverResult, DesiredCapabilities};
use crate::{SessionId, WebDriverSession};
use std::time::Duration;
pub type WebDriver = GenericWebDriver<ReqwestDriverSync>;
#[derive(Debug)]
pub struct GenericWebDriver<T: WebDriverHttpClientSync> {
pub session: WebDriverSession,
capabilities: Value,
quit_on_drop: bool,
phantom: PhantomData<T>,
}
impl<T: 'static> GenericWebDriver<T>
where
T: WebDriverHttpClientSync,
{
pub fn new<C>(server_url: &str, capabilities: C) -> WebDriverResult<Self>
where
C: Serialize,
{
Self::new_with_timeout(server_url, capabilities, Some(Duration::from_secs(120)))
}
pub fn new_with_timeout<C>(
server_url: &str,
capabilities: C,
timeout: Option<Duration>,
) -> WebDriverResult<Self>
where
C: Serialize,
{
let params = HttpClientCreateParams {
server_url: server_url.to_string(),
timeout,
};
let conn = T::create(params)?;
let (session_id, session_capabilities) = start_session(&conn, capabilities)?;
let driver = GenericWebDriver {
session: WebDriverSession::new(session_id, Arc::new(Mutex::new(conn))),
capabilities: session_capabilities,
quit_on_drop: true,
phantom: PhantomData,
};
Ok(driver)
}
pub fn capabilities(&self) -> DesiredCapabilities {
DesiredCapabilities::new(self.capabilities.clone())
}
pub fn session_id(&self) -> &SessionId {
self.session.session_id()
}
pub fn config(&self) -> &WebDriverConfig {
self.session.config()
}
pub fn config_mut(&mut self) -> &mut WebDriverConfig {
self.session.config_mut()
}
pub fn quit(mut self) -> WebDriverResult<()> {
self.cmd(Command::DeleteSession)?;
self.quit_on_drop = false;
Ok(())
}
pub fn set_request_timeout(&mut self, timeout: Duration) -> WebDriverResult<()> {
self.session.set_request_timeout(timeout)
}
}
impl<T> WebDriverCommands for GenericWebDriver<T>
where
T: WebDriverHttpClientSync,
{
fn session(&self) -> &WebDriverSession {
&self.session
}
}
impl<T> Drop for GenericWebDriver<T>
where
T: WebDriverHttpClientSync,
{
fn drop(&mut self) {
if self.quit_on_drop && !(self.session.session_id()).is_empty() {
if let Err(e) = self.cmd(Command::DeleteSession) {
error!("Failed to close session: {:?}", e);
}
}
}
}