Backed out 8 changesets (bug 1197146) for Marionette test_selected.py failures.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 25 Aug 2015 21:36:11 -0400
changeset 288902 66e9b94c406649129e114f4b230e4aa0d9f34611
parent 288901 05f2f11077f58a0d417733cd55f6d95ae884c7dd
child 288903 eccb9eac6d168e39f7756927403325c5fddc83f2
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1197146
milestone42.0a2
backs out95ea1b781b0fbcf88259efb1b7ad9217c7476740
9aec50a751b388a98b6562daa156efbd415c453c
33d9c59ab315f32a34a7d06905e7071128739f5e
62fa600295843ebffcf1abac328d7019ecef2542
6e0802b05f7b92b84f3f4474371b6ba60a3b9989
f71ee054aab401eb049b954c26bd813f235b46be
463f3471e857ef9d01e554b2f03797b9131c1bbc
e4069d54d4b18b0acd84074cc2931dbb56a76ea6
Backed out 8 changesets (bug 1197146) for Marionette test_selected.py failures. Backed out changeset 95ea1b781b0f (bug 1197146) Backed out changeset 9aec50a751b3 (bug 1197146) Backed out changeset 33d9c59ab315 (bug 1197146) Backed out changeset 62fa60029584 (bug 1197146) Backed out changeset 6e0802b05f7b (bug 1197146) Backed out changeset f71ee054aab4 (bug 1197146) Backed out changeset 463f3471e857 (bug 1197146) Backed out changeset e4069d54d4b1 (bug 1197146)
testing/marionette/driver.js
testing/marionette/listener.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -1940,20 +1940,20 @@ GeckoDriver.prototype.findElements = fun
             true /* all */,
             resolve,
             reject);
       }).then(null, e => { throw new NoSuchElementError(e.message); });
       break;
 
     case Context.CONTENT:
       resp.value = yield this.listener.findElementsContent({
-          value: cmd.parameters.value,
-          using: cmd.parameters.using,
-          element: cmd.parameters.element,
-          searchTimeout: this.searchTimeout});
+        value: cmd.parameters.value,
+        using: cmd.parameters.using,
+        element: cmd.parameters.element,
+        searchTimeout: this.searchTimeout});
       break;
   }
 };
 
 /**
  * Find elements using the indicated search strategy starting from a
  * known element.  Used for WebDriver Compatibility only.
  *
@@ -2089,17 +2089,17 @@ GeckoDriver.prototype.isElementDisplayed
   switch (this.context) {
     case Context.CHROME:
       let win = this.getCurrentWindow();
       let el = this.curBrowser.elementManager.getKnownElement(id, win);
       resp.value = utils.isElementDisplayed(el);
       break;
 
     case Context.CONTENT:
-      resp.value = yield this.listener.isElementDisplayed(id);
+      resp.value = yield this.listener.isElementDisplayed({id: id});
       break;
   }
 };
 
 /**
  * Return the property of the computed style of an element.
  *
  * @param {string} id
@@ -2114,17 +2114,18 @@ GeckoDriver.prototype.getElementValueOfC
     case Context.CHROME:
       let win = this.getCurrentWindow();
       let el = this.curBrowser.elementManager.getKnownElement(id, win);
       let sty = win.document.defaultView.getComputedStyle(el, null);
       resp.value = sty.getPropertyValue(prop);
       break;
 
     case Context.CONTENT:
-      resp.value = yield this.listener.getElementValueOfCssProperty(id, prop);
+      resp.value = yield this.listener.getElementValueOfCssProperty(
+          {id: id, propertyName: prop});
       break;
   }
 };
 
 /**
  * Check if element is enabled.
  *
  * @param {string} id
@@ -2166,17 +2167,17 @@ GeckoDriver.prototype.isElementSelected 
       } else if (typeof el.selected != "undefined") {
         resp.value = !!el.selected;
       } else {
         resp.value = true;
       }
       break;
 
     case Context.CONTENT:
-      resp.value = yield this.listener.isElementSelected(id);
+      resp.value = yield this.listener.isElementSelected({id: id});
       break;
   }
 };
 
 GeckoDriver.prototype.getElementSize = function(cmd, resp) {
   let id = cmd.parameters.id;
 
   switch (this.context) {
@@ -2303,33 +2304,34 @@ GeckoDriver.prototype.clearElement = fun
       if (el.nodeName == "textbox") {
         el.value = "";
       } else if (el.nodeName == "checkbox") {
         el.checked = false;
       }
       break;
 
     case Context.CONTENT:
-      yield this.listener.clearElement(id);
+      yield this.listener.clearElement({id: id});
       break;
   }
 };
 
 /**
  * Get an element's location on the page.
  *
  * The returned point will contain the x and y coordinates of the
  * top left-hand corner of the given element.  The point (0,0)
  * refers to the upper-left corner of the document.
  *
  * @return {Object.<string, number>}
  *     A point containing X and Y coordinates as properties.
  */
 GeckoDriver.prototype.getElementLocation = function(cmd, resp) {
-  return this.listener.getElementLocation(cmd.parameters.id);
+  resp.value = yield this.listener.getElementLocation(
+      {id: cmd.parameters.id});
 };
 
 /** Add a cookie to the document. */
 GeckoDriver.prototype.addCookie = function(cmd, resp) {
   yield this.listener.addCookie({cookie: cmd.parameters.cookie});
 };
 
 /**
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -12,17 +12,16 @@ let loader = Cc["@mozilla.org/moz/jssubs
 
 loader.loadSubScript("chrome://marionette/content/simpletest.js");
 loader.loadSubScript("chrome://marionette/content/common.js");
 loader.loadSubScript("chrome://marionette/content/actions.js");
 Cu.import("chrome://marionette/content/elements.js");
 Cu.import("chrome://marionette/content/error.js");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 let utils = {};
 utils.window = content;
 // Load Event/ChromeUtils for use with JS scripts:
 loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils);
 loader.loadSubScript("chrome://marionette/content/ChromeUtils.js", utils);
 loader.loadSubScript("chrome://marionette/content/atoms.js", utils);
 loader.loadSubScript("chrome://marionette/content/sendkeys.js", utils);
@@ -143,44 +142,35 @@ function emitTouchEventForIFrame(message
       typeForUtils = domWindowUtils.TOUCH_CONTACT;
       break;
   }
   domWindowUtils.sendNativeTouchPoint(identifier, typeForUtils,
     Math.round(message.screenX * ratio), Math.round(message.screenY * ratio),
     message.force, 90);
 }
 
-// Eventually we will not have a closure for every single command, but
-// use a generic dispatch for all listener commands.
-//
-// Perhaps one could even conceive having a separate instance of
-// CommandProcessor for the listener, because the code is mostly the same.
 function dispatch(fn) {
   return function(msg) {
     let id = msg.json.command_id;
-
-    let req = Task.spawn(function*() {
+    try {
       let rv;
       if (typeof msg.json == "undefined" || msg.json instanceof Array) {
-        return yield fn.apply(null, msg.json);
+        rv = fn.apply(null, msg.json);
       } else {
-        return yield fn(msg.json);
+        rv = fn(msg.json);
       }
-    });
 
-    let okOrValueResponse = rv => {
       if (typeof rv == "undefined") {
         sendOk(id);
       } else {
         sendResponse({value: rv}, id);
       }
-    };
-
-    req.then(okOrValueResponse, err => sendError(err, id))
-        .catch(error.report);
+    } catch (e) {
+      sendError(e, id);
+    }
   };
 }
 
 /**
  * Add a message listener that's tied to our listenerId.
  */
 function addMessageListenerId(messageName, handler) {
   addMessageListener(messageName + listenerId, handler);
@@ -200,23 +190,16 @@ let getActiveElementFn = dispatch(getAct
 let clickElementFn = dispatch(clickElement);
 let goBackFn = dispatch(goBack);
 let getElementAttributeFn = dispatch(getElementAttribute);
 let getElementTextFn = dispatch(getElementText);
 let getElementTagNameFn = dispatch(getElementTagName);
 let getElementRectFn = dispatch(getElementRect);
 let isElementEnabledFn = dispatch(isElementEnabled);
 let getCurrentUrlFn = dispatch(getCurrentUrl);
-let findElementContentFn = dispatch(findElementContent);
-let findElementsContentFn = dispatch(findElementsContent);
-let isElementSelectedFn = dispatch(isElementSelected);
-let getElementLocationFn = dispatch(getElementLocation);
-let clearElementFn = dispatch(clearElement);
-let isElementDisplayedFn = dispatch(isElementDisplayed);
-let getElementValueOfCssPropertyFn = dispatch(getElementValueOfCssProperty);
 
 /**
  * Start all message listeners
  */
 function startListeners() {
   addMessageListenerId("Marionette:receiveFiles", receiveFiles);
   addMessageListenerId("Marionette:newSession", newSession);
   addMessageListenerId("Marionette:executeScript", executeScript);
@@ -229,32 +212,32 @@ function startListeners() {
   addMessageListenerId("Marionette:pollForReadyState", pollForReadyState);
   addMessageListenerId("Marionette:cancelRequest", cancelRequest);
   addMessageListenerId("Marionette:getCurrentUrl", getCurrentUrlFn);
   addMessageListenerId("Marionette:getTitle", getTitleFn);
   addMessageListenerId("Marionette:getPageSource", getPageSourceFn);
   addMessageListenerId("Marionette:goBack", goBackFn);
   addMessageListenerId("Marionette:goForward", goForward);
   addMessageListenerId("Marionette:refresh", refresh);
-  addMessageListenerId("Marionette:findElementContent", findElementContentFn);
-  addMessageListenerId("Marionette:findElementsContent", findElementsContentFn);
+  addMessageListenerId("Marionette:findElementContent", findElementContent);
+  addMessageListenerId("Marionette:findElementsContent", findElementsContent);
   addMessageListenerId("Marionette:getActiveElement", getActiveElementFn);
   addMessageListenerId("Marionette:clickElement", clickElementFn);
   addMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn);
   addMessageListenerId("Marionette:getElementText", getElementTextFn);
   addMessageListenerId("Marionette:getElementTagName", getElementTagNameFn);
-  addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayedFn);
-  addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssPropertyFn);
+  addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
+  addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
   addMessageListenerId("Marionette:getElementSize", getElementSizeFn);  // deprecated
   addMessageListenerId("Marionette:getElementRect", getElementRectFn);
   addMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn);
