Bug 1321516 - Take <select multiple> into account for obscured click test draft
authorAndreas Tolfsen <ato@mozilla.com>
Mon, 17 Apr 2017 17:24:19 +0100
changeset 565892 85e786b9d3096dda786dfd758ff32993053d5d36
parent 565891 559f36c50db9e9641a81f924965fb7c9f99dcb25
child 565893 636d68286175aca5852a28bef7d9561c6b0052eb
push id55051
push userbmo:ato@mozilla.com
push dateThu, 20 Apr 2017 17:08:50 +0000
bugs1321516
milestone55.0a1
Bug 1321516 - Take <select multiple> into account for obscured click test Because individual <option> elements are painted and represented in the DOM when they belong to a <select multiple> list, the center point of the list might be one of the options. To take this into account, we perform an inclusive descendant check (DOMElement.contains) to see if the <option> element is a descendant of the container <select> element. In the case the targetted element is the element itself, the test will still pass since it is an _inclusive_ descendant check. In other words, containerEl.contains(tree[0]), if tree[0] is equal to containerEl, will pass. The relevant specification changes have been proposed in https://github.com/w3c/webdriver/pull/894. MozReview-Commit-ID: 9FVmnygvN7D
testing/marionette/element.js
testing/marionette/interaction.js
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -933,25 +933,29 @@ element.isVisible = function (el, x = un
 };
 
 /**
  * A pointer-interactable element is defined to be the first
  * non-transparent element, defined by the paint order found at the centre
  * point of its rectangle that is inside the viewport, excluding the size
  * of any rendered scrollbars.
  *
+ * An element is obscured if the pointer-interactable paint tree at its
+ * centre point is empty, or the first element in this tree is not an
+ * inclusive descendant of itself.
+ *
  * @param {DOMElement} el
  *     Element determine if is pointer-interactable.
  *
  * @return {boolean}
- *     True if interactable, false otherwise.
+ *     True if element is obscured, false otherwise.
  */
-element.isPointerInteractable = function (el) {
+element.isObscured = function (el) {
   let tree = element.getPointerInteractablePaintTree(el);
-  return tree[0] === el;
+  return !el.contains(tree[0]);
 };
 
 /**
  * Calculate the in-view centre point of the area of the given DOM client
  * rectangle that is inside the viewport.
  *
  * @param {DOMRect} rect
  *     Element off a DOMRect sequence produced by calling |getClientRects|
--- a/testing/marionette/interaction.js
+++ b/testing/marionette/interaction.js
@@ -140,17 +140,17 @@ interaction.clickElement = function* (el
     throw new ElementNotInteractableError(
         error.pprint`Element ${el} could not be scrolled into view`);
   }
 
   // step 7
   let rects = containerEl.getClientRects();
   let clickPoint = element.getInViewCentrePoint(rects[0], win);
 
-  if (!element.isPointerInteractable(containerEl)) {
+  if (element.isObscured(containerEl)) {
     throw new ElementClickInterceptedError(containerEl, clickPoint);
   }
 
   yield a11y.getAccessible(el, true).then(acc => {
     a11y.assertVisible(acc, el, true);
     a11y.assertEnabled(acc, el, true);
     a11y.assertActionable(acc, el);
   });