Bug 1255955 - Make interaction.clickElement return a promise; r?automatedtester draft
authorAndreas Tolfsen <ato@mozilla.com>
Tue, 09 Aug 2016 14:05:15 +0100
changeset 398577 bbe2f196d3f12990333fa2643d95644cb96faa97
parent 398576 e2525aeb1bfb6b1d150c1467eff1bbdcc29669b1
child 398578 50da9f1be66821db164d13d61eee4b1dec014572
push id25574
push userbmo:ato@mozilla.com
push dateTue, 09 Aug 2016 13:26:03 +0000
reviewersautomatedtester
bugs1255955
milestone51.0a1
Bug 1255955 - Make interaction.clickElement return a promise; r?automatedtester Accessibility checks will not pass if visibility checks are not performed first. To enforce this ordering we return a chained promise. MozReview-Commit-ID: 95RhUjYrlk8
testing/marionette/interaction.js
--- a/testing/marionette/interaction.js
+++ b/testing/marionette/interaction.js
@@ -74,28 +74,41 @@ const SELECTED_PROPERTY_SUPPORTED_XUL = 
   "TAB",
 ]);
 
 this.interaction = {};
 
 /**
  * Interact with an element by clicking it.
  *
+ * Performs visibility or interactability checks, depending on whether
+ * |specCompat| is required, accessibility checks if |strict| is needed,
+ * and finally interacts with the element if all tests pass.
+ *
  * @param {DOMElement|XULElement} el
  *     Element to click.
  * @param {boolean=} strict
  *     Enforce strict accessibility tests.
  * @param {boolean=} specCompat
  *     Use WebDriver specification compatible interactability definition.
+ *
+ * @return {Promise}
+ *
+ * @throws {ElementNotVisibleError}
+ *     If element is not visible or interactable.
+ * @throws {ElementNotAccessibleError}
+ *     If accessibility checks fail, or it is not possible to activate
+ *     |el| with the accessibility framework.
  */
 interaction.clickElement = function(el, strict = false, specCompat = false) {
+  let win = getWindow(el);
   let a11y = accessibility.get(strict);
-  return a11y.getAccessible(el, true).then(acc => {
-    let win = getWindow(el);
 
+  // determine visibiliy/interactability
+  return new Promise((resolve, reject) => {
     let selectEl;
     let visibilityCheckEl = el;
     if (el.localName == "option") {
       selectEl = interaction.getSelectForOptionElement(el);
       visibilityCheckEl = selectEl;
     }
 
     let visible = false;
@@ -107,23 +120,31 @@ interaction.clickElement = function(el, 
       visible = element.isInteractable(visibilityCheckEl);
     } else {
       visible = element.isVisible(visibilityCheckEl);
     }
 
     if (!visible) {
       throw new ElementNotVisibleError("Element is not visible");
     }
-    a11y.assertVisible(acc, visibilityCheckEl, visible);
-    if (!atom.isElementEnabled(visibilityCheckEl)) {
-      throw new InvalidElementStateError("Element is not enabled");
-    }
-    a11y.assertEnabled(acc, visibilityCheckEl, true);
-    a11y.assertActionable(acc, visibilityCheckEl);
+    resolve(visible);
 
+  // accessibility checks
+  }).then(visible => {
+    return a11y.getAccessible(el, true).then(acc => {
+      a11y.assertVisible(acc, el, visible);
+      if (!atom.isElementEnabled(el)) {
+        throw new InvalidElementStateError("Element is not enabled");
+      }
+      a11y.assertEnabled(acc, el, true);
+      a11y.assertActionable(acc, el);
+    });
+
+  // interact
+  }).then(() => {
     // chrome elements
     if (element.isXULElement(el)) {
       if (el.localName == "option") {
         interaction.selectOption(el);
       } else {
         el.click();
       }