Bug 1451916 - Have geckodriver recognise chrome elements. r?whimboo
Before we can deploy
bug 1400233 which removes the JSON Object field
"ELEMENT" from Marionette, we need to make geckodriver recognise
"chromeelement-9fc5-4b51-a3c8-01716eedeb04".
Technically a chrome element is not a web element, but geckodriver
treats it as such. This is in line with previous behaviour but should at
some point be changed when WebDriver supports these types of extensions.
This patch does not drop support for the legacy web element identifier
(ELEMENT) since it would entail dropping support for Firefox 55
and later. The new element identifiers were introduced in Firefox 58.
MozReview-Commit-ID: GiBHcOcvGbh
--- a/testing/geckodriver/CHANGES.md
+++ b/testing/geckodriver/CHANGES.md
@@ -1,13 +1,22 @@
Change log
==========
All notable changes to this program is documented in this file.
+
+Unreleased
+----------
+
+### Added
+
+- Support for the new chrome element identifier in Marionette.
+
+
0.20.1 (2018-04-06)
-------------------
### Fixed
- Avoid attempting to kill Firefox process that has stopped.
With the change to allow Firefox enough time to shut down in
--- a/testing/geckodriver/src/marionette.rs
+++ b/testing/geckodriver/src/marionette.rs
@@ -50,16 +50,18 @@ use webdriver::error::{ErrorStatus, WebD
use webdriver::server::{WebDriverHandler, Session};
use webdriver::httpapi::{WebDriverExtensionRoute};
use capabilities::{FirefoxCapabilities, FirefoxOptions};
use logging;
use prefs;
const DEFAULT_HOST: &'static str = "localhost";
+const CHROME_ELEMENT_KEY: &'static str = "chromeelement-9fc5-4b51-a3c8-01716eedeb04";
+const LEGACY_ELEMENT_KEY: &'static str = "ELEMENT";
pub fn extension_routes() -> Vec<(Method, &'static str, GeckoExtensionRoute)> {
return vec![(Method::Get, "/session/{sessionId}/moz/context", GeckoExtensionRoute::GetContext),
(Method::Post, "/session/{sessionId}/moz/context", GeckoExtensionRoute::SetContext),
(Method::Post,
"/session/{sessionId}/moz/xbl/{elementId}/anonymous_children",
GeckoExtensionRoute::XblAnonymousChildren),
(Method::Post,
@@ -642,35 +644,36 @@ impl MarionetteSession {
self.session_id = session_id.to_string().clone();
},
_ => {}
}
Ok(())
}
fn to_web_element(&self, json_data: &Json) -> WebDriverResult<WebElement> {
- let data = try_opt!(json_data.as_object(),
- ErrorStatus::UnknownError,
- "Failed to convert data to an object");
+ let data = try_opt!(
+ json_data.as_object(),
+ ErrorStatus::UnknownError,
+ "Failed to convert data to an object"
+ );
+
+ let web_element = data.get(ELEMENT_KEY);
+ let chrome_element = data.get(CHROME_ELEMENT_KEY);
+ let legacy_element = data.get(LEGACY_ELEMENT_KEY);
+
+ let value = try_opt!(
+ web_element.or(chrome_element).or(legacy_element),
+ ErrorStatus::UnknownError,
+ "Failed to extract web element from Marionette response"
+ );
let id = try_opt!(
- try_opt!(
- match data.get("ELEMENT") {
- Some(id) => Some(id),
- None => {
- match data.get(ELEMENT_KEY) {
- Some(id) => Some(id),
- None => None
- }
- }
- },
- ErrorStatus::UnknownError,
- "Failed to extract Web Element from response").as_string(),
+ value.as_string(),
ErrorStatus::UnknownError,
- "Failed to convert id value to string"
- ).to_string();
+ "Failed to convert web element reference value to string"
+ ).to_string();
Ok(WebElement::new(id))
}
pub fn next_command_id(&mut self) -> u64 {
self.command_id = self.command_id + 1;
self.command_id
}