use std::ops::Deref;
use std::sync::Arc;
use crate::Capabilities;
use crate::common::config::WebDriverConfig;
use crate::error::WebDriverResult;
use crate::prelude::WebDriverError;
use crate::session::create::start_session;
use crate::session::handle::SessionHandle;
use crate::session::http::HttpClient;
#[cfg(feature = "reqwest")]
use crate::session::http::create_reqwest_client;
#[derive(Debug, Clone)]
pub struct WebDriver {
pub handle: Arc<SessionHandle>,
}
#[derive(Debug, thiserror::Error)]
#[error("Webdriver has already quit, can't leak an already quit driver")]
pub struct AlreadyQuit(pub(crate) ());
impl WebDriver {
pub async fn new<S, C>(server_url: S, capabilities: C) -> WebDriverResult<Self>
where
S: Into<String>,
C: Into<Capabilities>,
{
Self::new_with_config(server_url, capabilities, WebDriverConfig::default()).await
}
pub async fn new_with_config<S, C>(
server_url: S,
capabilities: C,
config: WebDriverConfig,
) -> WebDriverResult<Self>
where
S: Into<String>,
C: Into<Capabilities>,
{
#[cfg(feature = "reqwest")]
let client = create_reqwest_client(config.reqwest_timeout);
#[cfg(not(feature = "reqwest"))]
let client = crate::session::http::null_client::create_null_client();
Self::new_with_config_and_client(server_url, capabilities, config, client).await
}
pub async fn new_with_config_and_client<S, C>(
server_url: S,
capabilities: C,
config: WebDriverConfig,
client: impl HttpClient,
) -> WebDriverResult<Self>
where
S: Into<String>,
C: Into<Capabilities>,
{
let capabilities = capabilities.into();
let server_url = server_url
.into()
.parse()
.map_err(|e| WebDriverError::ParseError(format!("invalid url: {e}")))?;
let client = Arc::new(client);
let session_id = start_session(client.as_ref(), &server_url, &config, capabilities).await?;
let handle = SessionHandle::new_with_config(client, server_url, session_id, config)?;
Ok(Self {
handle: Arc::new(handle),
})
}
pub fn clone_with_config(&self, config: WebDriverConfig) -> Self {
Self {
handle: Arc::new(self.handle.clone_with_config(config)),
}
}
pub async fn quit(self) -> WebDriverResult<()> {
self.handle.quit().await
}
pub fn leak(self) -> Result<(), AlreadyQuit> {
self.handle.leak()
}
}
impl Deref for WebDriver {
type Target = Arc<SessionHandle>;
fn deref(&self) -> &Self::Target {
&self.handle
}
}