summaryrefslogtreecommitdiffstats
path: root/remote/shared/listeners/test/browser/browser_ConsoleListener.js
diff options
context:
space:
mode:
Diffstat (limited to 'remote/shared/listeners/test/browser/browser_ConsoleListener.js')
-rw-r--r--remote/shared/listeners/test/browser/browser_ConsoleListener.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/remote/shared/listeners/test/browser/browser_ConsoleListener.js b/remote/shared/listeners/test/browser/browser_ConsoleListener.js
new file mode 100644
index 0000000000..41936a6c0d
--- /dev/null
+++ b/remote/shared/listeners/test/browser/browser_ConsoleListener.js
@@ -0,0 +1,148 @@
+/* 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/. */
+
+add_task(async function test_message_properties() {
+ const listenerId = await listenToConsoleMessage("error");
+ await logConsoleMessage({ message: "foo" });
+ const { level, message, timeStamp, stack } = await getConsoleMessage(
+ listenerId
+ );
+
+ is(level, "error", "Received expected log level");
+ is(message, "foo", "Received expected log message");
+ // Services.console.logMessage() doesn't include a stack.
+ is(stack, undefined, "No stack present");
+ is(typeof timeStamp, "number", "timestamp is of expected type number");
+
+ // Clear the console to avoid side effects with other tests in this file.
+ await clearConsole();
+});
+
+add_task(async function test_level() {
+ for (const level of ["error", "info", "warn"]) {
+ const listenerId = await listenToConsoleMessage(level);
+ await logConsoleMessage({ message: "foo", level });
+ const message = await getConsoleMessage(listenerId);
+
+ is(message.level, level, "Received expected log level");
+ }
+
+ // Clear the console to avoid side effects with other tests in this file.
+ await clearConsole();
+});
+
+add_task(async function test_stacktrace() {
+ const script = `
+ function foo() { throw new Error("cheese"); }
+ function bar() { foo(); }
+ bar();
+ `;
+
+ const listenerId = await listenToConsoleMessage("error");
+ await createScriptNode(script);
+ const { message, level, stacktrace } = await getConsoleMessage(listenerId);
+ is(level, "error", "Received expected log level");
+ is(message, "Error: cheese", "Received expected log message");
+ ok(Array.isArray(stacktrace), "frames is of expected type Array");
+ Assert.greaterOrEqual(stacktrace.length, 4, "Got at least 4 stack frames");
+
+ // First 3 stack frames are from the injected script and one more frame comes
+ // from head.js (chrome scope) where we inject the script.
+ checkStackFrame(stacktrace[0], "about:blank", "foo", 2, 28);
+ checkStackFrame(stacktrace[1], "about:blank", "bar", 3, 22);
+ checkStackFrame(stacktrace[2], "about:blank", "", 4, 5);
+ checkStackFrame(
+ stacktrace[3],
+ "chrome://mochitests/content/browser/remote/shared/listeners/test/browser/head.js",
+ "",
+ 34,
+ 29
+ );
+
+ // Clear the console to avoid side effects with other tests in this file.
+ await clearConsole();
+});
+
+function logConsoleMessage(options = {}) {
+ info(`Log console message ${options.message}`);
+ return SpecialPowers.spawn(gBrowser.selectedBrowser, [options], _options => {
+ const { level = "error" } = _options;
+
+ const levelToFlags = {
+ error: Ci.nsIScriptError.errorFlag,
+ info: Ci.nsIScriptError.infoFlag,
+ warn: Ci.nsIScriptError.warningFlag,
+ };
+
+ const scriptError = Cc["@mozilla.org/scripterror;1"].createInstance(
+ Ci.nsIScriptError
+ );
+ scriptError.initWithWindowID(
+ _options.message,
+ _options.sourceName || "sourceName",
+ null,
+ _options.lineNumber || 0,
+ _options.columnNumber || 0,
+ levelToFlags[level],
+ _options.category || "javascript",
+ content.windowGlobalChild.innerWindowId
+ );
+
+ Services.console.logMessage(scriptError);
+ });
+}
+
+function listenToConsoleMessage(level) {
+ info("Listen to a console message in content");
+ return SpecialPowers.spawn(
+ gBrowser.selectedBrowser,
+ [level],
+ async _level => {
+ const innerWindowId = content.windowGlobalChild.innerWindowId;
+ const { ConsoleListener } = ChromeUtils.importESModule(
+ "chrome://remote/content/shared/listeners/ConsoleListener.sys.mjs"
+ );
+ const consoleListener = new ConsoleListener(innerWindowId);
+ const onMessage = consoleListener.once(_level);
+ consoleListener.startListening();
+
+ const listenerId = Math.random();
+ content[listenerId] = { consoleListener, onMessage };
+ return listenerId;
+ }
+ );
+}
+
+function getConsoleMessage(listenerId) {
+ info("Retrieve the message event captured for listener: " + listenerId);
+ return SpecialPowers.spawn(
+ gBrowser.selectedBrowser,
+ [listenerId],
+ async _listenerId => {
+ const { consoleListener, onMessage } = content[_listenerId];
+ const message = await onMessage;
+
+ consoleListener.destroy();
+
+ return message;
+ }
+ );
+}
+
+function checkStackFrame(
+ frame,
+ filename,
+ functionName,
+ lineNumber,
+ columnNumber
+) {
+ is(frame.filename, filename, "Received expected filename for frame");
+ is(
+ frame.functionName,
+ functionName,
+ "Received expected function name for frame"
+ );
+ is(frame.lineNumber, lineNumber, "Received expected line for frame");
+ is(frame.columnNumber, columnNumber, "Received expected column for frame");
+}