Bug 1317386 - Scroll element into view at the bottom; r?automatedtester
When scrolling an element into view using `Element.scrollIntoView`,
use the `{block: "end", inline: "nearest"}` scroll position arguments,
which are equivalent to `Element.scrollIntoView(false)`. This is what
other WebDriver implementations have used for a while, and we meant to
change to this sooner.
This ensures that the element appears at the bottom of the viewport
rather than the top, where overlaying menus with fixed style position
may more frequently appear.
In the future we might consider replacing this with `{block: "center"}`
which is specified in the CSSOM specification, but not yet implemented
in any browsers.
This implements https://github.com/w3c/webdriver/pull/440, which should
fix https://github.com/mozilla/geckodriver/issues/327.
MozReview-Commit-ID: BRMupP4fM89
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -769,17 +769,17 @@ element.toJson = function(obj, seenEls)
};
/**
* Check if the element is detached from the current frame as well as
* the optional shadow root (when inside a Shadow DOM context).
*
* @param {nsIDOMElement} el
* Element to be checked.
- * @param nsIDOMWindow frame
+ * @param {nsIDOMWindow} frame
* Window object that contains the element or the current host
* of the shadow root.
* @param {ShadowRoot=} shadowRoot
* An optional shadow root containing an element.
*
* @return {boolean}
* Flag indicating that the element is disconnected.
*/
@@ -905,22 +905,18 @@ element.isVisible = function(el, x = und
return false;
}
if (el.tagName.toLowerCase() == "body") {
return true;
}
if (!element.inViewport(el, x, y)) {
- if (el.scrollIntoView) {
- el.scrollIntoView({block: "start", inline: "nearest"});
- if (!element.inViewport(el)) {
- return false;
- }
- } else {
+ element.scrollIntoView(el);
+ if (!element.inViewport(el)) {
return false;
}
}
return true;
};
element.isInteractable = function(el) {
return element.isPointerInteractable(el) ||
@@ -998,16 +994,28 @@ element.getInteractableElementTree = fun
};
// TODO(ato): Not implemented.
// In fact, it's not defined in the spec.
element.isKeyboardInteractable = function(el) {
return true;
};
+/**
+ * Attempts to scroll into view |el|.
+ *
+ * @param {DOMElement} el
+ * Element to scroll into view.
+ */
+element.scrollIntoView = function(el) {
+ if (el.scrollIntoView) {
+ el.scrollIntoView({block: "end", inline: "nearest", behavior: "instant"});
+ }
+};
+
element.isXULElement = function(el) {
let ns = atom.getElementAttribute(el, "namespaceURI");
return ns.indexOf("there.is.only.xul") >= 0;
};
const boolEls = {
audio: ["autoplay", "controls", "loop", "muted"],
button: ["autofocus", "disabled", "formnovalidate"],