summaryrefslogtreecommitdiff
path: root/testing/marionette/test_action.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/marionette/test_action.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/marionette/test_action.js')
-rw-r--r--testing/marionette/test_action.js627
1 files changed, 627 insertions, 0 deletions
diff --git a/testing/marionette/test_action.js b/testing/marionette/test_action.js
new file mode 100644
index 0000000000..1c58ced766
--- /dev/null
+++ b/testing/marionette/test_action.js
@@ -0,0 +1,627 @@
+/* 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/. */
+
+"use strict";
+
+const {utils: Cu} = Components;
+
+Cu.import("chrome://marionette/content/action.js");
+Cu.import("chrome://marionette/content/element.js");
+Cu.import("chrome://marionette/content/error.js");
+
+action.inputStateMap = new Map();
+
+add_test(function test_createAction() {
+ Assert.throws(() => new action.Action(), InvalidArgumentError,
+ "Missing Action constructor args");
+ Assert.throws(() => new action.Action(1, 2), InvalidArgumentError,
+ "Missing Action constructor args");
+ Assert.throws(
+ () => new action.Action(1, 2, "sometype"), /Expected string/, "Non-string arguments.");
+ ok(new action.Action("id", "sometype", "sometype"));
+
+ run_next_test();
+});
+
+add_test(function test_defaultPointerParameters() {
+ let defaultParameters = {pointerType: action.PointerType.Mouse};
+ deepEqual(action.PointerParameters.fromJson(), defaultParameters);
+
+ run_next_test();
+});
+
+add_test(function test_processPointerParameters() {
+ let check = (regex, message, arg) => checkErrors(
+ regex, action.PointerParameters.fromJson, [arg], message);
+ let parametersData;
+ for (let d of ["foo", "", "get", "Get"]) {
+ parametersData = {pointerType: d};
+ let message = `parametersData: [pointerType: ${parametersData.pointerType}]`;
+ check(/Unknown pointerType/, message, parametersData);
+ }
+ parametersData.pointerType = "mouse"; //TODO "pen";
+ deepEqual(action.PointerParameters.fromJson(parametersData),
+ {pointerType: "mouse"}); //TODO action.PointerType.Pen});
+
+ run_next_test();
+});
+
+add_test(function test_processPointerUpDownAction() {
+ let actionItem = {type: "pointerDown"};
+ let actionSequence = {type: "pointer", id: "some_id"};
+ for (let d of [-1, "a"]) {
+ actionItem.button = d;
+ checkErrors(
+ /Expected 'button' \(.*\) to be >= 0/, action.Action.fromJson, [actionSequence, actionItem],
+ `button: ${actionItem.button}`);
+ }
+ actionItem.button = 5;
+ let act = action.Action.fromJson(actionSequence, actionItem);
+ equal(act.button, actionItem.button);
+
+ run_next_test();
+});
+
+add_test(function test_validateActionDurationAndCoordinates() {
+ let actionItem = {};
+ let actionSequence = {id: "some_id"};
+ let check = function (type, subtype, message = undefined) {
+ message = message || `duration: ${actionItem.duration}, subtype: ${subtype}`;
+ actionItem.type = subtype;
+ actionSequence.type = type;
+ checkErrors(/Expected '.*' \(.*\) to be >= 0/,
+ action.Action.fromJson, [actionSequence, actionItem], message);
+ };
+ for (let d of [-1, "a"]) {
+ actionItem.duration = d;
+ check("none", "pause");
+ check("pointer", "pointerMove");
+ }
+ actionItem.duration = 5000;
+ for (let name of ["x", "y"]) {
+ actionItem[name] = "a";
+ actionItem.type = "pointerMove";
+ actionSequence.type = "pointer";
+ checkErrors(/Expected '.*' \(.*\) to be an Integer/,
+ action.Action.fromJson, [actionSequence, actionItem],
+ `duration: ${actionItem.duration}, subtype: pointerMove`);
+ }
+ run_next_test();
+});
+
+add_test(function test_processPointerMoveActionOriginValidation() {
+ let actionSequence = {type: "pointer", id: "some_id"};
+ let actionItem = {duration: 5000, type: "pointerMove"};
+ for (let d of [-1, {a: "blah"}, []]) {
+ actionItem.origin = d;
+
+ checkErrors(/Expected \'origin\' to be a string or a web element reference/,
+ action.Action.fromJson,
+ [actionSequence, actionItem],
+ `actionItem.origin: (${getTypeString(d)})`);
+ }
+
+ run_next_test();
+});
+
+add_test(function test_processPointerMoveActionOriginStringValidation() {
+ let actionSequence = {type: "pointer", id: "some_id"};
+ let actionItem = {duration: 5000, type: "pointerMove"};
+ for (let d of ["a", "", "get", "Get"]) {
+ actionItem.origin = d;
+ checkErrors(/Unknown pointer-move origin/,
+ action.Action.fromJson,
+ [actionSequence, actionItem],
+ `actionItem.origin: ${d}`);
+ }
+
+ run_next_test();
+});
+
+add_test(function test_processPointerMoveActionElementOrigin() {
+ let actionSequence = {type: "pointer", id: "some_id"};
+ let actionItem = {duration: 5000, type: "pointerMove"};
+ actionItem.origin = {[element.Key]: "something"};
+ let a = action.Action.fromJson(actionSequence, actionItem);
+ deepEqual(a.origin, actionItem.origin);
+ run_next_test();
+});
+
+add_test(function test_processPointerMoveActionDefaultOrigin() {
+ let actionSequence = {type: "pointer", id: "some_id"};
+ // origin left undefined
+ let actionItem = {duration: 5000, type: "pointerMove"};
+ let a = action.Action.fromJson(actionSequence, actionItem);
+ deepEqual(a.origin, action.PointerOrigin.Viewport);
+ run_next_test();
+});
+
+add_test(function test_processPointerMoveAction() {
+ let actionSequence = {id: "some_id", type: "pointer"};
+ let actionItems = [
+ {
+ duration: 5000,
+ type: "pointerMove",
+ origin: undefined,
+ x: undefined,
+ y: undefined,
+ },
+ {
+ duration: undefined,
+ type: "pointerMove",
+ origin: {[element.Key]: "id", [element.LegacyKey]: "id"},
+ x: undefined,
+ y: undefined,
+ },
+ {
+ duration: 5000,
+ type: "pointerMove",
+ x: 0,
+ y: undefined,
+ origin: undefined,
+ },
+ {
+ duration: 5000,
+ type: "pointerMove",
+ x: 1,
+ y: 2,
+ origin: undefined,
+ },
+ ];
+ for (let expected of actionItems) {
+ let actual = action.Action.fromJson(actionSequence, expected);
+ ok(actual instanceof action.Action);
+ equal(actual.duration, expected.duration);
+ equal(actual.x, expected.x);
+ equal(actual.y, expected.y);
+
+ let origin = expected.origin;
+ if (typeof origin == "undefined") {
+ origin = action.PointerOrigin.Viewport;
+ }
+ deepEqual(actual.origin, origin);
+
+ }
+ run_next_test();
+});
+
+add_test(function test_computePointerDestinationViewport() {
+ let act = { type: "pointerMove", x: 100, y: 200, origin: "viewport"};
+ let inputState = new action.InputState.Pointer(action.PointerType.Mouse);
+ // these values should not affect the outcome
+ inputState.x = "99";
+ inputState.y = "10";
+ let target = action.computePointerDestination(act, inputState);
+ equal(act.x, target.x);
+ equal(act.y, target.y);
+
+ run_next_test();
+});
+
+add_test(function test_computePointerDestinationPointer() {
+ let act = { type: "pointerMove", x: 100, y: 200, origin: "pointer"};
+ let inputState = new action.InputState.Pointer(action.PointerType.Mouse);
+ inputState.x = 10;
+ inputState.y = 99;
+ let target = action.computePointerDestination(act, inputState);
+ equal(act.x + inputState.x, target.x);
+ equal(act.y + inputState.y, target.y);
+
+
+ run_next_test();
+});
+
+add_test(function test_computePointerDestinationElement() {
+ // origin represents a web element
+ // using an object literal instead to test default case in computePointerDestination
+ let act = {type: "pointerMove", x: 100, y: 200, origin: {}};
+ let inputState = new action.InputState.Pointer(action.PointerType.Mouse);
+ let elementCenter = {x: 10, y: 99};
+ let target = action.computePointerDestination(act, inputState, elementCenter);
+ equal(act.x + elementCenter.x, target.x);
+ equal(act.y + elementCenter.y, target.y);
+
+ Assert.throws(
+ () => action.computePointerDestination(act, inputState, {a: 1}),
+ InvalidArgumentError,
+ "Invalid element center coordinates.");
+
+ Assert.throws(
+ () => action.computePointerDestination(act, inputState, undefined),
+ InvalidArgumentError,
+ "Undefined element center coordinates.");
+
+ run_next_test();
+});
+
+add_test(function test_processPointerAction() {
+ let actionSequence = {
+ type: "pointer",
+ id: "some_id",
+ parameters: {
+ pointerType: "mouse" //TODO "touch"
+ },
+ };
+ let actionItems = [
+ {
+ duration: 2000,
+ type: "pause",
+ },
+ {
+ type: "pointerMove",
+ duration: 2000,
+ },
+ {
+ type: "pointerUp",
+ button: 1,
+ }
+ ];
+ for (let expected of actionItems) {
+ let actual = action.Action.fromJson(actionSequence, expected);
+ equal(actual.type, actionSequence.type);
+ equal(actual.subtype, expected.type);
+ equal(actual.id, actionSequence.id);
+ if (expected.type === "pointerUp") {
+ equal(actual.button, expected.button);
+ } else {
+ equal(actual.duration, expected.duration);
+ }
+ if (expected.type !== "pause") {
+ equal(actual.pointerType, actionSequence.parameters.pointerType);
+ }
+ }
+
+ run_next_test();
+});
+
+add_test(function test_processPauseAction() {
+ let actionItem = {type: "pause", duration: 5000};
+ let actionSequence = {id: "some_id"};
+ for (let type of ["none", "key", "pointer"]) {
+ actionSequence.type = type;
+ let act = action.Action.fromJson(actionSequence, actionItem);
+ ok(act instanceof action.Action);
+ equal(act.type, type);
+ equal(act.subtype, actionItem.type);
+ equal(act.id, actionSequence.id);
+ equal(act.duration, actionItem.duration);
+ }
+ actionItem.duration = undefined;
+ let act = action.Action.fromJson(actionSequence, actionItem);
+ equal(act.duration, actionItem.duration);
+
+ run_next_test();
+});
+
+add_test(function test_processActionSubtypeValidation() {
+ let actionItem = {type: "dancing"};
+ let actionSequence = {id: "some_id"};
+ let check = function (regex) {
+ let message = `type: ${actionSequence.type}, subtype: ${actionItem.type}`;
+ checkErrors(regex, action.Action.fromJson, [actionSequence, actionItem], message);
+ };
+ for (let type of ["none", "key", "pointer"]) {
+ actionSequence.type = type;
+ check(new RegExp(`Unknown subtype for ${type} action`));
+ }
+ run_next_test();
+});
+
+add_test(function test_processKeyActionUpDown() {
+ let actionSequence = {type: "key", id: "some_id"};
+ let actionItem = {type: "keyDown"};
+
+ for (let v of [-1, undefined, [], ["a"], {length: 1}, null]) {
+ actionItem.value = v;
+ let message = `actionItem.value: (${getTypeString(v)})`;
+ Assert.throws(() => action.Action.fromJson(actionSequence, actionItem),
+ InvalidArgumentError, message);
+ Assert.throws(() => action.Action.fromJson(actionSequence, actionItem),
+ /Expected 'value' to be a string that represents single code point/, message);
+ }
+
+ actionItem.value = "\uE004";
+ let act = action.Action.fromJson(actionSequence, actionItem);
+ ok(act instanceof action.Action);
+ equal(act.type, actionSequence.type);
+ equal(act.subtype, actionItem.type);
+ equal(act.id, actionSequence.id);
+ equal(act.value, actionItem.value);
+
+ run_next_test();
+});
+
+add_test(function test_processInputSourceActionSequenceValidation() {
+ let actionSequence = {type: "swim", id: "some id"};
+ let check = (message, regex) => checkErrors(
+ regex, action.Sequence.fromJson, [actionSequence], message);
+ check(`actionSequence.type: ${actionSequence.type}`, /Unknown action type/);
+ action.inputStateMap.clear();
+
+ actionSequence.type = "none";
+ actionSequence.id = -1;
+ check(`actionSequence.id: ${getTypeString(actionSequence.id)}`,
+ /Expected 'id' to be a string/);
+ action.inputStateMap.clear();
+
+ actionSequence.id = undefined;
+ check(`actionSequence.id: ${getTypeString(actionSequence.id)}`,
+ /Expected 'id' to be defined/);
+ action.inputStateMap.clear();
+
+ actionSequence.id = "some_id";
+ actionSequence.actions = -1;
+ check(`actionSequence.actions: ${getTypeString(actionSequence.actions)}`,
+ /Expected 'actionSequence.actions' to be an Array/);
+ action.inputStateMap.clear();
+
+ run_next_test();
+});
+
+add_test(function test_processInputSourceActionSequence() {
+ let actionItem = { type: "pause", duration: 5};
+ let actionSequence = {
+ type: "none",
+ id: "some id",
+ actions: [actionItem],
+ };
+ let expectedAction = new action.Action(actionSequence.id, "none", actionItem.type);
+ expectedAction.duration = actionItem.duration;
+ let actions = action.Sequence.fromJson(actionSequence);
+ equal(actions.length, 1);
+ deepEqual(actions[0], expectedAction);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_processInputSourceActionSequencePointer() {
+ let actionItem = {type: "pointerDown", button: 1};
+ let actionSequence = {
+ type: "pointer",
+ id: "9",
+ actions: [actionItem],
+ parameters: {
+ pointerType: "mouse" // TODO "pen"
+ },
+ };
+ let expectedAction = new action.Action(
+ actionSequence.id, actionSequence.type, actionItem.type);
+ expectedAction.pointerType = actionSequence.parameters.pointerType;
+ expectedAction.button = actionItem.button;
+ let actions = action.Sequence.fromJson(actionSequence);
+ equal(actions.length, 1);
+ deepEqual(actions[0], expectedAction);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_processInputSourceActionSequenceKey() {
+ let actionItem = {type: "keyUp", value: "a"};
+ let actionSequence = {
+ type: "key",
+ id: "9",
+ actions: [actionItem],
+ };
+ let expectedAction = new action.Action(
+ actionSequence.id, actionSequence.type, actionItem.type);
+ expectedAction.value = actionItem.value;
+ let actions = action.Sequence.fromJson(actionSequence);
+ equal(actions.length, 1);
+ deepEqual(actions[0], expectedAction);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+
+add_test(function test_processInputSourceActionSequenceInputStateMap() {
+ let id = "1";
+ let actionItem = {type: "pause", duration: 5000};
+ let actionSequence = {
+ type: "key",
+ id: id,
+ actions: [actionItem],
+ };
+ let wrongInputState = new action.InputState.Null();
+ action.inputStateMap.set(actionSequence.id, wrongInputState);
+ checkErrors(/to be mapped to/, action.Sequence.fromJson, [actionSequence],
+ `${actionSequence.type} using ${wrongInputState}`);
+ action.inputStateMap.clear();
+ let rightInputState = new action.InputState.Key();
+ action.inputStateMap.set(id, rightInputState);
+ let acts = action.Sequence.fromJson(actionSequence);
+ equal(acts.length, 1);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_processPointerActionInputStateMap() {
+ let actionItem = {type: "pointerDown"};
+ let id = "1";
+ let parameters = {pointerType: "mouse"};
+ let a = new action.Action(id, "pointer", actionItem.type);
+ let wrongInputState = new action.InputState.Key();
+ action.inputStateMap.set(id, wrongInputState);
+ checkErrors(
+ /to be mapped to InputState whose type is/, action.processPointerAction,
+ [id, parameters, a],
+ `type "pointer" with ${wrongInputState.type} in inputState`);
+ action.inputStateMap.clear();
+
+ // TODO - uncomment once pen is supported
+ //wrongInputState = new action.InputState.Pointer("pen");
+ //action.inputStateMap.set(id, wrongInputState);
+ //checkErrors(
+ // /to be mapped to InputState whose subtype is/, action.processPointerAction,
+ // [id, parameters, a],
+ // `subtype ${parameters.pointerType} with ${wrongInputState.subtype} in inputState`);
+ //action.inputStateMap.clear();
+
+ let rightInputState = new action.InputState.Pointer("mouse");
+ action.inputStateMap.set(id, rightInputState);
+ action.processPointerAction(id, parameters, a);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_createInputState() {
+ for (let kind in action.InputState) {
+ let state;
+ if (kind == "Pointer") {
+ state = new action.InputState[kind]("mouse");
+ } else {
+ state = new action.InputState[kind]();
+ }
+ ok(state);
+ if (kind === "Null") {
+ equal(state.type, "none");
+ } else {
+ equal(state.type, kind.toLowerCase());
+ }
+ }
+ Assert.throws(() => new action.InputState.Pointer(), InvalidArgumentError,
+ "Missing InputState.Pointer constructor arg");
+ Assert.throws(() => new action.InputState.Pointer("foo"), InvalidArgumentError,
+ "Invalid InputState.Pointer constructor arg");
+ run_next_test();
+});
+
+add_test(function test_extractActionChainValidation() {
+ for (let actions of [-1, "a", undefined, null]) {
+ let message = `actions: ${getTypeString(actions)}`;
+ Assert.throws(() => action.Chain.fromJson(actions),
+ InvalidArgumentError, message);
+ Assert.throws(() => action.Chain.fromJson(actions),
+ /Expected 'actions' to be an Array/, message);
+ }
+ run_next_test();
+});
+
+add_test(function test_extractActionChainEmpty() {
+ deepEqual(action.Chain.fromJson([]), []);
+ run_next_test();
+});
+
+add_test(function test_extractActionChain_oneTickOneInput() {
+ let actionItem = {type: "pause", duration: 5000};
+ let actionSequence = {
+ type: "none",
+ id: "some id",
+ actions: [actionItem],
+ };
+ let expectedAction = new action.Action(actionSequence.id, "none", actionItem.type);
+ expectedAction.duration = actionItem.duration;
+ let actionsByTick = action.Chain.fromJson([actionSequence]);
+ equal(1, actionsByTick.length);
+ equal(1, actionsByTick[0].length);
+ deepEqual(actionsByTick, [[expectedAction]]);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_extractActionChain_twoAndThreeTicks() {
+ let mouseActionItems = [
+ {
+ type: "pointerDown",
+ button: 2,
+ },
+ {
+ type: "pointerUp",
+ button: 2,
+ },
+ ];
+ let mouseActionSequence = {
+ type: "pointer",
+ id: "7",
+ actions: mouseActionItems,
+ parameters: {
+ pointerType: "mouse" //TODO "touch"
+ },
+ };
+ let keyActionItems = [
+ {
+ type: "keyDown",
+ value: "a",
+ },
+ {
+ type: "pause",
+ duration: 4,
+ },
+ {
+ type: "keyUp",
+ value: "a",
+ },
+ ];
+ let keyActionSequence = {
+ type: "key",
+ id: "1",
+ actions: keyActionItems,
+ };
+ let actionsByTick = action.Chain.fromJson([keyActionSequence, mouseActionSequence]);
+ // number of ticks is same as longest action sequence
+ equal(keyActionItems.length, actionsByTick.length);
+ equal(2, actionsByTick[0].length);
+ equal(2, actionsByTick[1].length);
+ equal(1, actionsByTick[2].length);
+ let expectedAction = new action.Action(keyActionSequence.id, "key", keyActionItems[2].type);
+ expectedAction.value = keyActionItems[2].value;
+ deepEqual(actionsByTick[2][0], expectedAction);
+ action.inputStateMap.clear();
+
+ // one empty action sequence
+ actionsByTick = action.Chain.fromJson(
+ [keyActionSequence, {type: "none", id: "some", actions: []}]);
+ equal(keyActionItems.length, actionsByTick.length);
+ equal(1, actionsByTick[0].length);
+ action.inputStateMap.clear();
+ run_next_test();
+});
+
+add_test(function test_computeTickDuration() {
+ let expected = 8000;
+ let tickActions = [
+ {type: "none", subtype: "pause", duration: 5000},
+ {type: "key", subtype: "pause", duration: 1000},
+ {type: "pointer", subtype: "pointerMove", duration: 6000},
+ // invalid because keyDown should not have duration, so duration should be ignored.
+ {type: "key", subtype: "keyDown", duration: 100000},
+ {type: "pointer", subtype: "pause", duration: expected},
+ {type: "pointer", subtype: "pointerUp"},
+ ];
+ equal(expected, action.computeTickDuration(tickActions));
+ run_next_test();
+});
+
+add_test(function test_computeTickDuration_empty() {
+ equal(0, action.computeTickDuration([]));
+ run_next_test();
+});
+
+add_test(function test_computeTickDuration_noDurations() {
+ let tickActions = [
+ // invalid because keyDown should not have duration, so duration should be ignored.
+ {type: "key", subtype: "keyDown", duration: 100000},
+ // undefined duration permitted
+ {type: "none", subtype: "pause"},
+ {type: "pointer", subtype: "pointerMove"},
+ {type: "pointer", subtype: "pointerDown"},
+ {type: "key", subtype: "keyUp"},
+ ];
+
+ equal(0, action.computeTickDuration(tickActions));
+ run_next_test();
+});
+
+
+// helpers
+function getTypeString(obj) {
+ return Object.prototype.toString.call(obj);
+};
+
+function checkErrors(regex, func, args, message) {
+ if (typeof message == "undefined") {
+ message = `actionFunc: ${func.name}; args: ${args}`;
+ }
+ Assert.throws(() => func.apply(this, args), InvalidArgumentError, message);
+ Assert.throws(() => func.apply(this, args), regex, message);
+};