summaryrefslogtreecommitdiffstats
path: root/dom/console/tests
diff options
context:
space:
mode:
Diffstat (limited to 'dom/console/tests')
-rw-r--r--dom/console/tests/chrome.ini9
-rw-r--r--dom/console/tests/console.sys.mjs45
-rw-r--r--dom/console/tests/file_empty.html1
-rw-r--r--dom/console/tests/head.js24
-rw-r--r--dom/console/tests/mochitest.ini14
-rw-r--r--dom/console/tests/test_bug659625.html107
-rw-r--r--dom/console/tests/test_bug978522.html32
-rw-r--r--dom/console/tests/test_bug979109.html32
-rw-r--r--dom/console/tests/test_bug989665.html21
-rw-r--r--dom/console/tests/test_console.xhtml35
-rw-r--r--dom/console/tests/test_consoleEmptyStack.html26
-rw-r--r--dom/console/tests/test_console_binding.html40
-rw-r--r--dom/console/tests/test_console_proto.html17
-rw-r--r--dom/console/tests/test_count.html117
-rw-r--r--dom/console/tests/test_jsm.xhtml100
-rw-r--r--dom/console/tests/test_timer.html112
-rw-r--r--dom/console/tests/xpcshell/head.js22
-rw-r--r--dom/console/tests/xpcshell/test_basic.js29
-rw-r--r--dom/console/tests/xpcshell/test_failing_console_listener.js35
-rw-r--r--dom/console/tests/xpcshell/test_formatting.js77
-rw-r--r--dom/console/tests/xpcshell/test_reportForServiceWorkerScope.js42
-rw-r--r--dom/console/tests/xpcshell/xpcshell.ini8
22 files changed, 945 insertions, 0 deletions
diff --git a/dom/console/tests/chrome.ini b/dom/console/tests/chrome.ini
new file mode 100644
index 0000000000..b1f4e082c2
--- /dev/null
+++ b/dom/console/tests/chrome.ini
@@ -0,0 +1,9 @@
+[DEFAULT]
+skip-if = os == 'android'
+support-files =
+ file_empty.html
+ console.sys.mjs
+ head.js
+
+[test_console.xhtml]
+[test_jsm.xhtml]
diff --git a/dom/console/tests/console.sys.mjs b/dom/console/tests/console.sys.mjs
new file mode 100644
index 0000000000..d239d58a5d
--- /dev/null
+++ b/dom/console/tests/console.sys.mjs
@@ -0,0 +1,45 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+export var ConsoleTest = {
+ go(dumpFunction) {
+ console.log("Hello world!");
+ console.createInstance().log("Hello world!");
+
+ let c = console.createInstance({
+ consoleID: "wow",
+ innerID: "CUSTOM INNER",
+ dump: dumpFunction,
+ prefix: "_PREFIX_",
+ });
+
+ c.log("Hello world!");
+ c.trace("Hello world!");
+
+ console
+ .createInstance({ innerID: "LEVEL", maxLogLevel: "Off" })
+ .log("Invisible!");
+ console
+ .createInstance({ innerID: "LEVEL", maxLogLevel: "All" })
+ .log("Hello world!");
+ console
+ .createInstance({
+ innerID: "LEVEL",
+ maxLogLevelPref: "pref.test.console",
+ })
+ .log("Hello world!");
+
+ this.c2 = console.createInstance({
+ innerID: "NO PREF",
+ maxLogLevel: "Warn",
+ maxLogLevelPref: "pref.test.console.notset",
+ });
+ this.c2.log("Invisible!");
+ this.c2.warn("Hello world!");
+ },
+
+ go2() {
+ this.c2.log("Hello world!");
+ },
+};
diff --git a/dom/console/tests/file_empty.html b/dom/console/tests/file_empty.html
new file mode 100644
index 0000000000..495c23ec8a
--- /dev/null
+++ b/dom/console/tests/file_empty.html
@@ -0,0 +1 @@
+<!DOCTYPE html><html><body></body></html>
diff --git a/dom/console/tests/head.js b/dom/console/tests/head.js
new file mode 100644
index 0000000000..3e9c72cfb9
--- /dev/null
+++ b/dom/console/tests/head.js
@@ -0,0 +1,24 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const ConsoleAPIStorage = SpecialPowers.Cc[
+ "@mozilla.org/consoleAPI-storage;1"
+].getService(SpecialPowers.Ci.nsIConsoleAPIStorage);
+
+// This is intended to just be a drop-in replacement for an old observer
+// notification.
+function addConsoleStorageListener(listener) {
+ listener.__handler = (message, id) => {
+ listener.observe(message, id);
+ };
+ ConsoleAPIStorage.addLogEventListener(
+ listener.__handler,
+ SpecialPowers.wrap(document).nodePrincipal
+ );
+}
+
+function removeConsoleStorageListener(listener) {
+ ConsoleAPIStorage.removeLogEventListener(listener.__handler);
+}
diff --git a/dom/console/tests/mochitest.ini b/dom/console/tests/mochitest.ini
new file mode 100644
index 0000000000..d66a7245b3
--- /dev/null
+++ b/dom/console/tests/mochitest.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+support-files =
+ file_empty.html
+ head.js
+
+[test_bug659625.html]
+[test_bug978522.html]
+[test_bug979109.html]
+[test_bug989665.html]
+[test_consoleEmptyStack.html]
+[test_console_binding.html]
+[test_console_proto.html]
+[test_timer.html]
+[test_count.html]
diff --git a/dom/console/tests/test_bug659625.html b/dom/console/tests/test_bug659625.html
new file mode 100644
index 0000000000..1cf93d9bfd
--- /dev/null
+++ b/dom/console/tests/test_bug659625.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=659625
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 659625</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=659625">Mozilla Bug 659625</a>
+<script type="application/javascript">
+ const { Cc, Ci } = SpecialPowers;
+ let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
+ let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
+
+ let clearAndCheckStorage = () => {
+ console.clear();
+ is(storage.getEvents().length, 1,
+ "Only one event remains in consoleAPIStorage");
+ is(storage.getEvents()[0].level, "clear",
+ "Remaining event has level 'clear'");
+ };
+
+ storage.clearEvents();
+ is(storage.getEvents().length, 0,
+ "Console is empty when test is starting");
+ clearAndCheckStorage();
+
+ console.log("log");
+ console.debug("debug");
+ console.warn("warn");
+ console.error("error");
+ console.exception("exception");
+ is(storage.getEvents().length, 6,
+ "5 new console events have been registered for logging variants");
+ clearAndCheckStorage();
+
+ console.trace();
+ is(storage.getEvents().length, 2,
+ "1 new console event registered for trace");
+ clearAndCheckStorage();
+
+ console.dir({});
+ is(storage.getEvents().length, 2,
+ "1 new console event registered for dir");
+ clearAndCheckStorage();
+
+ console.count("count-label");
+ console.count("count-label");
+ is(storage.getEvents().length, 3,
+ "2 new console events registered for 2 count calls");
+ clearAndCheckStorage();
+
+ // For bug 1346326.
+ console.count("default");
+ console.count();
+ console.count(undefined);
+ let events = storage.getEvents();
+ // Drop the event from the previous "clear".
+ events.splice(0, 1);
+ is(events.length, 3,
+ "3 new console events registered for 3 'default' count calls");
+ for (let i = 0; i < events.length; ++i) {
+ is(events[i].counter.count, i + 1, "check counter for event " + i);
+ is(events[i].counter.label, "default", "check label for event " + i);
+ }
+ clearAndCheckStorage();
+
+ console.group("group-label");
+ console.log("group-log");
+ is(storage.getEvents().length, 3,
+ "2 new console events registered for group + log");
+ clearAndCheckStorage();
+
+ console.groupCollapsed("group-collapsed");
+ console.log("group-collapsed-log");
+ is(storage.getEvents().length, 3,
+ "2 new console events registered for groupCollapsed + log");
+ clearAndCheckStorage();
+
+ console.group("closed-group-label");
+ console.log("group-log");
+ console.groupEnd();
+ is(storage.getEvents().length, 4,
+ "3 new console events registered for group/groupEnd");
+ clearAndCheckStorage();
+
+ console.time("time-label");
+ console.timeEnd();
+ is(storage.getEvents().length, 3,
+ "2 new console events registered for time/timeEnd");
+ clearAndCheckStorage();
+
+ console.timeStamp("timestamp-label");
+ is(storage.getEvents().length, 2,
+ "1 new console event registered for timeStamp");
+ clearAndCheckStorage();
+
+ // Check that console.clear() clears previous clear messages
+ clearAndCheckStorage();
+
+</script>
+</body>
+</html>
diff --git a/dom/console/tests/test_bug978522.html b/dom/console/tests/test_bug978522.html
new file mode 100644
index 0000000000..b0cc4e76b9
--- /dev/null
+++ b/dom/console/tests/test_bug978522.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=978522
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 978522 - basic support</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978522">Mozilla Bug 978522</a>
+<script type="application/javascript">
+
+ console.log("%s", {
+ toString() {
+ console.log("%s", {
+ toString() {
+ ok(true, "Still alive \\o/");
+ SimpleTest.finish();
+ return "hello world";
+ },
+ });
+ },
+ });
+
+ SimpleTest.waitForExplicitFinish();
+
+</script>
+</body>
+</html>
diff --git a/dom/console/tests/test_bug979109.html b/dom/console/tests/test_bug979109.html
new file mode 100644
index 0000000000..231808e260
--- /dev/null
+++ b/dom/console/tests/test_bug979109.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=979109
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 979109</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=979109">Mozilla Bug 979109</a>
+<script type="application/javascript">
+
+ console.warn("%", "a");
+ console.warn("%%", "a");
+ console.warn("%123", "a");
+ console.warn("%123.", "a");
+ console.warn("%123.123", "a");
+ console.warn("%123.123o", "a");
+ console.warn("%123.123s", "a");
+ console.warn("%123.123d", "a");
+ console.warn("%123.123f", "a");
+ console.warn("%123.123z", "a");
+ console.warn("%.", "a");
+ console.warn("%.123", "a");
+ ok(true, "Still alive \\o/");
+
+</script>
+</body>
+</html>
diff --git a/dom/console/tests/test_bug989665.html b/dom/console/tests/test_bug989665.html
new file mode 100644
index 0000000000..484656a06b
--- /dev/null
+++ b/dom/console/tests/test_bug989665.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=989665
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 989665</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=989665">Mozilla Bug 989665</a>
+<script type="application/javascript">
+
+let w = new Worker("data:text/javascript;charset=UTF-8, console.log('%s', {toString: function() { throw 3 }}); ");
+ok(true, "This test should not crash.");
+
+</script>
+</body>
+</html>
diff --git a/dom/console/tests/test_console.xhtml b/dom/console/tests/test_console.xhtml
new file mode 100644
index 0000000000..cbeb9469e7
--- /dev/null
+++ b/dom/console/tests/test_console.xhtml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<window title="Test for URL API"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <iframe id="iframe" />
+ </body>
+
+ <!-- test code goes here -->
+ <script type="application/javascript"><![CDATA[
+
+ ok("console" in window, "Console exists");
+ window.console.log(42);
+ ok("table" in console, "Console has the 'table' method.");
+ window.console = 42;
+ is(window.console, 42, "Console is replacable");
+
+ var frame = document.getElementById("iframe");
+ ok(frame, "Frame must exist");
+ frame.src="http://mochi.test:8888/tests/dom/console/test/file_empty.html";
+ frame.onload = function() {
+ ok("console" in frame.contentWindow, "Console exists in the iframe");
+ frame.contentWindow.console.log(42);
+ frame.contentWindow.console = 42;
+ is(frame.contentWindow.console, 42, "Console is replacable in the iframe");
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ ]]></script>
+</window>
diff --git a/dom/console/tests/test_consoleEmptyStack.html b/dom/console/tests/test_consoleEmptyStack.html
new file mode 100644
index 0000000000..ec77d0ac6f
--- /dev/null
+++ b/dom/console/tests/test_consoleEmptyStack.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test for empty stack in console</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+window.setTimeout(console.log.bind(console), 0, "xyz");
+
+window.addEventListener("fake", console.log.bind(console, "xyz"));
+
+window.addEventListener("fake", function() {
+ ok(true, "Still alive");
+ SimpleTest.finish();
+});
+
+window.dispatchEvent(new Event("fake"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/console/tests/test_console_binding.html b/dom/console/tests/test_console_binding.html
new file mode 100644
index 0000000000..0ec1926400
--- /dev/null
+++ b/dom/console/tests/test_console_binding.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test Console binding</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <script type="application/javascript">
+
+function consoleListener() {
+ addConsoleStorageListener(this);
+}
+
+var order = 0;
+consoleListener.prototype = {
+ observe(obj) {
+ ok(!obj.chromeContext, "Thils is not a chrome context");
+ if (order + 1 == parseInt(obj.arguments[0])) {
+ ok(true, "Message received: " + obj.arguments[0]);
+ order++;
+ }
+
+ if (order == 3) {
+ removeConsoleStorageListener(this);
+ SimpleTest.finish();
+ }
+ },
+};
+
+var cl = new consoleListener();
+SimpleTest.waitForExplicitFinish();
+
+[1, 2, 3].forEach(console.log);
+
+ </script>
+</body>
+</html>
diff --git a/dom/console/tests/test_console_proto.html b/dom/console/tests/test_console_proto.html
new file mode 100644
index 0000000000..3e9461bade
--- /dev/null
+++ b/dom/console/tests/test_console_proto.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for console.__proto__</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <script type="application/javascript">
+
+ isnot(Object.getPrototypeOf(console), Object.prototype, "Foo");
+ is(Object.getPrototypeOf(Object.getPrototypeOf(console)), Object.prototype, "Boo");
+
+ </script>
+</body>
+</html>
diff --git a/dom/console/tests/test_count.html b/dom/console/tests/test_count.html
new file mode 100644
index 0000000000..5591768150
--- /dev/null
+++ b/dom/console/tests/test_count.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for count/countReset in console</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function ConsoleListener() {
+ addConsoleStorageListener(this);
+}
+
+ConsoleListener.prototype = {
+ observe(aSubject) {
+ let obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] != "test") {
+ return;
+ }
+
+ if (!this._cb) {
+ ok(false, "Callback not set!");
+ return;
+ }
+
+ if (!this._cb(obj)) {
+ return;
+ }
+
+ this._cb = null;
+ this._resolve();
+ },
+
+ shutdown() {
+ removeConsoleStorageListener(this);
+ },
+
+ waitFor(cb) {
+ return new Promise(resolve => {
+ this._cb = SpecialPowers.wrapCallback(cb);
+ this._resolve = resolve;
+ });
+ },
+};
+
+let listener = new ConsoleListener();
+
+async function runTest() {
+ // First count.
+ let cl = listener.waitFor(obj => {
+ return ("counter" in obj) &&
+ ("label" in obj.counter) &&
+ obj.counter.label == "test" &&
+ obj.counter.count == 1;
+ });
+ console.count("test");
+ await cl;
+ ok(true, "Console.count == 1 received!");
+
+ // Second count.
+ cl = listener.waitFor(obj => {
+ return ("counter" in obj) &&
+ ("label" in obj.counter) &&
+ obj.counter.label == "test" &&
+ obj.counter.count == 2;
+ });
+ console.count("test");
+ await cl;
+ ok(true, "Console.count == 2 received!");
+
+ // Counter reset.
+ cl = listener.waitFor(obj => {
+ return ("counter" in obj) &&
+ ("label" in obj.counter) &&
+ obj.counter.label == "test" &&
+ obj.counter.count == 0;
+ });
+ console.countReset("test");
+ await cl;
+ ok(true, "Console.countReset == 0 received!");
+
+ // Counter reset with error.
+ cl = listener.waitFor(obj => {
+ return ("counter" in obj) &&
+ ("label" in obj.counter) &&
+ obj.counter.label == "test" &&
+ obj.counter.error == "counterDoesntExist";
+ });
+ console.countReset("test");
+ await cl;
+ ok(true, "Console.countReset with error received!");
+
+ // First again!
+ cl = listener.waitFor(obj => {
+ return ("counter" in obj) &&
+ ("label" in obj.counter) &&
+ obj.counter.label == "test" &&
+ obj.counter.count == 1;
+ });
+ console.count("test");
+ await cl;
+ ok(true, "Console.count == 1 received!");
+}
+
+runTest().then(() => {
+ listener.shutdown();
+ SimpleTest.finish();
+});
+
+ </script>
+</body>
+</html>
diff --git a/dom/console/tests/test_jsm.xhtml b/dom/console/tests/test_jsm.xhtml
new file mode 100644
index 0000000000..9296d40b22
--- /dev/null
+++ b/dom/console/tests/test_jsm.xhtml
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<window title="Console + MJS"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="test();">
+
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+ <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+ <script src="head.js"/>
+
+ <script type="application/javascript">
+ <![CDATA[
+
+const MJS = "chrome://mochitests/content/chrome/dom/console/tests/console.sys.mjs";
+
+let dumpCalled = 0;
+function dumpFunction(msg) {
+ ok(msg.includes("_PREFIX_"), "we have a prefix");
+ dump("Message received: " + msg); // Just for debugging
+ dumpCalled++;
+}
+
+function promiseConsoleListenerCalled() {
+ return new Promise(resolve => {
+ let consoleListener = {
+ count: 0,
+
+ observe: function(aSubject) {
+ var obj = aSubject.wrappedJSObject;
+ ok(obj.chromeContext, "MJS is always a chrome context");
+
+ if (obj.innerID == MJS) {
+ is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+ is(obj.arguments[0], "Hello world!", "Message matches");
+ is(obj.consoleID, "", "No consoleID for console API");
+ is(obj.prefix, "", "prefix is empty by default");
+
+ // We want to see 2 messages from this innerID, the first is generated
+ // by console.log, the second one from createInstance().log();
+ ++this.count;
+ } else if (obj.innerID == "CUSTOM INNER") {
+ is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+ is(obj.arguments[0], "Hello world!", "Message matches");
+ is(obj.consoleID, "wow", "consoleID is set by consoleInstance");
+ is(obj.prefix, "_PREFIX_", "prefix is set by consoleInstance");
+ // We expect to see 2 messages from this innerID.
+ ++this.count;
+ } else if (obj.innerID == "LEVEL") {
+ // Nothing special... just we don't want to see 'invisible' messages.
+ is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+ is(obj.arguments[0], "Hello world!", "Message matches");
+ is(obj.prefix, "", "prefix is empty by default");
+ // We expect to see 2 messages from this innerID.
+ ++this.count;
+ } else if (obj.innerID == "NO PREF") {
+ // Nothing special... just we don't want to see 'invisible' messages.
+ is(obj.ID, "jsm", "ID and InnerID are correctly set.");
+ is(obj.arguments[0], "Hello world!", "Message matches");
+ is(obj.prefix, "", "prefix is empty by default");
+ // We expect to see 2 messages from this innerID.
+ ++this.count;
+ }
+
+ if (this.count == 8) {
+ is(dumpCalled, 2, "Dump has been called!");
+ removeConsoleStorageListener(consoleListener);
+ resolve();
+ }
+ }
+ }
+ addConsoleStorageListener(consoleListener);
+ });
+}
+
+async function test() {
+ SimpleTest.waitForExplicitFinish();
+
+ let consolePromise = promiseConsoleListenerCalled();
+ let { ConsoleTest } = ChromeUtils.importESModule(MJS);
+ await SpecialPowers.pushPrefEnv({set: [["pref.test.console", "log"]]})
+ ConsoleTest.go(dumpFunction);
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["pref.test.console.notset", "Log"]],
+ });
+ ConsoleTest.go2();
+
+ await consolePromise;
+ SimpleTest.finish();
+}
+
+ ]]>
+ </script>
+
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ </body>
+</window>
diff --git a/dom/console/tests/test_timer.html b/dom/console/tests/test_timer.html
new file mode 100644
index 0000000000..fa3ca7baec
--- /dev/null
+++ b/dom/console/tests/test_timer.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for timeStart/timeLog/timeEnd in console</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
+function ConsoleListener() {
+ addConsoleStorageListener(this);
+}
+
+ConsoleListener.prototype = {
+ observe(aSubject) {
+ let obj = aSubject.wrappedJSObject;
+ if (obj.arguments[0] != "test_bug1463614") {
+ return;
+ }
+
+ if (!this._cb || !this._cb(obj)) {
+ return;
+ }
+
+ this._cb = null;
+ this._resolve();
+ },
+
+ shutdown() {
+ removeConsoleStorageListener(this);
+ },
+
+ waitFor(cb) {
+ return new Promise(resolve => {
+ this._cb = SpecialPowers.wrapCallback(cb);
+ this._resolve = resolve;
+ });
+ },
+};
+
+let listener = new ConsoleListener();
+
+// Timer creation:
+async function runTest() {
+ let cl = listener.waitFor(obj => {
+ return ("timer" in obj) &&
+ ("name" in obj.timer) &&
+ obj.timer.name == "test_bug1463614";
+ });
+
+ console.time("test_bug1463614");
+ await cl;
+ ok(true, "Console.time received!");
+
+ // Timer check:
+ cl = listener.waitFor(obj => {
+ return ("timer" in obj) &&
+ ("name" in obj.timer) &&
+ obj.timer.name == "test_bug1463614" &&
+ ("duration" in obj.timer) &&
+ obj.timer.duration >= 0 &&
+ obj.arguments[1] == 1 &&
+ obj.arguments[2] == 2 &&
+ obj.arguments[3] == 3 &&
+ obj.arguments[4] == 4;
+ });
+ console.timeLog("test_bug1463614", 1, 2, 3, 4);
+ await cl;
+ ok(true, "Console.timeLog received!");
+
+ // Time deleted:
+ cl = listener.waitFor(obj => {
+ return ("timer" in obj) &&
+ ("name" in obj.timer) &&
+ obj.timer.name == "test_bug1463614" &&
+ ("duration" in obj.timer) &&
+ obj.timer.duration >= 0;
+ });
+ console.timeEnd("test_bug1463614");
+ await cl;
+ ok(true, "Console.timeEnd received!");
+
+ // Here an error:
+ cl = listener.waitFor(obj => {
+ return ("timer" in obj) &&
+ ("name" in obj.timer) &&
+ obj.timer.name == "test_bug1463614" &&
+ ("error" in obj.timer);
+ });
+ console.timeLog("test_bug1463614");
+ await cl;
+ ok(true, "Console.time with error received!");
+}
+
+runTest().then(() => {
+ listener.shutdown();
+
+ SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
+ SimpleTest.finish();
+});
+
+ </script>
+</body>
+</html>
diff --git a/dom/console/tests/xpcshell/head.js b/dom/console/tests/xpcshell/head.js
new file mode 100644
index 0000000000..446eb9ba9e
--- /dev/null
+++ b/dom/console/tests/xpcshell/head.js
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"].getService(
+ Ci.nsIConsoleAPIStorage
+);
+
+// This is intended to just be a drop-in replacement for an old observer
+// notification.
+function addConsoleStorageListener(listener) {
+ listener.__handler = (message, id) => {
+ listener.observe(message, id);
+ };
+ ConsoleAPIStorage.addLogEventListener(
+ listener.__handler,
+ Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal)
+ );
+}
+
+function removeConsoleStorageListener(listener) {
+ ConsoleAPIStorage.removeLogEventListener(listener.__handler);
+}
diff --git a/dom/console/tests/xpcshell/test_basic.js b/dom/console/tests/xpcshell/test_basic.js
new file mode 100644
index 0000000000..5736912979
--- /dev/null
+++ b/dom/console/tests/xpcshell/test_basic.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function () {
+ Assert.ok("console" in this);
+
+ let p = new Promise(resolve => {
+ function consoleListener() {
+ addConsoleStorageListener(this);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ let obj = aSubject.wrappedJSObject;
+ Assert.ok(obj.arguments[0] === 42, "Message received!");
+ Assert.ok(obj.ID === "jsm", "The ID is JSM");
+ Assert.ok(obj.innerID.endsWith("test_basic.js"), "The innerID matches");
+
+ removeConsoleStorageListener(this);
+ resolve();
+ },
+ };
+
+ new consoleListener();
+ });
+
+ console.log(42);
+ await p;
+});
diff --git a/dom/console/tests/xpcshell/test_failing_console_listener.js b/dom/console/tests/xpcshell/test_failing_console_listener.js
new file mode 100644
index 0000000000..bb1b7cd46c
--- /dev/null
+++ b/dom/console/tests/xpcshell/test_failing_console_listener.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function () {
+ Assert.ok("console" in this);
+
+ // Add a first listener that synchronously throws.
+ const removeListener1 = addConsoleListener(() => {
+ throw new Error("Fail");
+ });
+
+ // Add a second listener updating a flag we can observe from the test.
+ let secondListenerCalled = false;
+ const removeListener2 = addConsoleListener(
+ () => (secondListenerCalled = true)
+ );
+
+ console.log(42);
+ Assert.ok(secondListenerCalled, "Second listener was called");
+
+ // Cleanup listeners.
+ removeListener1();
+ removeListener2();
+});
+
+function addConsoleListener(callback) {
+ const principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
+ Ci.nsIPrincipal
+ );
+ ConsoleAPIStorage.addLogEventListener(callback, principal);
+
+ return () => {
+ ConsoleAPIStorage.removeLogEventListener(callback, principal);
+ };
+}
diff --git a/dom/console/tests/xpcshell/test_formatting.js b/dom/console/tests/xpcshell/test_formatting.js
new file mode 100644
index 0000000000..89d5a1947e
--- /dev/null
+++ b/dom/console/tests/xpcshell/test_formatting.js
@@ -0,0 +1,77 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function () {
+ Assert.ok("console" in this);
+
+ const tests = [
+ // Plain value.
+ [[42], ["42"]],
+
+ // Integers.
+ [["%d", 42], ["42"]],
+ [["%i", 42], ["42"]],
+ [["c%iao", 42], ["c42ao"]],
+
+ // Floats.
+ [["%2.4f", 42], ["42.0000"]],
+ [["%2.2f", 42], ["42.00"]],
+ [["%1.2f", 42], ["42.00"]],
+ [["a%3.2fb", 42], ["a42.00b"]],
+ [["%f", NaN], ["NaN"]],
+
+ // Strings
+ [["%s", 42], ["42"]],
+
+ // Empty values.
+ [
+ ["", 42],
+ ["", "42"],
+ ],
+ [
+ ["", 42],
+ ["", "42"],
+ ],
+ ];
+
+ let p = new Promise(resolve => {
+ let t = 0;
+
+ function consoleListener() {
+ addConsoleStorageListener(this);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ let test = tests[t++];
+
+ let obj = aSubject.wrappedJSObject;
+ Assert.equal(
+ obj.arguments.length,
+ test[1].length,
+ "Same number of arguments"
+ );
+ for (let i = 0; i < test[1].length; ++i) {
+ Assert.equal(
+ "" + obj.arguments[i],
+ test[1][i],
+ "Message received: " + test[1][i]
+ );
+ }
+
+ if (t === tests.length) {
+ removeConsoleStorageListener(this);
+ resolve();
+ }
+ },
+ };
+
+ new consoleListener();
+ });
+
+ tests.forEach(test => {
+ console.log(...test[0]);
+ });
+
+ await p;
+});
diff --git a/dom/console/tests/xpcshell/test_reportForServiceWorkerScope.js b/dom/console/tests/xpcshell/test_reportForServiceWorkerScope.js
new file mode 100644
index 0000000000..f96519183c
--- /dev/null
+++ b/dom/console/tests/xpcshell/test_reportForServiceWorkerScope.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function () {
+ let p = new Promise(resolve => {
+ function consoleListener() {
+ addConsoleStorageListener(this);
+ }
+
+ consoleListener.prototype = {
+ observe(aSubject) {
+ let obj = aSubject.wrappedJSObject;
+ Assert.ok(obj.arguments[0] === "Hello world!", "Message received!");
+ Assert.ok(obj.ID === "scope", "The ID is the scope");
+ Assert.ok(
+ obj.innerID === "ServiceWorker",
+ "The innerID is ServiceWorker"
+ );
+ Assert.ok(obj.filename === "filename", "The filename matches");
+ Assert.ok(obj.lineNumber === 42, "The lineNumber matches");
+ Assert.ok(obj.columnNumber === 24, "The columnNumber matches");
+ Assert.ok(obj.level === "error", "The level is correct");
+
+ removeConsoleStorageListener(this);
+ resolve();
+ },
+ };
+
+ new consoleListener();
+ });
+
+ let ci = console.createInstance();
+ ci.reportForServiceWorkerScope(
+ "scope",
+ "Hello world!",
+ "filename",
+ 42,
+ 24,
+ "error"
+ );
+ await p;
+});
diff --git a/dom/console/tests/xpcshell/xpcshell.ini b/dom/console/tests/xpcshell/xpcshell.ini
new file mode 100644
index 0000000000..51cc86f54c
--- /dev/null
+++ b/dom/console/tests/xpcshell/xpcshell.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+head = head.js
+support-files =
+
+[test_basic.js]
+[test_failing_console_listener.js]
+[test_reportForServiceWorkerScope.js]
+[test_formatting.js]