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
use std::marker::PhantomData;
use std::sync::Arc;
use log::error;
use serde::Serialize;
use serde_json::Value;
use crate::sync::http_sync::connection_sync::{RemoteConnectionSync, RemoteConnectionSyncCreate};
#[cfg(not(any(feature = "tokio-runtime", feature = "async-std-runtime")))]
use crate::sync::http_sync::nulldriver_sync::NullDriverSync;
#[cfg(feature = "tokio-runtime")]
use crate::sync::http_sync::reqwest_sync::ReqwestDriverSync;
use crate::sync::webdrivercommands::{start_session, WebDriverCommands, WebDriverSession};
use crate::{common::command::Command, error::WebDriverResult, DesiredCapabilities, SessionId};
#[cfg(not(any(feature = "tokio-runtime", feature = "async-std-runtime")))]
pub type WebDriver = GenericWebDriver<NullDriverSync>;
#[cfg(feature = "tokio-runtime")]
pub type WebDriver = GenericWebDriver<ReqwestDriverSync>;
#[derive(Debug)]
pub struct GenericWebDriver<T: RemoteConnectionSync + RemoteConnectionSyncCreate> {
pub session_id: SessionId,
conn: Arc<dyn RemoteConnectionSync>,
capabilities: Value,
quit_on_drop: bool,
phantom: PhantomData<T>,
}
impl<T: 'static> GenericWebDriver<T>
where
T: RemoteConnectionSync + RemoteConnectionSyncCreate,
{
pub fn new<C>(remote_server_addr: &str, capabilities: C) -> WebDriverResult<Self>
where
C: Serialize,
{
let conn = Arc::new(T::create(remote_server_addr)?);
let (session_id, session_capabilities) = start_session(conn.clone(), capabilities)?;
let driver = GenericWebDriver {
session_id,
conn,
capabilities: session_capabilities,
quit_on_drop: true,
phantom: PhantomData,
};
Ok(driver)
}
pub fn capabilities(&self) -> DesiredCapabilities {
DesiredCapabilities::new(self.capabilities.clone())
}
pub fn quit(mut self) -> WebDriverResult<()> {
self.cmd(Command::DeleteSession)?;
self.quit_on_drop = false;
Ok(())
}
}
impl<T> WebDriverCommands for GenericWebDriver<T>
where
T: RemoteConnectionSync + RemoteConnectionSyncCreate,
{
fn cmd(&self, command: Command<'_>) -> WebDriverResult<serde_json::Value> {
self.conn.execute(&self.session_id, command)
}
fn session(&self) -> WebDriverSession {
WebDriverSession::new(&self.session_id, self.conn.clone())
}
}
impl<T> Drop for GenericWebDriver<T>
where
T: RemoteConnectionSync + RemoteConnectionSyncCreate,
{
fn drop(&mut self) {
if self.quit_on_drop && !(*self.session_id).is_empty() {
if let Err(e) = self.cmd(Command::DeleteSession) {
error!("Failed to close session: {:?}", e);
}
}
}
}