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
--- 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);
});