diff options
author | chansuke <chansuke@georepublic.de> | 2018-09-04 23:43:00 +0900 |
---|---|---|
committer | chansuke <chansuke@georepublic.de> | 2018-09-04 23:43:00 +0900 |
commit | 511dfe8e1b062324fbfde0aac8d16cc5e20cf8ce (patch) | |
tree | b1d9a2a6de2365f97f74e304e2d7052f24675eb0 | |
parent | 73459d5b3608cc9d6a9fcd97a45ecca687bf219f (diff) | |
download | servo-511dfe8e1b062324fbfde0aac8d16cc5e20cf8ce.tar.gz servo-511dfe8e1b062324fbfde0aac8d16cc5e20cf8ce.zip |
Format component of webdriver_sever
-rw-r--r-- | components/webdriver_server/keys.rs | 8 | ||||
-rw-r--r-- | components/webdriver_server/lib.rs | 683 |
2 files changed, 466 insertions, 225 deletions
diff --git a/components/webdriver_server/keys.rs b/components/webdriver_server/keys.rs index d16f8232253..72fdb8b32ac 100644 --- a/components/webdriver_server/keys.rs +++ b/components/webdriver_server/keys.rs @@ -4,7 +4,6 @@ use msg::constellation_msg::{Key, KeyState, KeyModifiers}; - /// Takes a character and returns an Option containing a tuple of the /// corresponding keycode and whether shift is required. This is /// currently pretty much ascii-only and the webdriver spec isn't @@ -164,7 +163,7 @@ fn key_from_char(key_string: &char) -> Option<(Key, bool)> { '\u{E03C}' => Some((Key::F12, false)), '\u{E03D}' => None, '\u{E040}' => None, - _ => None + _ => None, } } @@ -172,7 +171,8 @@ pub fn keycodes_to_keys(key_codes: &str) -> Result<Vec<(Key, KeyModifiers, KeySt let mut rv = vec![]; for char_code in key_codes.chars() { - let (key, with_shift) = key_from_char(&char_code).ok_or(format!("Unsupported character code {}", char_code))?; + let (key, with_shift) = + key_from_char(&char_code).ok_or(format!("Unsupported character code {}", char_code))?; let modifiers = if with_shift { KeyModifiers::SHIFT } else { @@ -180,6 +180,6 @@ pub fn keycodes_to_keys(key_codes: &str) -> Result<Vec<(Key, KeyModifiers, KeySt }; rv.push((key, modifiers, KeyState::Pressed)); rv.push((key, modifiers, KeyState::Released)); - }; + } Ok(rv) } diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 47390248dd3..4caf137d32f 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -4,7 +4,6 @@ #![crate_name = "webdriver_server"] #![crate_type = "rlib"] - #![deny(unsafe_code)] extern crate base64; @@ -62,9 +61,23 @@ use webdriver::response::{WebDriverResponse, WindowRectResponse}; use webdriver::server::{self, Session, WebDriverHandler}; fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> { - return vec![(Post, "/session/{sessionId}/servo/prefs/get", ServoExtensionRoute::GetPrefs), - (Post, "/session/{sessionId}/servo/prefs/set", ServoExtensionRoute::SetPrefs), - (Post, "/session/{sessionId}/servo/prefs/reset", ServoExtensionRoute::ResetPrefs)] + return vec![ + ( + Post, + "/session/{sessionId}/servo/prefs/get", + ServoExtensionRoute::GetPrefs, + ), + ( + Post, + "/session/{sessionId}/servo/prefs/set", + ServoExtensionRoute::SetPrefs, + ), + ( + Post, + "/session/{sessionId}/servo/prefs/reset", + ServoExtensionRoute::ResetPrefs, + ), + ]; } fn cookie_msg_to_cookie(cookie: cookie_rs::Cookie) -> Cookie { @@ -73,15 +86,15 @@ fn cookie_msg_to_cookie(cookie: cookie_rs::Cookie) -> Cookie { value: cookie.value().to_owned(), path: match cookie.path() { Some(path) => Nullable::Value(path.to_string()), - None => Nullable::Null + None => Nullable::Null, }, domain: match cookie.domain() { Some(domain) => Nullable::Value(domain.to_string()), - None => Nullable::Null + None => Nullable::Null, }, expiry: match cookie.expires() { Some(time) => Nullable::Value(Date::new(time.to_timespec().sec as u64)), - None => Nullable::Null + None => Nullable::Null, }, secure: cookie.secure(), httpOnly: cookie.http_only(), @@ -90,13 +103,15 @@ fn cookie_msg_to_cookie(cookie: cookie_rs::Cookie) -> Cookie { pub fn start_server(port: u16, constellation_chan: Sender<ConstellationMsg>) { let handler = Handler::new(constellation_chan); - thread::Builder::new().name("WebdriverHttpServer".to_owned()).spawn(move || { - let address = SocketAddrV4::new("0.0.0.0".parse().unwrap(), port); - match server::start(SocketAddr::V4(address), handler, &extension_routes()) { - Ok(listening) => info!("WebDriver server listening on {}", listening.socket), - Err(_) => panic!("Unable to start WebDriver HTTPD server"), - } - }).expect("Thread spawning failed"); + thread::Builder::new() + .name("WebdriverHttpServer".to_owned()) + .spawn(move || { + let address = SocketAddrV4::new("0.0.0.0".parse().unwrap(), port); + match server::start(SocketAddr::V4(address), handler, &extension_routes()) { + Ok(listening) => info!("WebDriver server listening on {}", listening.socket), + Err(_) => panic!("Unable to start WebDriver HTTPD server"), + } + }).expect("Thread spawning failed"); } /// Represents the current WebDriver session and holds relevant session state. @@ -118,10 +133,10 @@ struct WebDriverSession { } impl WebDriverSession { - pub fn new(browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId) - -> WebDriverSession - { + pub fn new( + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + ) -> WebDriverSession { WebDriverSession { id: Uuid::new_v4(), browsing_context_id: browsing_context_id, @@ -150,22 +165,24 @@ enum ServoExtensionRoute { impl WebDriverExtensionRoute for ServoExtensionRoute { type Command = ServoExtensionCommand; - fn command(&self, - _captures: &Captures, - body_data: &Json) -> WebDriverResult<WebDriverCommand<ServoExtensionCommand>> { + fn command( + &self, + _captures: &Captures, + body_data: &Json, + ) -> WebDriverResult<WebDriverCommand<ServoExtensionCommand>> { let command = match *self { ServoExtensionRoute::GetPrefs => { let parameters: GetPrefsParameters = Parameters::from_json(&body_data)?; ServoExtensionCommand::GetPrefs(parameters) - } + }, ServoExtensionRoute::SetPrefs => { let parameters: SetPrefsParameters = Parameters::from_json(&body_data)?; ServoExtensionCommand::SetPrefs(parameters) - } + }, ServoExtensionRoute::ResetPrefs => { let parameters: GetPrefsParameters = Parameters::from_json(&body_data)?; ServoExtensionCommand::ResetPrefs(parameters) - } + }, }; Ok(WebDriverCommand::Extension(command)) } @@ -190,27 +207,34 @@ impl WebDriverExtensionCommand for ServoExtensionCommand { #[derive(Clone, Debug, PartialEq)] struct GetPrefsParameters { - prefs: Vec<String> + prefs: Vec<String>, } impl Parameters for GetPrefsParameters { fn from_json(body: &Json) -> WebDriverResult<GetPrefsParameters> { - let data = body.as_object().ok_or( - WebDriverError::new(ErrorStatus::InvalidArgument, - "Message body was not an object"))?; - let prefs_value = data.get("prefs").ok_or( - WebDriverError::new(ErrorStatus::InvalidArgument, - "Missing prefs key"))?; - let items = prefs_value.as_array().ok_or( - WebDriverError::new( - ErrorStatus::InvalidArgument, - "prefs was not an array"))?; - let params = items.iter().map(|x| x.as_string().map(|y| y.to_owned()).ok_or( - WebDriverError::new(ErrorStatus::InvalidArgument, - "Pref is not a string"))).collect::<Result<Vec<_>, _>>()?; - Ok(GetPrefsParameters { - prefs: params - }) + let data = body.as_object().ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Message body was not an object", + ))?; + let prefs_value = data.get("prefs").ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Missing prefs key", + ))?; + let items = prefs_value.as_array().ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "prefs was not an array", + ))?; + let params = items + .iter() + .map(|x| { + x.as_string() + .map(|y| y.to_owned()) + .ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Pref is not a string", + )) + }).collect::<Result<Vec<_>, _>>()?; + Ok(GetPrefsParameters { prefs: params }) } } @@ -224,31 +248,35 @@ impl ToJson for GetPrefsParameters { #[derive(Clone, Debug, PartialEq)] struct SetPrefsParameters { - prefs: Vec<(String, PrefValue)> + prefs: Vec<(String, PrefValue)>, } impl Parameters for SetPrefsParameters { fn from_json(body: &Json) -> WebDriverResult<SetPrefsParameters> { - let data = body.as_object().ok_or( - WebDriverError::new(ErrorStatus::InvalidArgument, - "Message body was not an object"))?; - let items = data.get("prefs").ok_or( - WebDriverError::new(ErrorStatus::InvalidArgument, - "Missing prefs key"))?.as_object().ok_or( - WebDriverError::new( + let data = body.as_object().ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Message body was not an object", + ))?; + let items = data + .get("prefs") + .ok_or(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Missing prefs key", + ))?.as_object() + .ok_or(WebDriverError::new( ErrorStatus::InvalidArgument, - "prefs was not an array"))?; + "prefs was not an array", + ))?; let mut params = Vec::with_capacity(items.len()); for (name, val) in items.iter() { - let value = PrefValue::from_json(val.clone()).or( - Err(WebDriverError::new(ErrorStatus::InvalidArgument, - "Pref is not a boolean or string")))?; + let value = PrefValue::from_json(val.clone()).or(Err(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Pref is not a boolean or string", + )))?; let key = name.to_owned(); params.push((key, value)); } - Ok(SetPrefsParameters { - prefs: params - }) + Ok(SetPrefsParameters { prefs: params }) } } @@ -287,23 +315,29 @@ impl Handler { } debug!("Timed out getting focused context."); - Err(WebDriverError::new(ErrorStatus::Timeout, - "Failed to get window handle")) + Err(WebDriverError::new( + ErrorStatus::Timeout, + "Failed to get window handle", + )) } fn session(&self) -> WebDriverResult<&WebDriverSession> { match self.session { Some(ref x) => Ok(x), - None => Err(WebDriverError::new(ErrorStatus::SessionNotCreated, - "Session not created")) + None => Err(WebDriverError::new( + ErrorStatus::SessionNotCreated, + "Session not created", + )), } } fn session_mut(&mut self) -> WebDriverResult<&mut WebDriverSession> { match self.session { Some(ref mut x) => Ok(x), - None => Err(WebDriverError::new(ErrorStatus::SessionNotCreated, - "Session not created")) + None => Err(WebDriverError::new( + ErrorStatus::SessionNotCreated, + "Session not created", + )), } } @@ -317,14 +351,17 @@ impl Handler { capabilities.insert("browserName".to_owned(), "servo".to_json()); capabilities.insert("browserVersion".to_owned(), "0.0.1".to_json()); capabilities.insert("acceptInsecureCerts".to_owned(), false.to_json()); - let response = NewSessionResponse::new(session.id.to_string(), Json::Object(capabilities)); + let response = + NewSessionResponse::new(session.id.to_string(), Json::Object(capabilities)); debug!("new session created {}.", session.id); self.session = Some(session); Ok(WebDriverResponse::NewSession(response)) } else { debug!("new session failed."); - Err(WebDriverError::new(ErrorStatus::UnknownError, - "Session already created")) + Err(WebDriverError::new( + ErrorStatus::UnknownError, + "Session already created", + )) } } @@ -333,16 +370,26 @@ impl Handler { Ok(WebDriverResponse::Void) } - fn browsing_context_script_command(&self, cmd_msg: WebDriverScriptCommand) -> WebDriverResult<()> { + fn browsing_context_script_command( + &self, + cmd_msg: WebDriverScriptCommand, + ) -> WebDriverResult<()> { let browsing_context_id = self.session()?.browsing_context_id; - let msg = ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd_msg)); + let msg = ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( + browsing_context_id, + cmd_msg, + )); self.constellation_chan.send(msg).unwrap(); Ok(()) } fn top_level_script_command(&self, cmd_msg: WebDriverScriptCommand) -> WebDriverResult<()> { - let browsing_context_id = BrowsingContextId::from(self.session()?.top_level_browsing_context_id); - let msg = ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd_msg)); + let browsing_context_id = + BrowsingContextId::from(self.session()?.top_level_browsing_context_id); + let msg = ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( + browsing_context_id, + cmd_msg, + )); self.constellation_chan.send(msg).unwrap(); Ok(()) } @@ -350,8 +397,12 @@ impl Handler { fn handle_get(&self, parameters: &GetParameters) -> WebDriverResult<WebDriverResponse> { let url = match ServoUrl::parse(¶meters.url[..]) { Ok(url) => url, - Err(_) => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - "Invalid URL")) + Err(_) => { + return Err(WebDriverError::new( + ErrorStatus::InvalidArgument, + "Invalid URL", + )) + }, }; let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; @@ -359,16 +410,20 @@ impl Handler { let (sender, receiver) = ipc::channel().unwrap(); let load_data = LoadData::new(url, None, None, None); - let cmd_msg = WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, sender.clone()); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + let cmd_msg = + WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, sender.clone()); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); self.wait_for_load(sender, receiver) } - fn wait_for_load(&self, - sender: IpcSender<LoadStatus>, - receiver: IpcReceiver<LoadStatus>) - -> WebDriverResult<WebDriverResponse> { + fn wait_for_load( + &self, + sender: IpcSender<LoadStatus>, + receiver: IpcReceiver<LoadStatus>, + ) -> WebDriverResult<WebDriverResponse> { let timeout = self.session()?.load_timeout; thread::spawn(move || { thread::sleep(Duration::from_millis(timeout)); @@ -380,7 +435,7 @@ impl Handler { LoadStatus::LoadComplete => Ok(WebDriverResponse::Void), LoadStatus::LoadTimeout => { Err(WebDriverError::new(ErrorStatus::Timeout, "Load timed out")) - } + }, } } @@ -390,7 +445,9 @@ impl Handler { let url = receiver.recv().unwrap(); - Ok(WebDriverResponse::Generic(ValueResponse::new(url.as_str().to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + url.as_str().to_json(), + ))) } fn handle_window_size(&self) -> WebDriverResult<WebDriverResponse> { @@ -398,17 +455,25 @@ impl Handler { let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; let cmd_msg = WebDriverCommandMsg::GetWindowSize(top_level_browsing_context_id, sender); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); let window_size = receiver.recv().unwrap(); let vp = window_size.initial_viewport; let window_size_response = WindowRectResponse { - x: 0, y: 0, width: vp.width as i32, height: vp.height as i32 + x: 0, + y: 0, + width: vp.width as i32, + height: vp.height as i32, }; Ok(WebDriverResponse::WindowRect(window_size_response)) } - fn handle_set_window_size(&self, params: &WindowRectParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_set_window_size( + &self, + params: &WindowRectParameters, + ) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); let width = match params.width { Nullable::Value(v) => v, @@ -420,9 +485,12 @@ impl Handler { }; let size = TypedSize2D::new(width as u32, height as u32); let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; - let cmd_msg = WebDriverCommandMsg::SetWindowSize(top_level_browsing_context_id, size, sender.clone()); + let cmd_msg = + WebDriverCommandMsg::SetWindowSize(top_level_browsing_context_id, size, sender.clone()); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); let timeout = self.resize_timeout; let constellation_chan = self.constellation_chan.clone(); @@ -431,13 +499,18 @@ impl Handler { // which will give the current window size. thread::sleep(Duration::from_millis(timeout as u64)); let cmd_msg = WebDriverCommandMsg::GetWindowSize(top_level_browsing_context_id, sender); - constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); }); let window_size = receiver.recv().unwrap(); let vp = window_size.initial_viewport; let window_size_response = WindowRectResponse { - x: 0, y: 0, width: vp.width as i32, height: vp.height as i32 + x: 0, + y: 0, + width: vp.width as i32, + height: vp.height as i32, }; Ok(WebDriverResponse::WindowRect(window_size_response)) } @@ -445,22 +518,38 @@ impl Handler { fn handle_is_enabled(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); - self.top_level_script_command(WebDriverScriptCommand::IsEnabled(element.id.clone(), sender))?; + self.top_level_script_command(WebDriverScriptCommand::IsEnabled( + element.id.clone(), + sender, + ))?; match receiver.recv().unwrap() { - Ok(is_enabled) => Ok(WebDriverResponse::Generic(ValueResponse::new(is_enabled.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, "Element not found")) + Ok(is_enabled) => Ok(WebDriverResponse::Generic(ValueResponse::new( + is_enabled.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Element not found", + )), } } fn handle_is_selected(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); - self.top_level_script_command(WebDriverScriptCommand::IsSelected(element.id.clone(), sender))?; + self.top_level_script_command(WebDriverScriptCommand::IsSelected( + element.id.clone(), + sender, + ))?; match receiver.recv().unwrap() { - Ok(is_selected) => Ok(WebDriverResponse::Generic(ValueResponse::new(is_selected.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, "Element not found")) + Ok(is_selected) => Ok(WebDriverResponse::Generic(ValueResponse::new( + is_selected.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Element not found", + )), } } @@ -486,7 +575,9 @@ impl Handler { let (sender, receiver) = ipc::channel().unwrap(); let cmd_msg = WebDriverCommandMsg::Refresh(top_level_browsing_context_id, sender.clone()); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); self.wait_for_load(sender, receiver) } @@ -497,27 +588,38 @@ impl Handler { self.top_level_script_command(WebDriverScriptCommand::GetTitle(sender))?; let value = receiver.recv().unwrap(); - Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))) } fn handle_window_handle(&self) -> WebDriverResult<WebDriverResponse> { // For now we assume there's only one window so just use the session // id as the window id let handle = self.session.as_ref().unwrap().id.to_string(); - Ok(WebDriverResponse::Generic(ValueResponse::new(handle.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + handle.to_json(), + ))) } fn handle_window_handles(&self) -> WebDriverResult<WebDriverResponse> { // For now we assume there's only one window so just use the session // id as the window id let handles = vec![self.session.as_ref().unwrap().id.to_string().to_json()]; - Ok(WebDriverResponse::Generic(ValueResponse::new(handles.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + handles.to_json(), + ))) } - fn handle_find_element(&self, parameters: &LocatorParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_find_element( + &self, + parameters: &LocatorParameters, + ) -> WebDriverResult<WebDriverResponse> { if parameters.using != LocatorStrategy::CSSSelector { - return Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, - "Unsupported locator strategy")) + return Err(WebDriverError::new( + ErrorStatus::UnsupportedOperation, + "Unsupported locator strategy", + )); } let (sender, receiver) = ipc::channel().unwrap(); @@ -529,54 +631,70 @@ impl Handler { Ok(value) => { let value_resp = value.map(|x| WebElement::new(x).to_json()).to_json(); Ok(WebDriverResponse::Generic(ValueResponse::new(value_resp))) - } - Err(_) => Err(WebDriverError::new(ErrorStatus::InvalidSelector, - "Invalid selector")) + }, + Err(_) => Err(WebDriverError::new( + ErrorStatus::InvalidSelector, + "Invalid selector", + )), } } - fn handle_switch_to_frame(&mut self, parameters: &SwitchToFrameParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_switch_to_frame( + &mut self, + parameters: &SwitchToFrameParameters, + ) -> WebDriverResult<WebDriverResponse> { use webdriver::common::FrameId; let frame_id = match parameters.id { FrameId::Null => { let session = self.session_mut()?; - session.browsing_context_id = BrowsingContextId::from(session.top_level_browsing_context_id); + session.browsing_context_id = + BrowsingContextId::from(session.top_level_browsing_context_id); return Ok(WebDriverResponse::Void); }, FrameId::Short(ref x) => WebDriverFrameId::Short(*x), - FrameId::Element(ref x) => WebDriverFrameId::Element(x.id.clone()) + FrameId::Element(ref x) => WebDriverFrameId::Element(x.id.clone()), }; self.switch_to_frame(frame_id) } - fn handle_switch_to_parent_frame(&mut self) -> WebDriverResult<WebDriverResponse> { self.switch_to_frame(WebDriverFrameId::Parent) } - fn switch_to_frame(&mut self, frame_id: WebDriverFrameId) -> WebDriverResult<WebDriverResponse> { + fn switch_to_frame( + &mut self, + frame_id: WebDriverFrameId, + ) -> WebDriverResult<WebDriverResponse> { if let WebDriverFrameId::Short(_) = frame_id { - return Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, - "Selecting frame by id not supported")); + return Err(WebDriverError::new( + ErrorStatus::UnsupportedOperation, + "Selecting frame by id not supported", + )); } let (sender, receiver) = ipc::channel().unwrap(); let cmd = WebDriverScriptCommand::GetBrowsingContextId(frame_id, sender); self.browsing_context_script_command(cmd)?; - let browsing_context_id = receiver.recv().unwrap() - .or(Err(WebDriverError::new(ErrorStatus::NoSuchFrame, "Frame does not exist")))?; + let browsing_context_id = receiver.recv().unwrap().or(Err(WebDriverError::new( + ErrorStatus::NoSuchFrame, + "Frame does not exist", + )))?; self.session_mut()?.browsing_context_id = browsing_context_id; Ok(WebDriverResponse::Void) } - - fn handle_find_elements(&self, parameters: &LocatorParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_find_elements( + &self, + parameters: &LocatorParameters, + ) -> WebDriverResult<WebDriverResponse> { if parameters.using != LocatorStrategy::CSSSelector { - return Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, - "Unsupported locator strategy")) + return Err(WebDriverError::new( + ErrorStatus::UnsupportedOperation, + "Unsupported locator strategy", + )); } let (sender, receiver) = ipc::channel().unwrap(); @@ -584,12 +702,18 @@ impl Handler { self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { Ok(value) => { - let resp_value: Vec<Json> = value.into_iter().map( - |x| WebElement::new(x).to_json()).collect(); - Ok(WebDriverResponse::Generic(ValueResponse::new(resp_value.to_json()))) - } - Err(_) => Err(WebDriverError::new(ErrorStatus::InvalidSelector, - "Invalid selector")) + let resp_value: Vec<Json> = value + .into_iter() + .map(|x| WebElement::new(x).to_json()) + .collect(); + Ok(WebDriverResponse::Generic(ValueResponse::new( + resp_value.to_json(), + ))) + }, + Err(_) => Err(WebDriverError::new( + ErrorStatus::InvalidSelector, + "Invalid selector", + )), } } @@ -601,13 +725,17 @@ impl Handler { match receiver.recv().unwrap() { Ok(rect) => { let response = ElementRectResponse { - x: rect.origin.x, y: rect.origin.y, - width: rect.size.width, height: rect.size.height + x: rect.origin.x, + y: rect.origin.y, + width: rect.size.width, + height: rect.size.height, }; Ok(WebDriverResponse::ElementRect(response)) }, - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, - "Unable to find element in document")) + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), } } @@ -616,9 +744,13 @@ impl Handler { let cmd = WebDriverScriptCommand::GetElementText(element.id.clone(), sender); self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { - Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, - "Unable to find element in document")) + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), } } @@ -626,8 +758,13 @@ impl Handler { let (sender, receiver) = ipc::channel().unwrap(); let cmd = WebDriverScriptCommand::GetActiveElement(sender); self.browsing_context_script_command(cmd)?; - let value = receiver.recv().unwrap().map(|x| WebElement::new(x).to_json()); - Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))) + let value = receiver + .recv() + .unwrap() + .map(|x| WebElement::new(x).to_json()); + Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))) } fn handle_element_tag_name(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> { @@ -635,31 +772,56 @@ impl Handler { let cmd = WebDriverScriptCommand::GetElementTagName(element.id.clone(), sender); self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { - Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, - "Unable to find element in document")) + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), } } - fn handle_element_attribute(&self, element: &WebElement, name: &str) -> WebDriverResult<WebDriverResponse> { + fn handle_element_attribute( + &self, + element: &WebElement, + name: &str, + ) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); - let cmd = WebDriverScriptCommand::GetElementAttribute(element.id.clone(), name.to_owned(), sender); + let cmd = WebDriverScriptCommand::GetElementAttribute( + element.id.clone(), + name.to_owned(), + sender, + ); self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { - Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, - "Unable to find element in document")) + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), } } - fn handle_element_css(&self, element: &WebElement, name: &str) -> WebDriverResult<WebDriverResponse> { + fn handle_element_css( + &self, + element: &WebElement, + name: &str, + ) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); - let cmd = WebDriverScriptCommand::GetElementCSS(element.id.clone(), name.to_owned(), sender); + let cmd = + WebDriverScriptCommand::GetElementCSS(element.id.clone(), name.to_owned(), sender); self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { - Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))), - Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, - "Unable to find element in document")) + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), } } @@ -668,10 +830,13 @@ impl Handler { let cmd = WebDriverScriptCommand::GetCookies(sender); self.browsing_context_script_command(cmd)?; let cookies = receiver.recv().unwrap(); - let response = cookies.into_iter().map(|cookie| { - cookie_msg_to_cookie(cookie.into_inner()) - }).collect::<Vec<Cookie>>(); - Ok(WebDriverResponse::Cookies(CookiesResponse { value: response })) + let response = cookies + .into_iter() + .map(|cookie| cookie_msg_to_cookie(cookie.into_inner())) + .collect::<Vec<Cookie>>(); + Ok(WebDriverResponse::Cookies(CookiesResponse { + value: response, + })) } fn handle_get_cookie(&self, name: &str) -> WebDriverResult<WebDriverResponse> { @@ -679,13 +844,20 @@ impl Handler { let cmd = WebDriverScriptCommand::GetCookie(name.to_owned(), sender); self.browsing_context_script_command(cmd)?; let cookies = receiver.recv().unwrap(); - let response = cookies.into_iter().map(|cookie| { - cookie_msg_to_cookie(cookie.into_inner()) - }).next().unwrap(); - Ok(WebDriverResponse::Cookie(CookieResponse { value: response })) + let response = cookies + .into_iter() + .map(|cookie| cookie_msg_to_cookie(cookie.into_inner())) + .next() + .unwrap(); + Ok(WebDriverResponse::Cookie(CookieResponse { + value: response, + })) } - fn handle_add_cookie(&self, params: &AddCookieParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_add_cookie( + &self, + params: &AddCookieParameters, + ) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); let cookie = cookie_rs::Cookie::build(params.name.to_owned(), params.value.to_owned()) @@ -705,18 +877,24 @@ impl Handler { match receiver.recv().unwrap() { Ok(_) => Ok(WebDriverResponse::Void), Err(response) => match response { - WebDriverCookieError::InvalidDomain => Err(WebDriverError::new(ErrorStatus::InvalidCookieDomain, - "Invalid cookie domain")), - WebDriverCookieError::UnableToSetCookie => Err(WebDriverError::new(ErrorStatus::UnableToSetCookie, - "Unable to set cookie")) - } + WebDriverCookieError::InvalidDomain => Err(WebDriverError::new( + ErrorStatus::InvalidCookieDomain, + "Invalid cookie domain", + )), + WebDriverCookieError::UnableToSetCookie => Err(WebDriverError::new( + ErrorStatus::UnableToSetCookie, + "Unable to set cookie", + )), + }, } } - fn handle_set_timeouts(&mut self, - parameters: &TimeoutsParameters) - -> WebDriverResult<WebDriverResponse> { - let session = self.session + fn handle_set_timeouts( + &mut self, + parameters: &TimeoutsParameters, + ) -> WebDriverResult<WebDriverResponse> { + let session = self + .session .as_mut() .ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, ""))?; @@ -733,8 +911,10 @@ impl Handler { Ok(WebDriverResponse::Void) } - fn handle_execute_script(&self, parameters: &JavascriptCommandParameters) - -> WebDriverResult<WebDriverResponse> { + fn handle_execute_script( + &self, + parameters: &JavascriptCommandParameters, + ) -> WebDriverResult<WebDriverResponse> { let func_body = ¶meters.script; let args_string = ""; @@ -750,16 +930,19 @@ impl Handler { self.postprocess_js_result(result) } - fn handle_execute_async_script(&self, - parameters: &JavascriptCommandParameters) - -> WebDriverResult<WebDriverResponse> { + fn handle_execute_async_script( + &self, + parameters: &JavascriptCommandParameters, + ) -> WebDriverResult<WebDriverResponse> { let func_body = ¶meters.script; let args_string = "window.webdriverCallback"; - let script = format!("setTimeout(webdriverTimeout, {}); (function(callback) {{ {} }})({})", - self.session()?.script_timeout, - func_body, - args_string); + let script = format!( + "setTimeout(webdriverTimeout, {}); (function(callback) {{ {} }})({})", + self.session()?.script_timeout, + func_body, + args_string + ); let (sender, receiver) = ipc::channel().unwrap(); let command = WebDriverScriptCommand::ExecuteAsyncScript(script, sender); @@ -768,40 +951,63 @@ impl Handler { self.postprocess_js_result(result) } - fn postprocess_js_result(&self, result: WebDriverJSResult) -> WebDriverResult<WebDriverResponse> { + fn postprocess_js_result( + &self, + result: WebDriverJSResult, + ) -> WebDriverResult<WebDriverResponse> { match result { - Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))), + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new( + value.to_json(), + ))), Err(WebDriverJSError::Timeout) => Err(WebDriverError::new(ErrorStatus::Timeout, "")), Err(WebDriverJSError::UnknownType) => Err(WebDriverError::new( - ErrorStatus::UnsupportedOperation, "Unsupported return type")), + ErrorStatus::UnsupportedOperation, + "Unsupported return type", + )), Err(WebDriverJSError::BrowsingContextNotFound) => Err(WebDriverError::new( - ErrorStatus::JavascriptError, "Pipeline id not found in browsing context")) + ErrorStatus::JavascriptError, + "Pipeline id not found in browsing context", + )), } } - fn handle_element_send_keys(&self, - element: &WebElement, - keys: &SendKeysParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_element_send_keys( + &self, + element: &WebElement, + keys: &SendKeysParameters, + ) -> WebDriverResult<WebDriverResponse> { let browsing_context_id = self.session()?.browsing_context_id; let (sender, receiver) = ipc::channel().unwrap(); let cmd = WebDriverScriptCommand::FocusElement(element.id.clone(), sender); let cmd_msg = WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); // TODO: distinguish the not found and not focusable cases - receiver.recv().unwrap().or_else(|_| Err(WebDriverError::new( - ErrorStatus::StaleElementReference, "Element not found or not focusable")))?; - - let keys = keycodes_to_keys(&keys.text).or_else(|_| - Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, "Failed to convert keycodes")))?; + receiver.recv().unwrap().or_else(|_| { + Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Element not found or not focusable", + )) + })?; + + let keys = keycodes_to_keys(&keys.text).or_else(|_| { + Err(WebDriverError::new( + ErrorStatus::UnsupportedOperation, + "Failed to convert keycodes", + )) + })?; // TODO: there's a race condition caused by the focus command and the // send keys command being two separate messages, // so the constellation may have changed state between them. let cmd_msg = WebDriverCommandMsg::SendKeys(browsing_context_id, keys); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); Ok(WebDriverResponse::Void) } @@ -816,7 +1022,9 @@ impl Handler { for _ in 0..iterations { let (sender, receiver) = ipc::channel().unwrap(); let cmd_msg = WebDriverCommandMsg::TakeScreenshot(top_level_id, sender); - self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap(); + self.constellation_chan + .send(ConstellationMsg::WebDriverCommand(cmd_msg)) + .unwrap(); if let Some(x) = receiver.recv().unwrap() { img = Some(x); @@ -828,65 +1036,91 @@ impl Handler { let img = match img { Some(img) => img, - None => return Err(WebDriverError::new(ErrorStatus::Timeout, - "Taking screenshot timed out")), + None => { + return Err(WebDriverError::new( + ErrorStatus::Timeout, + "Taking screenshot timed out", + )) + }, }; // The compositor always sends RGB pixels. - assert_eq!(img.format, PixelFormat::RGB8, "Unexpected screenshot pixel format"); + assert_eq!( + img.format, + PixelFormat::RGB8, + "Unexpected screenshot pixel format" + ); let rgb = RgbImage::from_raw(img.width, img.height, img.bytes.to_vec()).unwrap(); let mut png_data = Vec::new(); - DynamicImage::ImageRgb8(rgb).write_to(&mut png_data, ImageFormat::PNG).unwrap(); + DynamicImage::ImageRgb8(rgb) + .write_to(&mut png_data, ImageFormat::PNG) + .unwrap(); let encoded = base64::encode(&png_data); - Ok(WebDriverResponse::Generic(ValueResponse::new(encoded.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + encoded.to_json(), + ))) } - fn handle_get_prefs(&self, - parameters: &GetPrefsParameters) -> WebDriverResult<WebDriverResponse> { - let prefs = parameters.prefs + fn handle_get_prefs( + &self, + parameters: &GetPrefsParameters, + ) -> WebDriverResult<WebDriverResponse> { + let prefs = parameters + .prefs .iter() .map(|item| (item.clone(), PREFS.get(item).to_json())) .collect::<BTreeMap<_, _>>(); - Ok(WebDriverResponse::Generic(ValueResponse::new(prefs.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + prefs.to_json(), + ))) } - fn handle_set_prefs(&self, - parameters: &SetPrefsParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_set_prefs( + &self, + parameters: &SetPrefsParameters, + ) -> WebDriverResult<WebDriverResponse> { for &(ref key, ref value) in parameters.prefs.iter() { PREFS.set(key, value.clone()); } Ok(WebDriverResponse::Void) } - fn handle_reset_prefs(&self, - parameters: &GetPrefsParameters) -> WebDriverResult<WebDriverResponse> { + fn handle_reset_prefs( + &self, + parameters: &GetPrefsParameters, + ) -> WebDriverResult<WebDriverResponse> { let prefs = if parameters.prefs.len() == 0 { PREFS.reset_all(); BTreeMap::new() } else { - parameters.prefs + parameters + .prefs .iter() .map(|item| (item.clone(), PREFS.reset(item).to_json())) .collect::<BTreeMap<_, _>>() }; - Ok(WebDriverResponse::Generic(ValueResponse::new(prefs.to_json()))) + Ok(WebDriverResponse::Generic(ValueResponse::new( + prefs.to_json(), + ))) } } impl WebDriverHandler<ServoExtensionRoute> for Handler { - fn handle_command(&mut self, - _session: &Option<Session>, - msg: WebDriverMessage<ServoExtensionRoute>) -> WebDriverResult<WebDriverResponse> { + fn handle_command( + &mut self, + _session: &Option<Session>, + msg: WebDriverMessage<ServoExtensionRoute>, + ) -> WebDriverResult<WebDriverResponse> { // Unless we are trying to create a new session, we need to ensure that a // session has previously been created match msg.command { WebDriverCommand::NewSession(_) => {}, _ => { self.session()?; - } + }, } match msg.command { @@ -905,7 +1139,9 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { WebDriverCommand::GetTitle => self.handle_title(), WebDriverCommand::GetWindowHandle => self.handle_window_handle(), WebDriverCommand::GetWindowHandles => self.handle_window_handles(), - WebDriverCommand::SwitchToFrame(ref parameters) => self.handle_switch_to_frame(parameters), + WebDriverCommand::SwitchToFrame(ref parameters) => { + self.handle_switch_to_frame(parameters) + }, WebDriverCommand::SwitchToParentFrame => self.handle_switch_to_parent_frame(), WebDriverCommand::FindElement(ref parameters) => self.handle_find_element(parameters), WebDriverCommand::FindElements(ref parameters) => self.handle_find_elements(parameters), @@ -914,26 +1150,31 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { WebDriverCommand::GetActiveElement => self.handle_active_element(), WebDriverCommand::GetElementRect(ref element) => self.handle_element_rect(element), WebDriverCommand::GetElementText(ref element) => self.handle_element_text(element), - WebDriverCommand::GetElementTagName(ref element) => self.handle_element_tag_name(element), - WebDriverCommand::GetElementAttribute(ref element, ref name) => - self.handle_element_attribute(element, name), - WebDriverCommand::GetCSSValue(ref element, ref name) => - self.handle_element_css(element, name), + WebDriverCommand::GetElementTagName(ref element) => { + self.handle_element_tag_name(element) + }, + WebDriverCommand::GetElementAttribute(ref element, ref name) => { + self.handle_element_attribute(element, name) + }, + WebDriverCommand::GetCSSValue(ref element, ref name) => { + self.handle_element_css(element, name) + }, WebDriverCommand::ExecuteScript(ref x) => self.handle_execute_script(x), WebDriverCommand::ExecuteAsyncScript(ref x) => self.handle_execute_async_script(x), - WebDriverCommand::ElementSendKeys(ref element, ref keys) => - self.handle_element_send_keys(element, keys), + WebDriverCommand::ElementSendKeys(ref element, ref keys) => { + self.handle_element_send_keys(element, keys) + }, WebDriverCommand::SetTimeouts(ref x) => self.handle_set_timeouts(x), WebDriverCommand::TakeScreenshot => self.handle_take_screenshot(), - WebDriverCommand::Extension(ref extension) => { - match *extension { - ServoExtensionCommand::GetPrefs(ref x) => self.handle_get_prefs(x), - ServoExtensionCommand::SetPrefs(ref x) => self.handle_set_prefs(x), - ServoExtensionCommand::ResetPrefs(ref x) => self.handle_reset_prefs(x), - } - } - _ => Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, - "Command not implemented")) + WebDriverCommand::Extension(ref extension) => match *extension { + ServoExtensionCommand::GetPrefs(ref x) => self.handle_get_prefs(x), + ServoExtensionCommand::SetPrefs(ref x) => self.handle_set_prefs(x), + ServoExtensionCommand::ResetPrefs(ref x) => self.handle_reset_prefs(x), + }, + _ => Err(WebDriverError::new( + ErrorStatus::UnsupportedOperation, + "Command not implemented", + )), } } |