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
use super::*;
use std::process::{Command, Child, Stdio};
use std::thread;
use std::time::Duration;
use std::ffi::OsString;
use super::util;
pub struct GeckoDriverBuilder {
driver_binary: OsString,
port: Option<u16>,
ff_binary: String,
kill_on_drop: bool,
}
impl GeckoDriverBuilder {
pub fn new() -> Self {
GeckoDriverBuilder {
driver_binary: "geckodriver".into(),
port: None,
ff_binary: "firefox".to_owned(),
kill_on_drop: true,
}
}
pub fn driver_path<S: Into<OsString>>(mut self, path: S) -> Self {
self.driver_binary = path.into();
self
}
pub fn port(mut self, port: u16) -> Self {
self.port = Some(port);
self
}
pub fn firefox_binary(mut self, binary: &str) -> Self {
self.ff_binary = binary.to_owned();
self
}
pub fn kill_on_drop(mut self, kill: bool) -> Self {
self.kill_on_drop = kill;
self
}
pub fn spawn(self) -> Result<GeckoDriver, Error> {
let port = util::check_tcp_port(self.port)?;
let child = Command::new(self.driver_binary)
.arg("-b")
.arg(self.ff_binary)
.arg("--port")
.arg(format!("{}", port))
.stdin(Stdio::null())
.stderr(Stdio::null())
.stdout(Stdio::null())
.spawn()?;
thread::sleep(Duration::new(1, 500));
Ok(GeckoDriver {
child: child,
url: format!("http://localhost:{}", port),
kill_on_drop: self.kill_on_drop,
})
}
}
pub struct GeckoDriver {
child: Child,
url: String,
kill_on_drop: bool,
}
impl GeckoDriver {
pub fn spawn() -> Result<Self, Error> {
GeckoDriverBuilder::new().spawn()
}
pub fn build() -> GeckoDriverBuilder {
GeckoDriverBuilder::new()
}
}
impl Drop for GeckoDriver {
fn drop(&mut self) {
if self.kill_on_drop {
let _ = self.child.kill();
}
}
}
impl Driver for GeckoDriver {
fn url(&self) -> &str {
&self.url
}
}