-  addMessageListenerId("Marionette:isElementSelected", isElementSelectedFn);
+  addMessageListenerId("Marionette:isElementSelected", isElementSelected);
   addMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
-  addMessageListenerId("Marionette:getElementLocation", getElementLocationFn); //deprecated
-  addMessageListenerId("Marionette:clearElement", clearElementFn);
+  addMessageListenerId("Marionette:getElementLocation", getElementLocation); //deprecated
+  addMessageListenerId("Marionette:clearElement", clearElement);
   addMessageListenerId("Marionette:switchToFrame", switchToFrame);
   addMessageListenerId("Marionette:deleteSession", deleteSession);
   addMessageListenerId("Marionette:sleepSession", sleepSession);
   addMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   addMessageListenerId("Marionette:importScript", importScript);
   addMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
   addMessageListenerId("Marionette:setTestName", setTestName);
   addMessageListenerId("Marionette:takeScreenshot", takeScreenshot);
@@ -334,32 +317,32 @@ function deleteSession(msg) {
   removeMessageListenerId("Marionette:pollForReadyState", pollForReadyState);
   removeMessageListenerId("Marionette:cancelRequest", cancelRequest);
   removeMessageListenerId("Marionette:getTitle", getTitleFn);
   removeMessageListenerId("Marionette:getPageSource", getPageSourceFn);
   removeMessageListenerId("Marionette:getCurrentUrl", getCurrentUrlFn);
   removeMessageListenerId("Marionette:goBack", goBackFn);
   removeMessageListenerId("Marionette:goForward", goForward);
   removeMessageListenerId("Marionette:refresh", refresh);
-  removeMessageListenerId("Marionette:findElementContent", findElementContentFn);
-  removeMessageListenerId("Marionette:findElementsContent", findElementsContentFn);
+  removeMessageListenerId("Marionette:findElementContent", findElementContent);
+  removeMessageListenerId("Marionette:findElementsContent", findElementsContent);
   removeMessageListenerId("Marionette:getActiveElement", getActiveElementFn);
   removeMessageListenerId("Marionette:clickElement", clickElementFn);
   removeMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn);
   removeMessageListenerId("Marionette:getElementText", getElementTextFn);
   removeMessageListenerId("Marionette:getElementTagName", getElementTagNameFn);
