Bug 1253244 - Correct x,y offset type checks and add tests; r?automatedtester
The xOffset and yOffset arguments to element.coordinates previously
checked loose falsiness. If a number <= 0 would be given as an argument,
they would not be used and it would return the centre of the element.
This change adds more checks, documentation, and tests.
MozReview-Commit-ID: KmsiVFipzWx
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -745,34 +745,48 @@ element.generateUUID = function() {
/**
* This function generates a pair of coordinates relative to the viewport
* given a target element and coordinates relative to that element's
* top-left corner.
*
* @param {Node} node
* Target node.
- * @param {number=} x
- * Horizontal offset relative to target. Defaults to the centre of
- * the target's bounding box.
- * @param {number=} y
- * Vertical offset relative to target. Defaults to the centre of
- * the target's bounding box.
+ * @param {number=} xOffset
+ * Horizontal offset relative to target's top-left corner.
+ * Defaults to the centre of the target's bounding box.
+ * @param {number=} yOffset
+ * Vertical offset relative to target's top-left corner. Defaults to
+ * the centre of the target's bounding box.
+ *
+ * @return {Object.<string, number>}
+ * X- and Y coordinates.
+ *
+ * @throws TypeError
+ * If |xOffset| or |yOffset| are not numbers.
*/
-element.coordinates = function(node, x = undefined, y = undefined) {
+element.coordinates = function(
+ node, xOffset = undefined, yOffset = undefined) {
+
let box = node.getBoundingClientRect();
- if (!x) {
- x = box.width / 2.0;
+
+ if (typeof xOffset == "undefined" || xOffset === null) {
+ xOffset = box.width / 2.0;
+ }
+ if (typeof yOffset == "undefined" || yOffset === null) {
+ yOffset = box.height / 2.0;
}
- if (!y) {
- y = box.height / 2.0;
+
+ if (typeof yOffset != "number" || typeof xOffset != "number") {
+ throw new TypeError("Offset must be a number");
}
+
return {
- x: box.left + x,
- y: box.top + y,
+ x: box.left + xOffset,
+ y: box.top + yOffset,
};
};
/**
* This function returns true if the node is in the viewport.
*
* @param {Element} element
* Target element.
new file mode 100644
--- /dev/null
+++ b/testing/marionette/test_element.js
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const {utils: Cu} = Components;
+
+Cu.import("chrome://marionette/content/element.js");
+
+let el = {
+ getBoundingClientRect: function() {
+ return {
+ top: 0,
+ left: 0,
+ width: 100,
+ height: 100,
+ };
+ }
+};
+
+add_test(function test_coordinates() {
+ let p = element.coordinates(el);
+ ok(p.hasOwnProperty("x"));
+ ok(p.hasOwnProperty("y"));
+ equal("number", typeof p.x);
+ equal("number", typeof p.y);
+
+ deepEqual({x: 50, y: 50}, element.coordinates(el));
+ deepEqual({x: 10, y: 10}, element.coordinates(el, 10, 10));
+ deepEqual({x: -5, y: -5}, element.coordinates(el, -5, -5));
+
+ Assert.throws(() => element.coordinates(null));
+
+ Assert.throws(() => element.coordinates(el, "string", undefined));
+ Assert.throws(() => element.coordinates(el, undefined, "string"));
+ Assert.throws(() => element.coordinates(el, "string", "string"));
+ Assert.throws(() => element.coordinates(el, {}, undefined));
+ Assert.throws(() => element.coordinates(el, undefined, {}));
+ Assert.throws(() => element.coordinates(el, {}, {}));
+ Assert.throws(() => element.coordinates(el, [], undefined));
+ Assert.throws(() => element.coordinates(el, undefined, []));
+ Assert.throws(() => element.coordinates(el, [], []));
+
+ run_next_test();
+});
--- a/testing/marionette/unit.ini
+++ b/testing/marionette/unit.ini
@@ -2,10 +2,11 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# xpcshell unit tests for Marionette
[DEFAULT]
skip-if = appname == "thunderbird"
+[test_element.js]
[test_error.js]
[test_message.js]