mirror of
https://github.com/servo/servo.git
synced 2025-08-02 04:00:32 +01:00
Auto merge of #15246 - andreastt:webdriver-optional-timeout, r=jgraham
Allow script timeouts to be optional and associate timeouts with session state These changes let WebDriver script timeouts be optional and associated all timeout state with the session. Because the durations are currently associated with the handler which is never reset, they bleed across to any subsequent WebDriver sessions. See each individual commit for more information. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require tests because _Servo needs more work before it can pass the WPT WebDriver tests_ <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15246) <!-- Reviewable:end -->
This commit is contained in:
commit
b38da9b920
1 changed files with 67 additions and 32 deletions
|
@ -96,18 +96,40 @@ pub fn start_server(port: u16, constellation_chan: Sender<ConstellationMsg>) {
|
||||||
}).expect("Thread spawning failed");
|
}).expect("Thread spawning failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the current WebDriver session and holds relevant session state.
|
||||||
struct WebDriverSession {
|
struct WebDriverSession {
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
frame_id: Option<FrameId>
|
frame_id: Option<FrameId>,
|
||||||
|
|
||||||
|
/// Time to wait for injected scripts to run before interrupting them. A [`None`] value
|
||||||
|
/// specifies that the script should run indefinitely.
|
||||||
|
script_timeout: Option<u32>,
|
||||||
|
|
||||||
|
/// Time to wait for a page to finish loading upon navigation.
|
||||||
|
load_timeout: u32,
|
||||||
|
|
||||||
|
/// Time to wait for the element location strategy when retrieving elements, and when
|
||||||
|
/// waiting for an element to become interactable.
|
||||||
|
implicit_wait_timeout: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebDriverSession {
|
||||||
|
pub fn new() -> WebDriverSession {
|
||||||
|
WebDriverSession {
|
||||||
|
id: Uuid::new_v4(),
|
||||||
|
frame_id: None,
|
||||||
|
|
||||||
|
script_timeout: Some(30_000),
|
||||||
|
load_timeout: 300_000,
|
||||||
|
implicit_wait_timeout: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Handler {
|
struct Handler {
|
||||||
session: Option<WebDriverSession>,
|
session: Option<WebDriverSession>,
|
||||||
constellation_chan: Sender<ConstellationMsg>,
|
constellation_chan: Sender<ConstellationMsg>,
|
||||||
script_timeout: u32,
|
|
||||||
load_timeout: u32,
|
|
||||||
resize_timeout: u32,
|
resize_timeout: u32,
|
||||||
implicit_wait_timeout: u32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
@ -230,24 +252,12 @@ impl ToJson for SetPrefsParameters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebDriverSession {
|
|
||||||
pub fn new() -> WebDriverSession {
|
|
||||||
WebDriverSession {
|
|
||||||
id: Uuid::new_v4(),
|
|
||||||
frame_id: None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub fn new(constellation_chan: Sender<ConstellationMsg>) -> Handler {
|
pub fn new(constellation_chan: Sender<ConstellationMsg>) -> Handler {
|
||||||
Handler {
|
Handler {
|
||||||
session: None,
|
session: None,
|
||||||
constellation_chan: constellation_chan,
|
constellation_chan: constellation_chan,
|
||||||
script_timeout: 30_000,
|
|
||||||
load_timeout: 300_000,
|
|
||||||
resize_timeout: 500,
|
resize_timeout: 500,
|
||||||
implicit_wait_timeout: 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,19 +363,25 @@ impl Handler {
|
||||||
|
|
||||||
fn wait_for_load(&self,
|
fn wait_for_load(&self,
|
||||||
sender: IpcSender<LoadStatus>,
|
sender: IpcSender<LoadStatus>,
|
||||||
receiver: IpcReceiver<LoadStatus>) -> WebDriverResult<WebDriverResponse> {
|
receiver: IpcReceiver<LoadStatus>)
|
||||||
let timeout = self.load_timeout;
|
-> WebDriverResult<WebDriverResponse> {
|
||||||
|
let session = try!(self.session
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, "")));
|
||||||
|
|
||||||
|
let timeout = session.load_timeout;
|
||||||
let timeout_chan = sender;
|
let timeout_chan = sender;
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
thread::sleep(Duration::from_millis(timeout as u64));
|
thread::sleep(Duration::from_millis(timeout as u64));
|
||||||
let _ = timeout_chan.send(LoadStatus::LoadTimeout);
|
let _ = timeout_chan.send(LoadStatus::LoadTimeout);
|
||||||
});
|
});
|
||||||
|
|
||||||
//Wait to get a load event
|
// wait to get a load event
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
LoadStatus::LoadComplete => Ok(WebDriverResponse::Void),
|
LoadStatus::LoadComplete => Ok(WebDriverResponse::Void),
|
||||||
LoadStatus::LoadTimeout => Err(WebDriverError::new(ErrorStatus::Timeout,
|
LoadStatus::LoadTimeout => {
|
||||||
"Load timed out"))
|
Err(WebDriverError::new(ErrorStatus::Timeout, "Load timed out"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,15 +697,23 @@ impl Handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_set_timeouts(&mut self, parameters: &TimeoutsParameters) -> WebDriverResult<WebDriverResponse> {
|
fn handle_set_timeouts(&mut self,
|
||||||
//TODO: this conversion is crazy, spec should limit these to u32 and check upstream
|
parameters: &TimeoutsParameters)
|
||||||
|
-> WebDriverResult<WebDriverResponse> {
|
||||||
|
let mut session = try!(self.session
|
||||||
|
.as_mut()
|
||||||
|
.ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, "")));
|
||||||
|
|
||||||
|
// TODO: this conversion is crazy, spec should limit these to u32 and check upstream
|
||||||
let value = parameters.ms as u32;
|
let value = parameters.ms as u32;
|
||||||
match ¶meters.type_[..] {
|
match ¶meters.type_[..] {
|
||||||
"implicit" => self.implicit_wait_timeout = value,
|
"script" => session.script_timeout = Some(value),
|
||||||
"page load" => self.load_timeout = value,
|
"page load" => session.load_timeout = value,
|
||||||
"script" => self.script_timeout = value,
|
"implicit" => session.implicit_wait_timeout = value,
|
||||||
x => return Err(WebDriverError::new(ErrorStatus::InvalidSelector,
|
x => {
|
||||||
format!("Unknown timeout type {}", x)))
|
return Err(WebDriverError::new(ErrorStatus::InvalidSelector,
|
||||||
|
format!("Unknown timeout type {}", x)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
@ -710,13 +734,24 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_execute_async_script(&self,
|
fn handle_execute_async_script(&self,
|
||||||
parameters: &JavascriptCommandParameters) -> WebDriverResult<WebDriverResponse> {
|
parameters: &JavascriptCommandParameters)
|
||||||
|
-> WebDriverResult<WebDriverResponse> {
|
||||||
|
let session = try!(self.session
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, "")));
|
||||||
|
|
||||||
let func_body = ¶meters.script;
|
let func_body = ¶meters.script;
|
||||||
let args_string = "window.webdriverCallback";
|
let args_string = "window.webdriverCallback";
|
||||||
|
|
||||||
let script = format!(
|
let script = match session.script_timeout {
|
||||||
"setTimeout(webdriverTimeout, {}); (function(callback) {{ {} }})({})",
|
Some(timeout) => {
|
||||||
self.script_timeout, func_body, args_string);
|
format!("setTimeout(webdriverTimeout, {}); (function(callback) {{ {} }})({})",
|
||||||
|
timeout,
|
||||||
|
func_body,
|
||||||
|
args_string)
|
||||||
|
}
|
||||||
|
None => format!("(function(callback) {{ {} }})({})", func_body, args_string),
|
||||||
|
};
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let command = WebDriverScriptCommand::ExecuteAsyncScript(script, sender);
|
let command = WebDriverScriptCommand::ExecuteAsyncScript(script, sender);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue