bug 1203394: alias alert() to console.log() in background scripts r?kmag draft
authortofumatt <tofumatt@mozilla.com>
Tue, 22 Mar 2016 12:35:31 +0000
changeset 356037 3ba2e533eaa3e5173495dfb0512111ddaa3ff003
parent 356036 3dcce1366518e15d531bdf38c71ba07030c0eef0
child 356049 dc5884f9a173103c06df587780d5c7b96718fbcc
push id16417
push userbmo:tofumatt@mozilla.com
push dateMon, 25 Apr 2016 13:49:55 +0000
reviewerskmag
bugs1203394
milestone48.0a1
bug 1203394: alias alert() to console.log() in background scripts r?kmag MozReview-Commit-ID: 65m3yVGQhlQ *** Add test and fix nitpicks to alert() patch
toolkit/components/extensions/ext-backgroundPage.js
toolkit/components/extensions/test/mochitest/chrome.ini
toolkit/components/extensions/test/mochitest/test_chrome_ext_background_page.html
--- 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>