Bug 1451916 - Have geckodriver recognise chrome elements. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Fri, 06 Apr 2018 14:41:00 +0100
changeset 779724 1a5b0aafd24cb704b9cd178eefc3e902679b7b26
parent 779723 a8061a09cd7064a8783ca9e67979d77fb52e001e
push id105836
push userbmo:ato@sny.no
push dateTue, 10 Apr 2018 12:07:22 +0000
reviewerswhimboo
bugs1451916, 1400233
milestone61.0a1
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
testing/geckodriver/CHANGES.md
testing/geckodriver/src/marionette.rs
--- 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
     }