mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 1245064 - Implement element pointer-interactability; r=automatedtester
Implements the WebDriver pointer-interactability algorithm described in http://w3c.github.io/webdriver/webdriver-spec.html#dfn-interactable-element. The specification compatible behaviour is enabled only when the client requests the capability specificationLevel >= 0. MozReview-Commit-ID: BP60SGj49OW --HG-- extra : rebase_source : d84d38510e28ab5e0debce2051e336e1fd3f0f86
This commit is contained in:
parent
71b94d4505
commit
e3854ffb41
@ -844,6 +844,87 @@ element.isVisible = function(el, x = undefined, y = undefined) {
|
||||
return true;
|
||||
};
|
||||
|
||||
element.isInteractable = function(el) {
|
||||
return element.isPointerInteractable(el) ||
|
||||
element.isKeyboardInteractable(el);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param {DOMElement} el
|
||||
* Element determine if is pointer-interactable.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if interactable, false otherwise.
|
||||
*/
|
||||
element.isPointerInteractable = function(el) {
|
||||
let tree = element.getInteractableElementTree(el);
|
||||
return tree.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Produces a pointer-interactable elements tree from a given element.
|
||||
*
|
||||
* The tree is defined by the paint order found at the centre point of
|
||||
* the element's rectangle that is inside the viewport, excluding the size
|
||||
* of any rendered scrollbars.
|
||||
*
|
||||
* @param {DOMElement} el
|
||||
* Element to determine if is pointer-interactable.
|
||||
*
|
||||
* @return {Array.<DOMElement>}
|
||||
* Sequence of non-opaque elements in paint order.
|
||||
*/
|
||||
element.getInteractableElementTree = function(el) {
|
||||
let doc = el.ownerDocument;
|
||||
let win = doc.defaultView;
|
||||
|
||||
// step 1
|
||||
// TODO
|
||||
|
||||
// steps 2-3
|
||||
let box = el.getBoundingClientRect();
|
||||
let visible = {
|
||||
width: Math.max(box.x, box.x + box.width) - win.innerWidth,
|
||||
height: Math.max(box.y, box.y + box.height) - win.innerHeight,
|
||||
};
|
||||
|
||||
// steps 4-5
|
||||
let offset = {
|
||||
vertical: visible.width / 2.0,
|
||||
horizontal: visible.height / 2.0,
|
||||
};
|
||||
|
||||
// step 6
|
||||
let centre = {
|
||||
x: box.x + offset.horizontal,
|
||||
y: box.y + offset.vertical,
|
||||
};
|
||||
|
||||
// step 7
|
||||
let tree = doc.elementsFromPoint(centre.x, centre.y);
|
||||
|
||||
// filter out non-interactable elements
|
||||
let rv = [];
|
||||
for (let el of tree) {
|
||||
if (win.getComputedStyle(el).opacity === "1") {
|
||||
rv.push(el);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
// TODO(ato): Not implemented.
|
||||
// In fact, it's not defined in the spec.
|
||||
element.isKeyboardInteractable = function(el) {
|
||||
return true;
|
||||
};
|
||||
|
||||
element.isXULElement = function(el) {
|
||||
let ns = atom.getElementAttribute(el, "namespaceURI");
|
||||
return ns.indexOf("there.is.only.xul") >= 0;
|
||||
|
@ -83,10 +83,22 @@ this.interaction = {};
|
||||
* Element to click.
|
||||
* @param {boolean=} strict
|
||||
* Enforce strict accessibility tests.
|
||||
* @param {boolean=} specCompat
|
||||
* Use WebDriver specification compatible interactability definition.
|
||||
*/
|
||||
interaction.clickElement = function(el, strict = false) {
|
||||
interaction.clickElement = function(el, strict = false, specCompat = false) {
|
||||
let win = getWindow(el);
|
||||
let visible = element.isVisible(el, win);
|
||||
|
||||
let visible = false;
|
||||
if (specCompat) {
|
||||
visible = element.isInteractable(el);
|
||||
if (visible) {
|
||||
el.scrollIntoView(false);
|
||||
}
|
||||
} else {
|
||||
visible = element.isVisible(el);
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
throw new ElementNotVisibleError("Element is not visible");
|
||||
}
|
||||
|
@ -1272,7 +1272,9 @@ function getActiveElement() {
|
||||
function clickElement(id) {
|
||||
let el = elementManager.getKnownElement(id, curContainer);
|
||||
return interaction.clickElement(
|
||||
el, capabilities.raisesAccessibilityExceptions);
|
||||
el,
|
||||
!!capabilities.raisesAccessibilityExceptions,
|
||||
capabilities.specificationLevel >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user