thirtyfour/webdriver.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
use crate::error::WebDriverResult;
use crate::session::handle::SessionHandle;
use crate::Capabilities;
use std::ops::{Deref, DerefMut};
/// The `WebDriver` struct encapsulates an async Selenium WebDriver browser
/// session.
///
/// # Example:
/// ```no_run
/// use thirtyfour::prelude::*;
/// # use thirtyfour::support::block_on;
///
/// # fn main() -> WebDriverResult<()> {
/// # block_on(async {
/// let caps = DesiredCapabilities::firefox();
/// // NOTE: this assumes you have a WebDriver compatible server running
/// // at http://localhost:4444
/// // e.g. `geckodriver -p 4444`
/// let driver = WebDriver::new("http://localhost:4444", caps).await?;
/// driver.goto("https://www.rust-lang.org/").await?;
/// // Always remember to close the session.
/// driver.quit().await?;
/// # Ok(())
/// # })
/// # }
/// ```
#[derive(Clone)]
pub struct WebDriver {
pub handle: SessionHandle,
}
impl WebDriver {
/// Create a new WebDriver as follows:
///
/// # Example
/// ```no_run
/// # use thirtyfour::prelude::*;
/// # use thirtyfour::support::block_on;
/// #
/// # fn main() -> WebDriverResult<()> {
/// # block_on(async {
/// let caps = DesiredCapabilities::firefox();
/// // NOTE: this assumes you have a WebDriver compatible server running
/// // at http://localhost:4444
/// // e.g. `geckodriver -p 4444`
/// let driver = WebDriver::new("http://localhost:4444", caps).await?;
/// # driver.quit().await?;
/// # Ok(())
/// # })
/// # }
/// ```
///
/// **NOTE:** If the webdriver appears to hang or give no response, please check that the
/// capabilities object is of the correct type for that webdriver.
#[allow(unused_variables)]
pub async fn new<C>(server_url: &str, capabilities: C) -> WebDriverResult<Self>
where
C: Into<Capabilities>,
{
#[cfg(not(any(feature = "rusttls-tls", feature = "native-tls")))]
panic!("please set either the rusttls-tls or native-tls feature");
#[cfg(any(feature = "rusttls-tls", feature = "native-tls"))]
{
use crate::TimeoutConfiguration;
use fantoccini::ClientBuilder;
let caps: Capabilities = capabilities.into();
#[cfg(feature = "native-tls")]
let mut builder = ClientBuilder::native();
#[cfg(feature = "rusttls-tls")]
let mut builder = ClientBuilder::rustls();
let client = builder.capabilities(caps.clone()).connect(server_url).await?;
// Set default timeouts.
let timeouts = TimeoutConfiguration::default();
client.update_timeouts(timeouts).await?;
Ok(Self {
handle: SessionHandle::new(client).await?,
})
}
}
// /// Creates a new WebDriver just like the `new` function. Allows a
// /// configurable timeout for all HTTP requests including the session creation.
// ///
// /// Create a new WebDriver as follows:
// ///
// /// # Example
// /// ```no_run
// /// # use thirtyfour::prelude::*;
// /// # use thirtyfour::support::block_on;
// /// # use std::time::Duration;
// /// #
// /// # fn main() -> WebDriverResult<()> {
// /// # block_on(async {
// /// let caps = DesiredCapabilities::chrome();
// /// let driver = WebDriver::new_with_timeout("http://localhost:4444", &caps, Some(Duration::from_secs(120))).await?;
// /// # driver.quit().await?;
// /// # Ok(())
// /// # })
// /// # }
// /// ```
// pub async fn new_with_timeout<C>(
// _server_url: &str,
// _capabilities: C,
// _timeout: Option<Duration>,
// ) -> WebDriverResult<Self>
// where
// C: Into<Capabilities>,
// {
// unimplemented!()
// }
/// End the webdriver session and close the browser.
///
/// **NOTE:** The browser will not close automatically when `WebDriver` goes out of scope.
/// Thus if you intend for the browser to close once you are done with it, then
/// you must call this method at that point, and await it.
pub async fn quit(self) -> WebDriverResult<()> {
self.handle.client.close().await?;
Ok(())
}
}
/// The Deref implementation allows the WebDriver to "fall back" to SessionHandle and
/// exposes all of the methods there without requiring us to use an async_trait.
/// See documentation at the top of this module for more details on the design.
impl Deref for WebDriver {
type Target = SessionHandle;
fn deref(&self) -> &Self::Target {
&self.handle
}
}
impl DerefMut for WebDriver {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.handle
}
}