aboutsummaryrefslogtreecommitdiffstats
path: root/components/webdriver_server/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/webdriver_server/lib.rs')
-rw-r--r--components/webdriver_server/lib.rs107
1 files changed, 100 insertions, 7 deletions
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index 0d92be01a3f..cd479d7fae6 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -667,6 +667,7 @@ impl Handler {
cmd_msg: WebDriverScriptCommand,
) -> WebDriverResult<()> {
let browsing_context_id = self.session()?.browsing_context_id;
+ self.verify_browsing_context_is_open(browsing_context_id)?;
let msg = EmbedderToConstellationMessage::WebDriverCommand(
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd_msg),
);
@@ -675,7 +676,9 @@ impl Handler {
}
fn top_level_script_command(&self, cmd_msg: WebDriverScriptCommand) -> WebDriverResult<()> {
- let browsing_context_id = BrowsingContextId::from(self.session()?.webview_id);
+ let webview_id = self.session()?.webview_id;
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
+ let browsing_context_id = BrowsingContextId::from(webview_id);
let msg = EmbedderToConstellationMessage::WebDriverCommand(
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd_msg),
);
@@ -683,7 +686,14 @@ impl Handler {
Ok(())
}
+ /// <https://w3c.github.io/webdriver/#navigate-to>
fn handle_get(&self, parameters: &GetParameters) -> WebDriverResult<WebDriverResponse> {
+ let webview_id = self.session()?.webview_id;
+ // Step 2. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
+ // Step 3. If URL is not an absolute URL or is not an absolute URL with fragment
+ // or not a local scheme, return error with error code invalid argument.
let url = match ServoUrl::parse(&parameters.url[..]) {
Ok(url) => url,
Err(_) => {
@@ -694,8 +704,6 @@ impl Handler {
},
};
- let webview_id = self.session()?.webview_id;
-
let cmd_msg =
WebDriverCommandMsg::LoadUrl(webview_id, url, self.load_status_sender.clone());
self.constellation_chan
@@ -732,6 +740,9 @@ impl Handler {
fn handle_window_size(&self) -> WebDriverResult<WebDriverResponse> {
let (sender, receiver) = ipc::channel().unwrap();
let webview_id = self.session()?.webview_id;
+
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
+
let cmd_msg = WebDriverCommandMsg::GetWindowSize(webview_id, sender);
self.constellation_chan
@@ -764,6 +775,11 @@ impl Handler {
let height = params.height.unwrap_or(0);
let size = Size2D::new(width as u32, height as u32);
let webview_id = self.session()?.webview_id;
+ // TODO: Return some other error earlier if the size is invalid.
+
+ // Step 12. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
let cmd_msg = WebDriverCommandMsg::SetWindowSize(webview_id, size.to_i32(), sender.clone());
self.constellation_chan
@@ -793,6 +809,10 @@ impl Handler {
}
fn handle_is_enabled(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
+ // Step 1. If session's current browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_browsing_context_is_open(self.session()?.browsing_context_id)?;
+
let (sender, receiver) = ipc::channel().unwrap();
self.top_level_script_command(WebDriverScriptCommand::IsEnabled(
@@ -809,6 +829,10 @@ impl Handler {
}
fn handle_is_selected(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
+ // Step 1. If session's current browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_browsing_context_is_open(self.session()?.browsing_context_id)?;
+
let (sender, receiver) = ipc::channel().unwrap();
self.top_level_script_command(WebDriverScriptCommand::IsSelected(
@@ -826,6 +850,9 @@ impl Handler {
fn handle_go_back(&self) -> WebDriverResult<WebDriverResponse> {
let webview_id = self.session()?.webview_id;
+ // Step 1. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
let direction = TraversalDirection::Back(1);
let msg = EmbedderToConstellationMessage::TraverseHistory(webview_id, direction);
self.constellation_chan.send(msg).unwrap();
@@ -834,6 +861,9 @@ impl Handler {
fn handle_go_forward(&self) -> WebDriverResult<WebDriverResponse> {
let webview_id = self.session()?.webview_id;
+ // Step 1. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
let direction = TraversalDirection::Forward(1);
let msg = EmbedderToConstellationMessage::TraverseHistory(webview_id, direction);
self.constellation_chan.send(msg).unwrap();
@@ -842,6 +872,9 @@ impl Handler {
fn handle_refresh(&self) -> WebDriverResult<WebDriverResponse> {
let webview_id = self.session()?.webview_id;
+ // Step 1. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
let cmd_msg = WebDriverCommandMsg::Refresh(webview_id, self.load_status_sender.clone());
self.constellation_chan
@@ -864,6 +897,9 @@ impl Handler {
fn handle_window_handle(&self) -> WebDriverResult<WebDriverResponse> {
let session = self.session.as_ref().unwrap();
+ // Step 1. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(session.webview_id)?;
match session.window_handles.get(&session.webview_id) {
Some(handle) => Ok(WebDriverResponse::Generic(ValueResponse(
serde_json::to_value(handle)?,
@@ -929,10 +965,13 @@ impl Handler {
}
}
+ /// <https://w3c.github.io/webdriver/#close-window>
fn handle_close_window(&mut self) -> WebDriverResult<WebDriverResponse> {
{
+ let webview_id = self.session()?.webview_id;
+ self.verify_top_level_browsing_context_is_open(webview_id)?;
let session = self.session_mut().unwrap();
- session.window_handles.remove(&session.webview_id);
+ session.window_handles.remove(&webview_id);
let cmd_msg = WebDriverCommandMsg::CloseWebView(session.webview_id);
self.constellation_chan
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
@@ -949,6 +988,7 @@ impl Handler {
)))
}
+ /// <https://w3c.github.io/webdriver/#new-window>
fn handle_new_window(
&mut self,
_parameters: &NewWindowParameters,
@@ -956,11 +996,15 @@ impl Handler {
let (sender, receiver) = ipc::channel().unwrap();
let session = self.session().unwrap();
+ self.verify_top_level_browsing_context_is_open(session.webview_id)?;
+
let cmd_msg = WebDriverCommandMsg::NewWebView(
session.webview_id,
sender,
self.load_status_sender.clone(),
);
+ // Step 5. Create a new top-level browsing context by running the window open steps.
+ // This MUST be done without invoking the focusing steps.
self.constellation_chan
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
.unwrap();
@@ -968,8 +1012,6 @@ impl Handler {
let mut handle = self.session.as_ref().unwrap().id.to_string();
if let Ok(new_webview_id) = receiver.recv() {
let session = self.session_mut().unwrap();
- session.webview_id = new_webview_id;
- session.browsing_context_id = BrowsingContextId::from(new_webview_id);
let new_handle = Uuid::new_v4().to_string();
handle = new_handle.clone();
session.window_handles.insert(new_webview_id, new_handle);
@@ -1501,6 +1543,9 @@ impl Handler {
&mut self,
parameters: ActionsParameters,
) -> WebDriverResult<WebDriverResponse> {
+ // Step 1. If session's current browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_browsing_context_is_open(self.session()?.browsing_context_id)?;
// Step 5. Let actions by tick be the result of trying to extract an action sequence
let actions_by_tick = self.extract_an_action_sequence(parameters);
@@ -1516,6 +1561,9 @@ impl Handler {
// TODO: The previous implementation of this function was different from the spec.
// Need to re-implement this to match the spec.
let session = self.session()?;
+ // Step 1. If session's current browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_browsing_context_is_open(session.browsing_context_id)?;
session.input_state_table.borrow_mut().clear();
Ok(WebDriverResponse::Void)
@@ -1635,7 +1683,9 @@ impl Handler {
keys: &SendKeysParameters,
) -> WebDriverResult<WebDriverResponse> {
let browsing_context_id = self.session()?.browsing_context_id;
-
+ // Step 3. If session's current browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_browsing_context_is_open(browsing_context_id)?;
let (sender, receiver) = ipc::channel().unwrap();
let cmd = WebDriverScriptCommand::WillSendKeys(
@@ -1755,6 +1805,9 @@ impl Handler {
}
fn take_screenshot(&self, rect: Option<Rect<f32, CSSPixel>>) -> WebDriverResult<String> {
+ // Step 1. If session's current top-level browsing context is no longer open,
+ // return error with error code no such window.
+ self.verify_top_level_browsing_context_is_open(self.session()?.webview_id)?;
let mut img = None;
let interval = 1000;
@@ -1902,6 +1955,46 @@ impl Handler {
serde_json::to_value(map)?,
)))
}
+
+ fn verify_top_level_browsing_context_is_open(
+ &self,
+ webview_id: WebViewId,
+ ) -> Result<(), WebDriverError> {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.constellation_chan
+ .send(EmbedderToConstellationMessage::WebDriverCommand(
+ WebDriverCommandMsg::IsWebViewOpen(webview_id, sender),
+ ))
+ .unwrap();
+ if !receiver.recv().unwrap_or(false) {
+ Err(WebDriverError::new(
+ ErrorStatus::NoSuchWindow,
+ "No such window",
+ ))
+ } else {
+ Ok(())
+ }
+ }
+
+ fn verify_browsing_context_is_open(
+ &self,
+ browsing_context_id: BrowsingContextId,
+ ) -> Result<(), WebDriverError> {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.constellation_chan
+ .send(EmbedderToConstellationMessage::WebDriverCommand(
+ WebDriverCommandMsg::IsBrowsingContextOpen(browsing_context_id, sender),
+ ))
+ .unwrap();
+ if !receiver.recv().unwrap_or(false) {
+ Err(WebDriverError::new(
+ ErrorStatus::NoSuchWindow,
+ "No such window",
+ ))
+ } else {
+ Ok(())
+ }
+ }
}
impl WebDriverHandler<ServoExtensionRoute> for Handler {