bug 1203394: alias alert() to console.log() in background scripts r?kmag
MozReview-Commit-ID: 65m3yVGQhlQ
***
Add test and fix nitpicks to alert() patch
--- a/toolkit/components/extensions/ext-backgroundPage.js
+++ b/toolkit/components/extensions/ext-backgroundPage.js
@@ -70,16 +70,44 @@ BackgroundPage.prototype = {
if (this.extension.addonData.instanceID) {
AddonManager.getAddonByInstanceID(this.extension.addonData.instanceID)
.then(addon => addon.setDebugGlobal(window));
}
// TODO: Right now we run onStartup after the background page
// finishes. See if this is what Chrome does.
let loadListener = event => {
+ // Override the `alert()` method inside background windows;
+ // we alias it to console.log().
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1203394
+ let alertDisplayedWarning = false;
+ let alertOverwrite = text => {
+ if (!alertDisplayedWarning) {
+ let consoleWindow = Services.wm.getMostRecentWindow("devtools:webconsole");
+ if (!consoleWindow) {
+ let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+ require("devtools/client/framework/devtools-browser");
+ let hudservice = require("devtools/client/webconsole/hudservice");
+ let {console} = Cu.import("resource://gre/modules/Console.jsm", {});
+ hudservice.toggleBrowserConsole().catch(Cu.reportError);
+ } else {
+ // the Browser Console was already open
+ consoleWindow.focus();
+ }
+
+ this.context.contentWindow.console.warn("alert() is not supported in background windows; please use console.log instead.");
+
+ alertDisplayedWarning = true;
+ }
+
+ window.console.log(text);
+ };
+ Components.utils.exportFunction(alertOverwrite, window, {
+ defineAs: "alert"
+ });
if (event.target != window.document) {
return;
}
event.currentTarget.removeEventListener("load", loadListener, true);
if (this.scripts) {
let doc = window.document;
for (let script of this.scripts) {
--- a/toolkit/components/extensions/test/mochitest/chrome.ini
+++ b/toolkit/components/extensions/test/mochitest/chrome.ini
@@ -2,16 +2,17 @@
support-files =
file_download.html
file_download.txt
interruptible.sjs
file_sample.html
[test_chrome_ext_background_debug_global.html]
skip-if = (os == 'android') # android doesn't have devtools
+[test_chrome_ext_background_page.html]
[test_chrome_ext_downloads_download.html]
[test_chrome_ext_downloads_misc.html]
[test_chrome_ext_downloads_search.html]
[test_chrome_ext_eventpage_warning.html]
[test_chrome_ext_contentscript_unrecognizedprop_warning.html]
skip-if = (os == 'android') # browser.tabs is undefined. Bug 1258975 on android.
[test_chrome_ext_webnavigation_resolved_urls.html]
-skip-if = (os == 'android') # browser.tabs is undefined. Bug 1258975 on android.
\ No newline at end of file
+skip-if = (os == 'android') # browser.tabs is undefined. Bug 1258975 on android.
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_background_page.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>WebExtension test</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" href="chrome://mochikit/contents/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+const {
+ classes: Cc,
+ interfaces: Ci,
+ utils: Cu,
+} = Components;
+const Services = SpecialPowers.Services;
+
+add_task(function* testAlertNotShownInBackgroundWindow() {
+ ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(),
+ "Alerts should not be present at the start of the test.");
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: "new " + function() {
+ browser.test.log("background script executed");
+
+ alert("I am an alert in the background.");
+
+ browser.test.notifyPass("alertCalled");
+ },
+ });
+
+ yield extension.startup();
+
+ info("startup complete loaded");
+
+ yield extension.awaitFinish("alertCalled");
+
+ let alertWindows = Services.wm.getEnumerator("alert:alert");
+ ok(!alertWindows.hasMoreElements(), "Should not show alert");
+
+ // Make sure the message we output to the console is seen.
+ // This message is in ext-backgroundPage.js
+ let events = Cc["@mozilla.org/consoleAPI-storage;1"]
+ .getService(Ci.nsIConsoleAPIStorage).getEvents();
+ // This is the warning that is output after the first `alert()` call is made.
+ let alertWarningEvent = events[events.length - 2];
+ is(alertWarningEvent.arguments[0], "alert() is not supported in background windows; please use console.log instead.")
+ // This is the actual alert text that should be present in the console
+ // instead of as an `alert`.
+ let alertEvent = events[events.length - 1];
+ is(alertEvent.arguments[0], "I am an alert in the background.")
+
+ let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+ require("devtools/client/framework/devtools-browser");
+ let hudservice = require("devtools/client/webconsole/hudservice");
+
+ while (!hudservice.getBrowserConsole()) {
+ // Setting this to 0 fails, but 200 seems to do the trick.
+ yield new Promise(resolve => setTimeout(resolve, 200));
+ }
+ let haveConsole = !!hudservice.getBrowserConsole();
+ ok(haveConsole, "Expected browser console to be open");
+
+ if (haveConsole) {
+ yield hudservice.toggleBrowserConsole();
+ }
+
+ yield extension.unload();
+});
+</script>
+
+</body>
+</html>