Bug 1359079 - Take <select multiple> into account for obscured click test; r=whimboo

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 were made in
40abcefd6a.

MozReview-Commit-ID: ORX8zLxQJ

--HG--
extra : rebase_source : 87ca38df6696257d569ef1ffcb888426d1f569af
This commit is contained in:
Andreas Tolfsen 2017-04-17 17:24:19 +01:00
parent 95edf04ce7
commit 8f9f92f1cb
3 changed files with 26 additions and 4 deletions

View File

@ -949,15 +949,19 @@ element.isVisible = function (el, x = undefined, y = undefined) {
* 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]);
};
/**

View File

@ -269,6 +269,24 @@ class TestClick(TestLegacyClick):
button.click()
self.assertFalse(self.marionette.execute_script("return window.clicked", sandbox=None))
def test_inclusive_descendant(self):
self.marionette.navigate(inline("""
<select multiple>
<option>first
<option>second
<option>third
</select>"""))
select = self.marionette.find_element(By.TAG_NAME, "select")
# This tests that the pointer-interactability test does not
# cause an ElementClickInterceptedException.
#
# At a <select multiple>'s in-view centre point, you might
# find a fully rendered <option>. Marionette should test that
# the paint tree at this point _contains_ <option>, not that the
# first element of the paint tree is _equal_ to <select>.
select.click()
class TestClickNavigation(MarionetteTestCase):

View File

@ -157,7 +157,7 @@ function* webdriverClickElement (el, a11y) {
let rects = containerEl.getClientRects();
let clickPoint = element.getInViewCentrePoint(rects[0], win);
if (!element.isPointerInteractable(containerEl)) {
if (element.isObscured(containerEl)) {
throw new ElementClickInterceptedError(containerEl, clickPoint);
}