-  removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayedFn);
-  removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssPropertyFn);
+  removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
+  removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
   removeMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated
   removeMessageListenerId("Marionette:getElementRect", getElementRectFn);
   removeMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn);
-  removeMessageListenerId("Marionette:isElementSelected", isElementSelectedFn);
+  removeMessageListenerId("Marionette:isElementSelected", isElementSelected);
   removeMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
-  removeMessageListenerId("Marionette:getElementLocation", getElementLocationFn);
-  removeMessageListenerId("Marionette:clearElement", clearElementFn);
+  removeMessageListenerId("Marionette:getElementLocation", getElementLocation);
+  removeMessageListenerId("Marionette:clearElement", clearElement);
   removeMessageListenerId("Marionette:switchToFrame", switchToFrame);
   removeMessageListenerId("Marionette:deleteSession", deleteSession);
   removeMessageListenerId("Marionette:sleepSession", sleepSession);
   removeMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   removeMessageListenerId("Marionette:importScript", importScript);
   removeMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
   removeMessageListenerId("Marionette:setTestName", setTestName);
   removeMessageListenerId("Marionette:takeScreenshot", takeScreenshot);
@@ -1352,45 +1335,43 @@ function refresh(msg) {
   let listen = function() {
     removeEventListener("DOMContentLoaded", arguments.callee, false);
     sendOk(command_id);
   };
   addEventListener("DOMContentLoaded", listen, false);
 }
 
 /**
- * Find an element in the current browsing context's document using the
- * given search strategy.
+ * Find an element in the document using requested search strategy
  */
