summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2011-01-28 21:59:48 -0500
committerKris Maglione <maglione.k@gmail.com>2011-01-28 21:59:48 -0500
commit199604041ba15664cc6f39c250901a7007ba3402 (patch)
tree938c367d88c0349ed17e28894a5350e4166b9c66
parent5cba6cbc773065bdc20cb7819f69e4e8550b041f (diff)
downloadpentadactyl-199604041ba15664cc6f39c250901a7007ba3402.tar.gz
Add a half slew of generic command execution/completion/code coverage tests. Add unhandled exception checking to tests. Fix some detected merge artifacts.
-rw-r--r--common/Makefile4
-rw-r--r--common/content/commandline.js4
-rw-r--r--common/content/dactyl.js29
-rw-r--r--common/modules/addons.jsm2
-rw-r--r--common/modules/base.jsm2
-rw-r--r--common/modules/completion.jsm9
-rw-r--r--common/modules/downloads.jsm2
-rw-r--r--common/modules/util.jsm5
-rw-r--r--common/tests/functional/dactyl.js397
-rw-r--r--common/tests/functional/testEchoCommands.js13
-rw-r--r--common/tests/functional/testFindCommands.js7
-rw-r--r--common/tests/functional/testHelpCommands.js4
-rw-r--r--common/tests/functional/testShellCommands.js4
-rw-r--r--common/tests/functional/testVersionCommand.js4
14 files changed, 422 insertions, 64 deletions
diff --git a/common/Makefile b/common/Makefile
index 846deb09..6d537643 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -36,7 +36,7 @@ XPI_BINS = $(JAR_BINS)
XPI_NAME = $(NAME)-$(VERSION)
XPI = ../downloads/$(XPI_NAME).xpi
-XPI_PATH = $(TOP)$(XPI:%.xpi=%)
+XPI_PATH = $(TOP)/$(XPI:%.xpi=%)
RDF = ../downloads/update.rdf
RDF_IN = $(RDF).in
@@ -162,7 +162,7 @@ distclean:
rm -rf $(BUILD_DIR)
# TODO: generalize log path
-test: $(XPI)
+test: xpi
@echo "Running functional tests..."
$(MOZMILL) --show-all -l /tmp/dactyl-test.log -b $(HOSTAPP_PATH) --addons $(XPI) -t $(TEST_DIR)
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 6fa3c94f..51ed7f5a 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -204,7 +204,9 @@ var CommandWidgets = Class("CommandWidgets", {
[this.commandbar, this.statusbar].forEach(function (nodeSet) {
let elem = nodeSet[obj.name];
- if (val != null) {
+ if (val == null)
+ elem.value = "";
+ else {
highlight.highlightNode(elem,
(val[0] != null ? val[0] : obj.defaultGroup)
.split(/\s/).filter(util.identity)
diff --git a/common/content/dactyl.js b/common/content/dactyl.js
index 76db2f82..45096aef 100644
--- a/common/content/dactyl.js
+++ b/common/content/dactyl.js
@@ -155,7 +155,18 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
if (type in this._observers)
this._observers[type] = this._observers[type].filter(function (callback) {
if (callback.get()) {
- callback.get().apply(null, args);
+ try {
+ try {
+ callback.get().apply(null, args);
+ }
+ catch (e if e.message == "can't wrap XML objects") {
+ // Horrible kludge.
+ callback.get().apply(null, [String(args[0])].concat(args.slice(1)))
+ }
+ }
+ catch (e) {
+ dactyl.reportError(e);
+ }
return true;
}
});
@@ -207,6 +218,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* 'visualbell' option.
*/
beep: function () {
+ this.triggerObserver("beep");
if (options["visualbell"]) {
let elems = {
bell: document.getElementById("dactyl-bell"),
@@ -1087,6 +1099,12 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
}
},
+ onExecute: function onExecute(event) {
+ let cmd = event.originalTarget.getAttribute("dactyl-execute");
+ commands.execute(cmd, null, false, null,
+ { file: "[Command Line]", line: 1 });
+ },
+
/**
* Opens one or more URLs. Returns true when load was initiated, or
* false on error.
@@ -1331,9 +1349,13 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
*/
reportError: function reportError(error, echo) {
if (error instanceof FailedAssertion || error.message === "Interrupted") {
+
let prefix = io.sourcing ? io.sourcing.file + ":" + io.sourcing.line + ": " : "";
+ if (error.message && error.message.indexOf(prefix) !== 0)
+ error.message = prefix + error.message;
+
if (error.message)
- dactyl.echoerr(template.linkifyHelp(prefix + error.message));
+ dactyl.echoerr(template.linkifyHelp(error.message));
else
dactyl.beep();
return;
@@ -1428,6 +1450,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
}, {
events: function () {
events.addSessionListener(window, "click", dactyl.closure.onClick, true);
+ events.addSessionListener(window, "dactyl.execute", dactyl.closure.onExecute, true);
},
// Only general options are added here, which are valid for all Dactyl extensions
options: function () {
@@ -1670,7 +1693,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
function (args) {
try {
let cmd = dactyl.userEval(args[0] || "");
- dactyl.execute(cmd, null, true);
+ dactyl.execute(cmd || "", null, true);
}
catch (e) {
dactyl.echoerr(e);
diff --git a/common/modules/addons.jsm b/common/modules/addons.jsm
index 2cd642a8..484f47b6 100644
--- a/common/modules/addons.jsm
+++ b/common/modules/addons.jsm
@@ -302,7 +302,7 @@ var AddonList = Class("AddonList", {
if (addon && addon.id in this.addons)
this.addons[addon.id].update();
if (this.ready)
- this.modules.mow.resize(false);
+ this.modules.commandline.updateOutputHeight(false);
},
onDisabled: function (addon) { this.update(addon); },
diff --git a/common/modules/base.jsm b/common/modules/base.jsm
index 9e04c492..8e0c6cc8 100644
--- a/common/modules/base.jsm
+++ b/common/modules/base.jsm
@@ -658,7 +658,7 @@ function Class() {
var Constructor = eval(String.replace(<![CDATA[
(function constructor() {
- let self = Object.create(Constructor.prototype, {
+ var self = Object.create(Constructor.prototype, {
constructor: { value: Constructor },
});
self.instance = self;
diff --git a/common/modules/completion.jsm b/common/modules/completion.jsm
index 9f291f02..8716c4a1 100644
--- a/common/modules/completion.jsm
+++ b/common/modules/completion.jsm
@@ -870,10 +870,15 @@ var Completion = Module("completion", {
context = context.contexts["/list"];
context.wait();
+ let contexts = context.contextList.filter(function (c) c.hasItems && c.items.length);
+ if (!contexts.length)
+ contexts = context.contextList.filter(function (c) c.hasItems).slice(0, 1);
+ if (!contexts.length)
+ contexts = context.contextList.slice(-1);
+
modules.commandline.commandOutput(
<div highlight="Completions">
- { template.map(context.contextList.filter(function (c) c.hasItems && c.items.length),
- function (context)
+ { template.map(contexts, function (context)
template.completionRow(context.title, "CompTitle") +
template.map(context.items, function (item) context.createRow(item), null, 100)) }
</div>);
diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm
index 5dbbc897..ec985ee3 100644
--- a/common/modules/downloads.jsm
+++ b/common/modules/downloads.jsm
@@ -296,7 +296,7 @@ var DownloadList = Class("DownloadList",
else {
this.addDownload(download.id);
- this.modules.mow.resize(false);
+ this.modules.commandline.updateOutputHeight(false);
this.nodes.list.scrollIntoView(false);
}
this.update();
diff --git a/common/modules/util.jsm b/common/modules/util.jsm
index 01fce1ae..ef596fd8 100644
--- a/common/modules/util.jsm
+++ b/common/modules/util.jsm
@@ -1344,13 +1344,16 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
});
},
- maxErrors: 15,
+ errorCount: 0,
errors: Class.memoize(function () []),
+ maxErrors: 15,
reportError: function (error) {
if (Cu.reportError)
Cu.reportError(error);
try {
+ this.errorCount++;
+
let obj = update({}, error, {
toString: function () String(error),
stack: <>{util.stackLines(String(error.stack || Error().stack)).join("\n").replace(/^/mg, "\t")}</>
diff --git a/common/tests/functional/dactyl.js b/common/tests/functional/dactyl.js
index 8adf268c..ae5a6853 100644
--- a/common/tests/functional/dactyl.js
+++ b/common/tests/functional/dactyl.js
@@ -1,5 +1,31 @@
-var elementslib = {}; Components.utils.import("resource://mozmill/modules/elementslib.js", elementslib);
-var jumlib = {}; Components.utils.import("resource://mozmill/modules/jum.js", jumlib);
+
+var utils = require("utils");
+const { module, NS } = utils;
+
+var elementslib = module("resource://mozmill/modules/elementslib.js");
+var frame = module("resource://mozmill/modules/frame.js");
+var jumlib = module("resource://mozmill/modules/jum.js");
+
+function wrapAssertNoErrors(func, message) {
+ return function wrapped(arg) this.assertNoErrors(func, this, arguments, message || arg);
+}
+
+function assertMessage(funcName, want, got, message) {
+ if (typeof want === "string")
+ return utils.assertEqual(funcName, want, got, message);
+ else if (typeof want === "function")
+ return utils.test(want(got), {
+ function: funcName,
+ want: want, got: got,
+ comment: message
+ });
+ else
+ return utils.test(want.test(got), {
+ function: funcName,
+ want: want, got: got,
+ comment: message
+ });
+}
/**
* A controller for simulating Dactyl related user actions and for making
@@ -8,84 +34,354 @@ var jumlib = {}; Components.utils.import("resource://mozmill/modules/jum.js
* @param {MozMillController} controller The browser's MozMill controller.
*/
function Controller(controller) {
+ var self = this;
this.controller = controller;
- this._dactyl = controller.window.dactyl.modules;
+
+ /**
+ * @property {object} The dactyl modules namespace, to be used
+ * sparingly in tests.
+ */
+ this.dactyl = controller.window.dactyl.modules;
+
+ this.errorCount = 0;
+
+ this._counBeep = function countBeep() {
+ self.beepCount++;
+ }
+ this._countError = function countError(message, highlight) {
+ if (/\bErrorMsg\b/.test(highlight))
+ self.errorCount++;
+ }
+ this.dactyl.dactyl.registerObserver("beep", this._countBeep);
+ this.dactyl.dactyl.registerObserver("echoLine", this._countError);
+ this.dactyl.dactyl.registerObserver("echoMultiline", this._countError);
+
+ this.resetErrorCount();
}
Controller.prototype = {
+ teardown: function () {
+ this.dactyl.dactyl.unregisterObserver("beep", this._countBeep);
+ this.dactyl.dactyl.unregisterObserver("echoLine", this._countError);
+ this.dactyl.dactyl.unregisterObserver("echoMultiline", this._countError);
+ },
+
+ beepCount: 0,
+ errorCount: 0,
+
+ /**
+ * Asserts that an error message is displayed during the execution
+ * of *func*.
+ *
+ * @param {function} func A function to call during before the
+ * assertion takes place.
+ * @param {object} self The 'this' object to be used during the call
+ * of *func*. @optional
+ * @param {Array} args Arguments to be passed to *func*. @optional
+ * @param {string} message The message to display upon assertion failure. @optional
+ */
+ assertMessageError: function (func, self, args, message) {
+ let errorCount = this.errorCount;
+ this.assertNoErrors(func, self, args, message);
+ // dump("assertMessageError " + errorCount + " " + this.errorCount + "\n");
+ return utils.assert('dactyl.assertMessageError', this.errorCount > errorCount,
+ "Expected error but got none" + (message ? ": " + message : ""));
+ },
+
+ /**
+ * Asserts that any output message text content matches *text*.
+ *
+ * @param {string|RegExp|function} want The expected text of the expected message line.
+ * @param {string} message The message to display upon assertion failure.
+ */
+ assertMessage: function (want, message) {
+ return assertMessage('dactyl.assertMessage', want,
+ this.readMessageWindow() || this.readMessageLine(),
+ message);
+ },
+
/**
* Asserts that the output message line text content matches *text*.
*
- * @param {string|RegExp} text The expected text of the expected message line.
+ * @param {string|RegExp|function} want The expected text of the expected message line.
* @param {string} message The message to display upon assertion failure.
*/
- assertMessageLine: function (text, message) {
- let value = this.readMessageLine();
- jumlib.assertTrue(typeof text == "string" ? text == value : text.test(value), message);
+ assertMessageLine: function (want, message) {
+ return assertMessage('dactyl.assertMessageLine', want,
+ this.readMessageLine(),
+ message);
},
/**
* Asserts that the output message window text content matches *text*.
*
- * @param {string|RegExp} text The expected text of the message window.
+ * @param {string|RegExp|function} want The expected text of the message window.
* @param {string} message The message to display upon assertion failure.
*/
- assertMessageWindow: function (text, message) {
- let value = this.readMessageWindow();
- jumlib.assertTrue(typeof text == "string" ? text == value : text.test(value), message);
+ assertMessageWindow: function (want, message) {
+ return assertMessage('dactyl.assertMessageWindow', want,
+ this.readMessageWindow(),
+ message);
},
/**
- * Asserts that an error message has been echoed to the message line or
- * appended to the message window with the given *text*.
+ * Asserts that the output message line text is an error and content matches *text*.
*
- * @param {string|RegExp} text The expected text of the error message.
+ * @param {string|RegExp|function} want The expected text of the expected message line.
* @param {string} message The message to display upon assertion failure.
*/
- // TODO: test against the tail of the MOW too.
- assertErrorMessage: function (text, message) {
- this.controller.sleep(0); // XXX
- let messageBox = new elementslib.ID(this.controller.window.document, "dactyl-message").getNode();
- jumlib.assertTrue(messageBox.value == text && /\bErrorMsg\b/.test(messageBox.getAttribute("highlight")), message);
+ assertErrorMessage: function (want, message) {
+ return assertMessage('dactyl.assertMessageError', want,
+ this.readMessageLine(),
+ message) &&
+ assertMessage('dactyl.assertMessageError', /\bErrorMsg\b/,
+ this.elements.message.getAttributeNS(NS, "highlight"),
+ message);
+ },
+
+ /**
+ * Asserts that the multi-line output window is in the given state.
+ *
+ * @param {boolean} open True if the window is expected to be open.
+ * @param {string} message The message to display upon assertion failure. @optional
+ */
+ assertMessageWindowOpen: function (open, message) {
+ return utils.assertEqual('dactyl.assertMessageWindowOpen', open,
+ !this.elements.multilineContainer.collapsed,
+ message || "Multi-line output not in the expected state");
+ },
+
+ /**
+ * Asserts that the no errors have been reported since the last call
+ * to resetErrorCount.
+ *
+ * @param {function} func A function to call during before the
+ * assertion takes place. When present, the current error count
+ * is reset before execution.
+ * @optional
+ * @param {object} self The 'this' object to be used during the call
+ * of *func*. @optional
+ * @param {Array} args Arguments to be passed to *func*. @optional
+ * @param {string} message The message to display upon assertion failure. @optional
+ * @param {string} message The message to display upon assertion failure. @optional
+ */
+ assertNoErrors: function (func, self, args, message) {
+ let msg = message ? ": " + message : "";
+ let beepCount = this.beepCount;
+ let errorCount = this.errorCount;
+
+ if (func) {
+ errorCount = this.dactyl.util.errorCount;
+
+ try {
+ func.apply(self || this, args || []);
+ }
+ catch (e) {
+ this.dactyl.util.reportError(e);
+ }
+ }
+
+ if (this.beepCount > beepCount)
+ this.frame.log({
+ function: "dactyl.beepMonitor",
+ want: beepCount, got: this.beepCount,
+ comment: "Got " + (this.beepCount - beepCount) + " beeps during execution" + msg
+ });
+
+ if (errorCount != this.dactyl.util.errorCount)
+ var errors = this.dactyl.util.errors.slice(errorCount - this.dactyl.util.errorCount)
+ .join("\n");
+
+ return utils.assertEqual('dactyl.assertNoErrors',
+ errorCount, this.dactyl.util.errorCount,
+ "Errors were reported during the execution of this test" + msg + "\n" + errors);
+ },
+
+ /**
+ * Resets the error count used to determine whether new errors were
+ * reported during the execution of a test.
+ */
+ resetErrorCount: function () {
+ this.errorCount = this.dactyl.util.errorCount;
+ },
+
+ /**
+ * Wraps the given function such that any errors triggered during
+ * its execution will trigger a failed assertion.
+ *
+ * @param {function} func The function to wrap.
+ * @param {string} message The message to display upon assertion failure. @optional
+ */
+ wrapAssertNoErrors: function (func, message) {
+ let self = this;
+ return function wrapped() self.assertNoErrors(func, this, arguments, message);
},
/**
* Asserts that the current window selection matches *text*.
*
- * @param {string|RegExp} text The expected text of the current selection.
+ * @param {string|RegExp|function} text The expected text of the current selection.
* @param {string} message The message to display upon assertion failure.
*/
- assertSelection: function (text, message) {
- let selection = String(this.controller.window.content.getSelection());
- jumlib.assertTrue(typeof text == "string" ? text == selection : text.test(selection), message);
+ assertSelection: function (want, message) {
+ return assertMessage('dactyl.assertSelection', want,
+ String(this.controller.window.content.getSelection()),
+ message);
},
/**
+ * @property {string} The name of dactyl's current key handling
+ * mode.
+ */
+ get currentMode() this.dactyl.modes.main.name,
+
+ /**
+ * @property {object} A map of dactyl widgets to be used sparingly
+ * for focus assertions.
+ */
+ get elements() let (self = this) ({
+ /**
+ * @property {HTMLInputElement} The command line's command input box
+ */
+ get commandInput() self.dactyl.commandline.widgets.active.command.inputField,
+ /**
+ * @property {Node|null} The currently focused node.
+ */
+ get focused() self.controller.window.document.commandDispatcher.focusedElement,
+ /**
+ * @property {HTMLInputElement} The message bar's command input box
+ */
+ get message() self.dactyl.commandline.widgets.active.message,
+ /**
+ * @property {Node} The multi-line output window.
+ */
+ get multiline() self.dactyl.commandline.widgets.multilineOutput,
+ /**
+ * @property {Node} The multi-line output container.
+ */
+ get multilineContainer() self.dactyl.commandline.widgets.mowContainer,
+ }),
+
+ /**
+ * Returns dactyl to normal mode.
+ */
+ setNormalMode: wrapAssertNoErrors(function () {
+ // XXX: Normal mode test
+ for (let i = 0; i < 15 && this.dactyl.modes.stack.length > 1; i++)
+ this.controller.keypress(null, "VK_ESCAPE", {});
+
+ this.controller.keypress(null, "l", { ctrlKey: true });
+
+ utils.assert("dactyl.setNormalMode", this.dactyl.modes.stack.length == 1,
+ "Failed to return to Normal mode");
+
+ this.assertMessageWindowOpen(false, "Returning to normal mode: Multi-line output not closed");
+ this.assertMessageLine(function (msg) !msg, "Returning to normal mode: Message not cleared");
+ }, "Returning to normal mode"),
+
+ /**
+ * Returns dactyl to Ex mode.
+ */
+ setExMode: wrapAssertNoErrors(function () {
+ if (this.currentMode !== "EX") {
+ this.setNormalMode();
+ this.controller.keypress(null, ":", {});
+ }
+ else {
+ this.elements.commandInput.value = "";
+ }
+ }),
+
+ /**
* Runs a Vi command.
*
* @param {string|Array} keys Either a string of simple keys suitable for
* {@link MozMillController#type} or an array of keysym - modifier
* pairs suitable for {@link MozMillController#keypress}.
*/
- runViCommand: function (keys) {
+ runViCommand: wrapAssertNoErrors(function (keys) {
if (typeof keys == "string")
keys = [[k] for each (k in keys)];
- let self = this;
- keys.forEach(function ([key, modifiers]) { self.controller.keypress(null, key, modifiers || {}); });
- },
+ keys.forEach(function ([key, modifiers]) { this.controller.keypress(null, key, modifiers || {}); }, this);
+ }),
/**
* Runs an Ex command.
*
* @param {string} cmd The Ex command string as entered on the command
* line.
+ * @param {object} args An args object by means of which to execute
+ * the command. If absent *cmd* is parsed as a complete
+ * arguments string. @optional
*/
- runExCommand: function (cmd) {
- this.controller.keypress(null, ":", {});
- this.controller.type(null, cmd);
- this.controller.keypress(null, "VK_RETURN", {});
- },
+ // TODO: Use execution code from commandline.js to catch more
+ // possible errors without being insanely inefficient after the
+ // merge.
+ runExCommand: wrapAssertNoErrors(function (cmd, args) {
+ this.setNormalMode();
+ try {
+ // Force async commands to wait for their output to be ready
+ // before returning.
+ this.dactyl.commandline.savingOutput = true;
+ if (args)
+ this.dactyl.ex[cmd](args);
+ else if (true)
+ this.dactyl.commands.execute(cmd, null, false, null,
+ { file: "[Command Line]", line: 1 });
+ else {
+ var doc = this.controller.window.document;
+ var event = doc.createEvent("Events");
+ event.initEvent("dactyl.execute", false, false);
+ doc.documentElement.setAttribute("dactyl-execute", cmd);
+ doc.documentElement.dispatchEvent(event);
+ }
+ }
+ finally {
+ this.dactyl.commandline.savingOutput = false;
+ }
+ }),
+
+ /**
+ * Triggers Ex completion for the given command string and ensures
+ * that no errors have occurred during the process.
+ *
+ * @param {string} cmd The Ex command string as entered on the command
+ * line.
+ */
+ runExCompletion: wrapAssertNoErrors(function (cmd) {
+ this.setExMode();
+
+ utils.assertEqual("dactyl.runExCompletion",
+ this.elements.commandInput,
+ this.elements.focused,
+ "Running Ex Completion: The command line is not focused");
+
+ // dump("runExCompletion " + cmd + "\n");
+ if (true) {
+ let input = this.elements.commandInput;
+ input.value = cmd;
+
+ var event = input.ownerDocument.createEvent("Events");
+ event.initEvent("change", true, false);
+ input.dispatchEvent(event);
+ }
+ else {
+ this.controller.type(null, cmd);
+
+ utils.assertEqual("dactyl.runExCompletion", cmd,
+ this.elements.commandInput.editor.rootElement.firstChild.textContent,
+ "Command line does not have the expected value: " + cmd);
+ }
+
+ this.controller.keypress(null, "VK_TAB", {});
+
+ // XXX
+ if (this.dactyl.commandline._tabTimer)
+ this.dactyl.commandline._tabTimer.flush();
+ else if (this.dactyl.commandline.commandSession && this.dactyl.commandline.commandSession.completions)
+ this.dactyl.commandline.commandSession.completions.tabTimer.flush();
+ }),
/**
* Returns the text content of the output message line.
@@ -93,8 +389,7 @@ Controller.prototype = {
* @returns {string} The message line text content.
*/
readMessageLine: function () {
- this.controller.sleep(0); // XXX
- return new elementslib.ID(this.controller.window.document, "dactyl-message").getNode().value;
+ return this.elements.message.value;
},
/**
@@ -103,36 +398,38 @@ Controller.prototype = {
* @returns {string} The message window text content.
*/
readMessageWindow: function () {
- let messageWindow = new elementslib.ID(this.controller.window.document, "dactyl-multiline-output").getNode();
- try {
- this.controller.waitForEval("subject.collapsed == false", 1000, 100, messageWindow.parentNode);
- return messageWindow.contentDocument.body.textContent;
- }
- catch (e) {
- return "";
- }
+ if (!this.elements.multilineContainer.collapsed)
+ return this.elements.multiline.contentDocument.body.textContent;
+ return "";
},
/**
* Opens the output message window by echoing a single newline character.
*/
- openMessageWindow: function() {
- //this.runExCommand("echo '\\n'");
- this.runExCommand("echo " + "\n".quote());
+ openMessageWindow: wrapAssertNoErrors(function() {
+ this.dactyl.dactyl.echo("\n");
+ }, "Opening message window"),
+
+ /**
+ * Clears the current message.
+ */
+ clearMessage: function() {
+ this.elements.message.value = ""; // XXX
},
/**
* Closes the output message window if open.
*/
- closeMessageWindow: function() {
- if (!this._dactyl.commandline.widgets.mowContainer.collapsed) // XXX
- this.runViCommand([["VK_RETURN"]]);
- },
+ closeMessageWindow: wrapAssertNoErrors(function() {
+ for (let i = 0; i < 15 && !this.elements.multilineContainer.collapsed; i++)
+ this.controller.keypress(null, "VK_ESCAPE", {});
+ this.assertMessageWindowOpen(false, "Clearing message window failed");
+ }, "Clearing message window"),
/**
* @property {string} The specific Dactyl application. Eg. Pentadactyl
*/
- get applicationName() this._dactyl.config.appName // XXX
+ get applicationName() this.dactyl.config.appName // XXX
};
exports.Controller = Controller;
diff --git a/common/tests/functional/testEchoCommands.js b/common/tests/functional/testEchoCommands.js
index cd1d65d2..d46694aa 100644
--- a/common/tests/functional/testEchoCommands.js
+++ b/common/tests/functional/testEchoCommands.js
@@ -5,6 +5,10 @@ var setupModule = function (module) {
dactyl = new dactyllib.Controller(controller);
};
+var teardownModule = function (module) {
+ dactyl.teardown();
+}
+
var teardownTest = function (test) {
dactyl.closeMessageWindow();
};
@@ -56,13 +60,18 @@ var testEchoCommand_ObjectArgumentAndClosedMOW_MessageDisplayedInMOW = function
});
};
+function executeCommand(command) {
+ dactyl.runViCommand(":" + command);
+ dactyl.runViCommand([["VK_RETURN"]]);
+}
+
function assertEchoGeneratesWindowOutput({ ECHO_COMMAND, EXPECTED_OUTPUT }) {
- dactyl.runExCommand(ECHO_COMMAND);
+ executeCommand(ECHO_COMMAND);
dactyl.assertMessageWindow(EXPECTED_OUTPUT);
}
function assertEchoGeneratesLineOutput({ ECHO_COMMAND, EXPECTED_OUTPUT }) {
- dactyl.runExCommand(ECHO_COMMAND);
+ executeCommand(ECHO_COMMAND);
dactyl.assertMessageLine(EXPECTED_OUTPUT);
}
diff --git a/common/tests/functional/testFindCommands.js b/common/tests/functional/testFindCommands.js
index 02aaeb3c..f567cdfa 100644
--- a/common/tests/functional/testFindCommands.js
+++ b/common/tests/functional/testFindCommands.js
@@ -7,9 +7,14 @@ var setupModule = function (module) {
dactyl = new dactyllib.Controller(controller);
};
+var teardownModule = function (module) {
+ dactyl.teardown();
+}
+
var setupTest = function (test) {
controller.open(FIND_TEST_PAGE);
controller.waitForPageLoad(controller.tabs.activeTab);
+ controller.sleep(1000);
};
var testFindCommand_PresentAlphabeticText_TextSelected = function () {
@@ -32,6 +37,8 @@ var testFindCommand_MissingText_ErrorMessageDisplayed = function () {
function runTextSearchCommand(str) {
dactyl.runViCommand("/" + str);
dactyl.runViCommand([["VK_RETURN"]]);
+
+ controller.sleep(0);
}
function assertTextFoundInPage(text) {
diff --git a/common/tests/functional/testHelpCommands.js b/common/tests/functional/testHelpCommands.js
index a56ced0c..270e40c9 100644
--- a/common/tests/functional/testHelpCommands.js
+++ b/common/tests/functional/testHelpCommands.js
@@ -6,6 +6,10 @@ var setupModule = function (module) {
dactyl = new dactyllib.Controller(controller);
};
+var teardownModule = function (module) {
+ dactyl.teardown();
+}
+
var setupTest = function (test) {
dactyl.runViCommand([["VK_ESCAPE"]]);
};
diff --git a/common/tests/functional/testShellCommands.js b/common/tests/functional/testShellCommands.js
index 0a4ae7c1..db8a48e3 100644
--- a/common/tests/functional/testShellCommands.js
+++ b/common/tests/functional/testShellCommands.js
@@ -5,6 +5,10 @@ var setupModule = function (module) {
dactyl = new dactyllib.Controller(controller);
};
+var teardownModule = function (module) {
+ dactyl.teardown();
+}
+
var teardownTest = function (test) {
dactyl.closeMessageWindow();
};
diff --git a/common/tests/functional/testVersionCommand.js b/common/tests/functional/testVersionCommand.js
index 6627dd12..12bf4b8e 100644
--- a/common/tests/functional/testVersionCommand.js
+++ b/common/tests/functional/testVersionCommand.js
@@ -5,6 +5,10 @@ var setupModule = function (module) {
dactyl = new dactyllib.Controller(controller);
};
+var teardownModule = function (module) {
+ dactyl.teardown();
+}
+
var setupTest = function (test) {
dactyl.closeMessageWindow();
};