-function findElementContent(opts) {
-  return new Promise((resolve, reject) => {
-    elementManager.find(
-        curFrame,
-        opts,
-        opts.searchTimeout,
-        false /* all */,
-        resolve,
-        reject);
-  });
+function findElementContent(msg) {
+  let command_id = msg.json.command_id;
+  try {
+    let onSuccess = (el, id) => sendResponse({value: el}, id);
+    let onError = (err, id) => sendError(err, id);
+    elementManager.find(curFrame, msg.json, msg.json.searchTimeout,
+        false /* all */, onSuccess, onError, command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
- * Find elements in the current browsing context's document using the
- * given search strategy.
+ * Find elements in the document using requested search strategy
  */
-function findElementsContent(opts) {
-  return new Promise((resolve, reject) => {
-    elementManager.find(
-        curFrame,
-        opts,
-        opts.searchTimeout,
-        true /* all */,
-        resolve,
-        reject);
-  });
+function findElementsContent(msg) {
+  let command_id = msg.json.command_id;
+  try {
+    let onSuccess = (els, id) => sendResponse({value: els}, id);
+    let onError = (err, id) => sendError(err, id);
+    elementManager.find(curFrame, msg.json, msg.json.searchTimeout,
+        true /* all */, onSuccess, onError, command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
  * Find and return the active element on the page.
  *
  * @return {WebElement}
  *     Reference to web element.
  */
@@ -1461,44 +1442,48 @@ function getElementText(id) {
  *     Tag name of element.
  */
 function getElementTagName(id) {
   let el = elementManager.getKnownElement(id, curFrame);
   return el.tagName.toLowerCase();
 }
 
 /**
- * Determine the element displayedness of the given web element.
- *
- * Also performs additional accessibility checks if enabled by session
- * capability.
+ * Check if element is displayed
  */
-function isElementDisplayed(id) {
-  let el = elementManager.getKnownElement(id, curFrame);
-  let displayed = utils.isElementDisplayed(el);
-  checkVisibleAccessibility(accessibility.getAccessibleObject(el), displayed);
-  return displayed;
+function isElementDisplayed(msg) {
+  let command_id = msg.json.command_id;
+  try {
+    let el = elementManager.getKnownElement(msg.json.id, curFrame);
+    let displayed = utils.isElementDisplayed(el);
+    checkVisibleAccessibility(accessibility.getAccessibleObject(el), displayed);
+    sendResponse({value: displayed}, command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
- * Retrieves the computed value of the given CSS property of the given
- * web element.
- *
- * @param {String} id
- *     Web element reference.
- * @param {String} prop
- *     The CSS property to get.
+ * Return the property of the computed style of an element
  *
- * @return {String}
- *     Effective value of the requested CSS property.
+ * @param object aRequest
+ *               'element' member holds the reference id to
+ *               the element that will be checked
+ *               'propertyName' is the CSS rule that is being requested
  */
-function getElementValueOfCssProperty(id, prop) {
-  let el = elementManager.getKnownElement(id, curFrame);
-  let st = curFrame.document.defaultView.getComputedStyle(el, null);
-  return st.getPropertyValue(prop);
+function getElementValueOfCssProperty(msg) {
+  let command_id = msg.json.command_id;
+  let propertyName = msg.json.propertyName;
+  try {
+    let el = elementManager.getKnownElement(msg.json.id, curFrame);
+    sendResponse({value: curFrame.document.defaultView.getComputedStyle(el, null).getPropertyValue(propertyName)},
+                 command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
  * Get the size of the element.
  *
  * @param {WebElement} id
  *     Web element reference.
  *
@@ -1543,24 +1528,26 @@ function getElementRect(id) {
 function isElementEnabled(id) {
   let el = elementManager.getKnownElement(id, curFrame);
   let enabled = utils.isElementEnabled(el);
   checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), enabled);
   return enabled;
 }
 
 /**
- * Determines if the referenced element is selected or not.
- *
- * This operation only makes sense on input elements of the Checkbox-
- * and Radio Button states, or option elements.
+ * Check if element is selected
  */
-function isElementSelected(id) {
-  let el = elementManager.getKnownElement(id, curFrame);
-  return selected;
+function isElementSelected(msg) {
+  let command_id = msg.json.command_id;
+  try {
+    let el = elementManager.getKnownElement(msg.json.id, curFrame);
+    sendResponse({value: utils.isElementSelected(el)}, command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
  * Send keys to element
  */
 function sendKeysToElement(msg) {
   let command_id = msg.json.command_id;
   let val = msg.json.value;
@@ -1577,41 +1564,52 @@ function sendKeysToElement(msg) {
   } else {
     utils.sendKeysToElement(curFrame, el, val, sendOk, sendError, command_id);
   }
 }
 
 /**
  * Get the element's top left-hand corner point.
  */
-function getElementLocation(id) {
-  let el = elementManager.getKnownElement(id, curFrame);
-  let rect = el.getBoundingClientRect();
-  return {x: rect.left, y: rect.top};
+function getElementLocation(msg) {
+  let command_id = msg.json.command_id;
+  try {
+    let el = elementManager.getKnownElement(msg.json.id, curFrame);
+    let rect = el.getBoundingClientRect();
+
+    let location = {};
+    location.x = rect.left;
+    location.y = rect.top;
+
+    sendResponse({value: location}, command_id);
+  } catch (e) {
+    sendError(e, command_id);
+  }
 }
 
 /**
- * Clear the text of an element.
+ * Clear the text of an element
  */
-function clearElement(id) {
+function clearElement(msg) {
+  let command_id = msg.json.command_id;
   try {
-    let el = elementManager.getKnownElement(id, curFrame);
+    let el = elementManager.getKnownElement(msg.json.id, curFrame);
     if (el.type == "file") {
       el.value = null;
     } else {
       utils.clearElement(el);
     }
+    sendOk(command_id);
   } catch (e) {
     // Bug 964738: Newer atoms contain status codes which makes wrapping
     // this in an error prototype that has a status property unnecessary
     if (e.name == "InvalidElementStateError") {
-      throw new InvalidElementStateError(e.message);
-    } else {
-      throw e;
+      e = new InvalidElementStateError(e.message);
     }
+    sendError(e, command_id);
   }
 }
 
 /**
  * Switch to frame given either the server-assigned element id,
  * its index in window.frames, or the iframe's name or id.
  */
 function switchToFrame(msg) {