Bug 587734: enable the lazy console API added in bug 568629, and hook it up to the Web Console, r=gavin, a=blocking
authorDavid Dahl <ddahl@mozilla.com>
Tue, 16 Nov 2010 16:34:53 -0500
changeset 57601 aafeff43ea2582d6d6d2a8d55a4a0c2e81d57129
parent 57598 ef83567ee8d8ce284a513c640dab55e0c366c27e
child 57602 898ef162e026304a9fa624dadb2243087ce4a36d
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersgavin, blocking
bugs587734, 568629
milestone2.0b8pre
Bug 587734: enable the lazy console API added in bug 568629, and hook it up to the Web Console, r=gavin, a=blocking
dom/base/ConsoleAPI.manifest
dom/tests/browser/browser_ConsoleAPITests.js
toolkit/components/console/hudservice/HUDService.jsm
toolkit/components/console/hudservice/tests/browser/Makefile.in
toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588342_document_focus.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_589162_css_filter.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601352_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
toolkit/components/console/hudservice/tests/browser/head.js
toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html
toolkit/components/console/hudservice/tests/browser/test-console.html
toolkit/components/console/hudservice/tests/browser/test-own-console.html
--- a/dom/base/ConsoleAPI.manifest
+++ b/dom/base/ConsoleAPI.manifest
@@ -1,4 +1,3 @@
 component {b49c18f8-3379-4fc0-8c90-d7772c1a9ff3} ConsoleAPI.js
 contract @mozilla.org/console-api;1 {b49c18f8-3379-4fc0-8c90-d7772c1a9ff3}
-# disabled for now
-# category JavaScript-global-property console @mozilla.org/console-api;1
+category JavaScript-global-property console @mozilla.org/console-api;1
--- a/dom/tests/browser/browser_ConsoleAPITests.js
+++ b/dom/tests/browser/browser_ConsoleAPITests.js
@@ -35,20 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html";
 
 var gWindow;
 
 function test() {
-  // FIXME
-  todo(false, "This test is disabled until bug 587734 lands");
-  return;
-
   waitForExplicitFinish();
 
   var tab = gBrowser.addTab(TEST_URI);
   gBrowser.selectedTab = tab;
   var browser = gBrowser.selectedBrowser;
 
   registerCleanupFunction(function () {
     gBrowser.removeTab(tab);
--- a/toolkit/components/console/hudservice/HUDService.jsm
+++ b/toolkit/components/console/hudservice/HUDService.jsm
@@ -41,16 +41,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
+const CONSOLEAPI_CLASS_ID = "{b49c18f8-3379-4fc0-8c90-d7772c1a9ff3}";
+
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = ["HUDService", "ConsoleUtils"];
 
 XPCOMUtils.defineLazyServiceGetter(this, "scriptError",
                                    "@mozilla.org/scripterror;1",
                                    "nsIScriptError");
@@ -731,17 +733,17 @@ function NetworkPanel(aParent, aHttpActi
     if (self.linkNode) {
       self.linkNode._panelOpen = false;
       self.linkNode = null;
     }
   }, false);
 
   // Set the document object and update the content once the panel is loaded.
   this.panel.addEventListener("load", function onLoad() {
-    self.panel.removeEventListener("load", onLoad, true)
+    self.panel.removeEventListener("load", onLoad, true);
     self.document = self.iframe.contentWindow.document;
     self.update();
   }, true);
 
   // Create the footer.
   let footer = createElement(doc, "hbox", { align: "end" });
   createAndAppendElement(footer, "spacer", { flex: 1 });
 
@@ -1427,16 +1429,41 @@ HUD_SERVICE.prototype =
   sequencer: null,
 
   /**
    * Each HeadsUpDisplay has a set of filter preferences
    */
   filterPrefs: {},
 
   /**
+   * Gets the ID of the outer window of this DOM window
+   *
+   * @param nsIDOMWindow aWindow
+   * @returns integer
+   */
+  getWindowId: function HS_getWindowId(aWindow)
+  {
+    return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
+  },
+
+  /**
+   * Gets the top level content window that has an outer window with
+   * the given ID or returns null if no such content window exists
+   *
+   * @param integer aId
+   * @returns nsIDOMWindow
+   */
+  getWindowByWindowId: function HS_getWindowByWindowId(aId)
+  {
+    let someWindow = Services.wm.getMostRecentWindow(null);
+    let windowUtils = someWindow.getInterface(Ci.nsIDOMWindowUtils);
+    return windowUtils.getOuterWindowWithId(aId);
+  },
+
+  /**
    * Whether to save the bodies of network requests and responses. Disabled by
    * default to save memory.
    */
   saveRequestAndResponseBodies: false,
 
   /**
    * Tell the HUDService that a HeadsUpDisplay can be activated
    * for the window or context that has 'aContextDOMId' node id
@@ -1806,31 +1833,34 @@ HUD_SERVICE.prototype =
   deleteHeadsUpDisplay: function HS_deleteHeadsUpDisplay(aHUDId)
   {
     delete this.hudWeakReferences[aHUDId].get();
   },
 
   /**
    * Register a new Heads Up Display
    *
-   * @param string aHUDId
    * @param nsIDOMWindow aContentWindow
    * @returns void
    */
   registerDisplay: function HS_registerDisplay(aHUDId, aContentWindow)
   {
     // register a display DOM node Id and HUD uriSpec with the service
 
     if (!aHUDId || !aContentWindow){
       throw new Error(ERRORS.MISSING_ARGS);
     }
-    var URISpec = aContentWindow.document.location.href
+    var URISpec = aContentWindow.document.location.href;
     this.filterPrefs[aHUDId] = this.defaultFilterPrefs;
     this.displayRegistry[aHUDId] = URISpec;
-    this._headsUpDisplays[aHUDId] = { id: aHUDId, };
+
+    // get the window Id
+    var windowId = this.getWindowId(aContentWindow);
+    this._headsUpDisplays[aHUDId] = { id: aHUDId, windowId: windowId };
+
     this.registerActiveContext(aHUDId);
     // init storage objects:
     this.storage.createDisplay(aHUDId);
 
     var huds = this.uriRegistry[URISpec];
     var foundHUDId = false;
 
     if (huds) {
@@ -1892,22 +1922,16 @@ HUD_SERVICE.prototype =
       if (splitters[i].getAttribute("class") == "hud-splitter") {
         splitters[i].parentNode.removeChild(splitters[i]);
         break;
       }
     }
     // remove the DOM Nodes
     parent.removeChild(outputNode);
 
-    this.windowRegistry[id].forEach(function(aContentWindow) {
-      if (aContentWindow.console instanceof HUDConsole) {
-        delete aContentWindow.console;
-      }
-    });
-
     // remove our record of the DOM Nodes from the registry
     delete this._headsUpDisplays[id];
     // remove the HeadsUpDisplay object from memory
     this.deleteHeadsUpDisplay(id);
     // remove the related storage object
     this.storage.removeDisplay(id);
     // remove the related window objects
     delete this.windowRegistry[id];
@@ -2120,20 +2144,19 @@ HUD_SERVICE.prototype =
    * @returns void
    */
   logMessage: function HS_logMessage(aMessage, aConsoleNode, aMessageNode)
   {
     if (!aMessage) {
       throw new Error(ERRORS.MISSING_ARGS);
     }
 
-    var hud = this.getHeadsUpDisplay(aMessage.hudId);
     switch (aMessage.origin) {
       case "network":
-      case "HUDConsole":
+      case "WebConsole":
       case "console-listener":
         this.logHUDMessage(aMessage, aConsoleNode, aMessageNode);
         break;
       default:
         // noop
         break;
     }
   },
@@ -2173,32 +2196,16 @@ HUD_SERVICE.prototype =
     };
 
     let messageObject =
     this.messageFactory(msgFormat, "error", outputNode, msgFormat.activityObject);
     this.logMessage(messageObject.messageObject, outputNode, messageObject.messageNode);
   },
 
   /**
-   * generates an nsIScriptError
-   *
-   * @param object aMessage
-   * @param integer flag
-   * @returns nsIScriptError
-   */
-  generateConsoleMessage:
-  function HS_generateConsoleMessage(aMessage, flag)
-  {
-    let message = scriptError; // nsIScriptError
-    message.init(aMessage.message, null, null, 0, 0, flag,
-                 "HUDConsole");
-    return message;
-  },
-
-  /**
    * Register a Gecko app's specialized ApplicationHooks object
    *
    * @returns void or throws "UNSUPPORTED APPLICATION" error
    */
   registerApplicationHooks:
   function HS_registerApplications(aAppName, aHooksObject)
   {
     switch(aAppName) {
@@ -2250,17 +2257,18 @@ HUD_SERVICE.prototype =
    *
    * @param nsIDOMNode aNode
    *        DOMNode to display the panel next to.
    * @param object aHttpActivity
    *        httpActivity object. The data of this object is displayed in the
    *        NetworkPanel.
    * @returns NetworkPanel
    */
-  openNetworkPanel: function (aNode, aHttpActivity) {
+  openNetworkPanel: function HS_openNetworkPanel(aNode, aHttpActivity)
+  {
     let doc = aNode.ownerDocument;
     let parent = doc.getElementById("mainPopupSet");
     let netPanel = new NetworkPanel(parent, aHttpActivity);
     netPanel.linkNode = aNode;
 
     let panel = netPanel.panel;
     panel.openPopup(aNode, "after_pointer", 0, 0, false, false);
     panel.sizeTo(350, 400);
@@ -2274,18 +2282,22 @@ HUD_SERVICE.prototype =
    * is active for.
    */
   startHTTPObservation: function HS_httpObserverFactory()
   {
     // creates an observer for http traffic
     var self = this;
     var httpObserver = {
       observeActivity :
-      function (aChannel, aActivityType, aActivitySubtype,
-                aTimestamp, aExtraSizeData, aExtraStringData)
+      function HS_SHO_observeActivity(aChannel,
+                                      aActivityType,
+                                      aActivitySubtype,
+                                      aTimestamp,
+                                      aExtraSizeData,
+                                      aExtraStringData)
       {
         if (aActivityType ==
               activityDistributor.ACTIVITY_TYPE_HTTP_TRANSACTION ||
             aActivityType ==
               activityDistributor.ACTIVITY_TYPE_SOCKET_TRANSPORT) {
 
           aChannel = aChannel.QueryInterface(Ci.nsIHttpChannel);
 
@@ -2303,16 +2315,17 @@ HUD_SERVICE.prototype =
             // Try to get the hudId that is associated to the window.
             hudId = self.getHudIdByWindow(win);
             if (!hudId) {
               return;
             }
 
             // The httpActivity object will hold all information concerning
             // this request and later response.
+
             let httpActivity = {
               id: self.sequenceId(),
               hudId: hudId,
               url: aChannel.URI.spec,
               method: aChannel.requestMethod,
               channel: aChannel,
               charset: win.document.characterSet,
 
@@ -2850,35 +2863,23 @@ HUD_SERVICE.prototype =
     let docElem = xulWindow.document.documentElement;
     if (!docElem || docElem.getAttribute("windowtype") != "navigator:browser" ||
         !xulWindow.gBrowser) {
       // Do not do anything unless we have a browser window.
       // This may be a view-source window or other type of non-browser window.
       return;
     }
 
-    if (aContentWindow.document.location.href == "about:blank" &&
-        HUDWindowObserver.initialConsoleCreated == false) {
-      // TODO: need to make this work with about:blank in the future
-      // see bug 568661
-      return;
-    }
-
     xulWindow.addEventListener("unload", this.onWindowUnload, false);
 
     let gBrowser = xulWindow.gBrowser;
 
-
-    var container = gBrowser.tabContainer;
+    let container = gBrowser.tabContainer;
     container.addEventListener("TabClose", this.onTabClose, false);
 
-    if (gBrowser && !HUDWindowObserver.initialConsoleCreated) {
-      HUDWindowObserver.initialConsoleCreated = true;
-    }
-
     let _browser = gBrowser.
       getBrowserForDocument(aContentWindow.top.document);
     let nBox = gBrowser.getNotificationBox(_browser);
     let nBoxId = nBox.getAttribute("id");
     let hudId = "hud_" + nBoxId;
 
     if (!this.canActivateContext(hudId)) {
       return;
@@ -2898,37 +2899,38 @@ HUD_SERVICE.prototype =
       }
     }
 
     let hud;
     // If there is no HUD for this tab create a new one.
     if (!hudNode) {
       // get nBox object and call new HUD
       let config = { parentNode: nBox,
-                     contentWindow: aContentWindow,
+                     contentWindow: aContentWindow
                    };
 
       hud = new HeadsUpDisplay(config);
 
       let hudWeakRef = Cu.getWeakReference(hud);
       HUDService.registerHUDWeakReference(hudWeakRef, hudId);
     }
     else {
       hud = this.hudWeakReferences[hudId].get();
-      hud.reattachConsole(aContentWindow.top);
+      if (aContentWindow == aContentWindow.top) {
+        // TODO: name change?? doesn't actually re-attach the console
+        hud.reattachConsole(aContentWindow);
+      }
     }
 
-    // Check if aContentWindow has a console object. If so, don't attach
-    // our console, but warn the user about this.
-    if (aContentWindow.wrappedJSObject.console) {
+    // need to detect that the console component has been paved over
+    // TODO: change how we detect our console: bug 612405
+    let consoleObject = aContentWindow.wrappedJSObject.console;
+    if (consoleObject && consoleObject.classID != CONSOLEAPI_CLASS_ID) {
       this.logWarningAboutReplacedAPI(hudId);
     }
-    else {
-      aContentWindow.wrappedJSObject.console = hud.console;
-    }
 
     // register the controller to handle "select all" properly
     this.createController(xulWindow);
   },
 
   /**
    * Adds the command controller to the XUL window if it's not already present.
    *
@@ -3095,31 +3097,28 @@ function HeadsUpDisplay(aConfig)
 
   let splitter = this.chromeDocument.createElement("splitter");
   splitter.setAttribute("class", "hud-splitter");
 
   this.notificationBox.insertBefore(splitter,
                                     this.notificationBox.childNodes[1]);
 
   this.HUDBox.lastTimestamp = 0;
-
-  // Create the console object that is attached to the window later.
-  this._console = this.createConsole();
-
   // create the JSTerm input element
   try {
     this.createConsoleInput(this.contentWindow, this.consoleWrap, this.outputNode);
     this.HUDBox.querySelectorAll(".jsterm-input-node")[0].focus();
   }
   catch (ex) {
     Cu.reportError(ex);
   }
 }
 
 HeadsUpDisplay.prototype = {
+
   /**
    * L10N shortcut function
    *
    * @param string aName
    * @returns string
    */
   getStr: function HUD_getStr(aName)
   {
@@ -3172,20 +3171,16 @@ HeadsUpDisplay.prototype = {
    * @returns void
    */
   reattachConsole: function HUD_reattachConsole(aContentWindow)
   {
     this.contentWindow = aContentWindow;
     this.contentDocument = this.contentWindow.document;
     this.uriSpec = this.contentWindow.location.href;
 
-    if (!this._console) {
-      this._console = this.createConsole();
-    }
-
     if (!this.jsterm) {
       this.createConsoleInput(this.contentWindow, this.consoleWrap, this.outputNode);
     }
     else {
       this.jsterm.context = Cu.getWeakReference(this.contentWindow);
       this.jsterm.console = this.console;
       this.jsterm.createSandbox();
     }
@@ -3479,129 +3474,110 @@ HeadsUpDisplay.prototype = {
 
       let nodes = this.notificationBox.insertBefore(this.HUDBox,
         this.notificationBox.childNodes[0]);
 
       return this.HUDBox;
     }
   },
 
-  get console() {
-    if (!this._console) {
-      this._console = this.createConsole();
-    }
-
-    return this._console;
-  },
+  get console() { return this.contentWindow.wrappedJSObject.console; },
 
   getLogCount: function HUD_getLogCount()
   {
     return this.outputNode.childNodes.length;
   },
 
   getLogNodes: function HUD_getLogNodes()
   {
     return this.outputNode.childNodes;
   },
 
-  /**
-   * This console will accept a message, get the tab's meta-data and send
-   * properly-formatted message object to the service identifying
-   * where it came from, etc...
-   *
-   * @returns console
-   */
-  createConsole: function HUD_createConsole()
-  {
-    return new HUDConsole(this);
-  },
-
   ERRORS: {
     HUD_BOX_DOES_NOT_EXIST: "Heads Up Display does not exist",
     TAB_ID_REQUIRED: "Tab DOM ID is required",
     PARENTNODE_NOT_FOUND: "parentNode element not found"
   }
 };
 
 
 //////////////////////////////////////////////////////////////////////////////
-// HUDConsole factory function
+// ConsoleAPIObserver
 //////////////////////////////////////////////////////////////////////////////
 
-/**
- * The console object that is attached to each contentWindow
- *
- * @param object aHeadsUpDisplay
- * @returns object
- */
-function HUDConsole(aHeadsUpDisplay)
-{
-  let hud = aHeadsUpDisplay;
-  let hudId = hud.hudId;
-  let outputNode = hud.outputNode;
-  let chromeDocument = hud.chromeDocument;
-
-  let sendToHUDService = function console_send(aLevel, aArguments)
+let ConsoleAPIObserver = {
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+
+  init: function CAO_init()
+  {
+    Services.obs.addObserver(this, "quit-application-granted", false);
+    Services.obs.addObserver(this, "console-api-log-event", false);
+  },
+
+  observe: function CAO_observe(aMessage, aTopic, aData)
+  {
+    if (aTopic == "console-api-log-event") {
+      aMessage = aMessage.wrappedJSObject;
+      let windowId = parseInt(aData);
+      try {
+        let win = HUDService.getWindowByWindowId(windowId).top;
+      }
+      catch (ex) {
+        // noop
+        return;
+      }
+
+      let hudId;
+      let displays = HUDService._headsUpDisplays;
+      let foundConsoleId = false;
+      for (let idx in displays) {
+        if (parseInt(displays[idx].windowId) == parseInt(windowId)) {
+          hudId = displays[idx].id;
+          foundConsoleId = true;
+          let webConsole = HUDService.hudWeakReferences[hudId].get();
+
+          this.sendToWebConsole(webConsole, aMessage.level, aMessage.arguments);
+        }
+      }
+    }
+    else if (aTopic == "quit-application-granted") {
+      this.shutdown();
+    }
+  },
+
+  shutdown: function CAO_shutdown()
+  {
+    Services.obs.removeObserver(this, "console-api-log-event");
+  },
+
+  sendToWebConsole:
+  function CAO_sendToWebConsole(aWebConsole, aLevel, aArguments)
   {
     let ts = ConsoleUtils.timestamp();
-    let messageNode = hud.makeXULNode("label");
-
+    let messageNode = aWebConsole.makeXULNode("label");
     let klass = "hud-msg-node hud-" + aLevel;
 
     messageNode.setAttribute("class", klass);
 
-    let argumentArray = [];
-    for (var i = 0; i < aArguments.length; i++) {
-      argumentArray.push(aArguments[i]);
-    }
-
-    let message = argumentArray.join(' ');
-    let timestampedMessage = ConsoleUtils.timestampString(ts) + ": " +
-      message + "\n";
-
-    messageNode.appendChild(chromeDocument.createTextNode(timestampedMessage));
-
+    let message = Array.join(aArguments, " ") + "\n";
+    let timestampedMessage = ConsoleUtils.timestampString(ts) + ": " + message;
+
+    messageNode.appendChild(aWebConsole.chromeDocument.createTextNode(timestampedMessage));
     // need a constructor here to properly set all attrs
     let messageObject = {
       logLevel: aLevel,
-      hudId: hud.hudId,
+      hudId: aWebConsole.hudId,
       message: message,
       timestamp: ts,
-      origin: "HUDConsole",
+      origin: "WebConsole",
     };
 
-    HUDService.logMessage(messageObject, hud.outputNode, messageNode);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Console API.
-  this.log = function console_log()
-  {
-    sendToHUDService("log", arguments);
+    HUDService.logMessage(messageObject, aWebConsole.outputNode, messageNode);
   },
-
-  this.info = function console_info()
-  {
-    sendToHUDService("info", arguments);
-  },
-
-  this.warn = function console_warn()
-  {
-    sendToHUDService("warn", arguments);
-  },
-
-  this.error = function console_error()
-  {
-    sendToHUDService("error", arguments);
-  },
-
-  this.exception = function console_exception()
-  {
-    sendToHUDService("exception", arguments);
-  }
 };
 
 /**
  * Creates a DOM Node factory for XUL nodes - as well as textNodes
  * @param aFactoryType "xul" or "text"
  * @param ignored This parameter is currently ignored, and will be removed
  * See bug 594304
  * @param aDocument The document, the factory is to generate nodes from
@@ -4093,37 +4069,38 @@ JSTerm.prototype = {
     this.sandbox.console = this.console;
     JSTermHelper(this);
   },
 
   get _window()
   {
     return this.context.get().QueryInterface(Ci.nsIDOMWindowInternal);
   },
+
   /**
    * Evaluates a string in the sandbox. The string is currently wrapped by a
    * with(window) { aString } construct, see bug 574033.
    *
    * @param string aString
    *        String to evaluate in the sandbox.
    * @returns something
    *          The result of the evaluation.
    */
   evalInSandbox: function JST_evalInSandbox(aString)
   {
-    return Cu.evalInSandbox(aString, this.sandbox, "1.8", "HUD Console", 1);
+    return Cu.evalInSandbox(aString, this.sandbox, "1.8", "Web Console", 1);
   },
 
 
   execute: function JST_execute(aExecuteString)
   {
     // attempt to execute the content of the inputNode
     aExecuteString = aExecuteString || this.inputNode.value;
     if (!aExecuteString) {
-      this.console.log("no value to execute");
+      this.writeOutput("no value to execute");
       return;
     }
 
     this.writeOutput(aExecuteString, true);
 
     try {
       var result = this.evalInSandbox(aExecuteString);
 
@@ -4133,17 +4110,17 @@ JSTerm.prototype = {
       else if (result === undefined) {
         this.writeOutput("undefined", false);
       }
       else if (result === null) {
         this.writeOutput("null", false);
       }
     }
     catch (ex) {
-      this.console.error(ex);
+      this.writeOutput(ex);
     }
 
     this.history.push(aExecuteString);
     this.historyIndex++;
     this.historyPlaceHolder = this.history.length;
     this.setInputValue("");
   },
 
@@ -4633,17 +4610,17 @@ JSTerm.prototype = {
     else {
       // Look up possible completion values.
       let completion = this.propertyProvider(this.sandbox.window, inputValue);
       if (!completion) {
         return false;
       }
       matches = completion.matches;
       matchIndexToUse = 0;
-      matchOffset = completion.matchProp.length
+      matchOffset = completion.matchProp.length;
       // Store this match;
       this.lastCompletion = {
         index: 0,
         value: inputValue,
         matches: matches,
         matchOffset: matchOffset
       };
     }
@@ -4822,16 +4799,17 @@ LogMessage.prototype = {
       this.message.message;
     var messageTxtNode = this.textFactory(this.timestampedMessage + "\n");
 
     this.messageNode.appendChild(messageTxtNode);
 
     this.messageNode.classList.add("hud-msg-node");
     this.messageNode.classList.add("hud-" + this.level);
 
+
     if (this.activityObject.category == "CSS Parser") {
       this.messageNode.classList.add("hud-cssparser");
     }
 
     var self = this;
 
     var messageObject = {
       logLevel: self.level,
@@ -5386,21 +5364,16 @@ HUDWindowObserver = {
   },
 
   uninit: function HWO_uninit()
   {
     Services.obs.removeObserver(this, "content-document-global-created");
     HUDService.shutdown();
   },
 
-  /**
-   * once an initial console is created set this to true so we don't
-   * over initialize
-   */
-  initialConsoleCreated: false,
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 // CommandController
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
  * A controller (an instance of nsIController) that makes editing actions
@@ -5547,14 +5520,15 @@ function appName()
 
 try {
   // start the HUDService
   // This is in a try block because we want to kill everything if
   // *any* of this fails
   var HUDService = new HUD_SERVICE();
   HUDWindowObserver.init();
   HUDConsoleObserver.init();
+  ConsoleAPIObserver.init();
 }
 catch (ex) {
   Cu.reportError("HUDService failed initialization.\n" + ex);
   // TODO: kill anything that may have started up
   // see bug 568665
 }
--- a/toolkit/components/console/hudservice/tests/browser/Makefile.in
+++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in
@@ -95,22 +95,20 @@ include $(topsrcdir)/config/rules.mk
 	browser_webconsole_bug_589162_css_filter.js \
 	browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js \
 	browser_webconsole_bug_595350_multiple_windows_and_tabs.js \
 	browser_webconsole_bug_594497_history_arrow_keys.js \
 	browser_webconsole_bug_588342_document_focus.js \
 	browser_webconsole_bug_595934_message_categories.js \
 	browser_webconsole_bug_601352_scroll.js \
 	browser_webconsole_bug_592442_closing_brackets.js \
+	browser_webconsole_bug_593003_iframe_wrong_hud.js \
 	head.js \
 	$(NULL)
 
-# compartment-disabled
-#	browser_webconsole_bug_593003_iframe_wrong_hud.js \
-
 _BROWSER_TEST_PAGES = \
 	test-console.html \
 	test-network.html \
 	test-network-request.html \
 	test-mutation.html \
 	testscript.js \
 	test-filter.html \
 	test-observe-http-ajax.html \
--- a/toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
@@ -52,22 +52,22 @@ function test()
 function testOpenWebConsole()
 {
   openConsole();
   is(HUDService.displaysIndex().length, 1, "WebConsole was opened");
 
   hudId = HUDService.displaysIndex()[0];
   hud = HUDService.getHeadsUpDisplay(hudId);
 
-  HUDService.logWarningAboutReplacedAPI(hudId);
   testWarning();
 }
 
 function testWarning()
 {
   const successMsg = "Found the warning message";
   const errMsg = "Could not find the warning message about the replaced API";
 
-  outputNode = HUDService.hudWeakReferences[hudId].get().outputNode;
-  testLogEntry(outputNode, "disabled", { success: successMsg, err: errMsg });
+  testLogEntry(hud, "disabled",
+               { success: "Found disabled console error message",
+                 err: "disable msg not found"});
 
   finishTest();
 }
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
@@ -50,14 +50,13 @@ function test() {
 function testInputFocus() {
   browser.removeEventListener("DOMContentLoaded", testInputFocus, false);
 
   openConsole();
   let hudId = HUDService.displaysIndex()[0];
   let hudBox = HUDService.getHeadsUpDisplay(hudId);
 
   let inputNode = hudBox.querySelector(".jsterm-input-node");
-  log("focused: " + inputNode.getAttribute("focused"));
   ok(inputNode.getAttribute("focused"), "input node is focused");
 
   finishTest();
 }
 
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
@@ -97,14 +97,13 @@ var consoleObserver = {
 
     hudId = HUDService.displaysIndex()[0];
     hud = HUDService.hudWeakReferences[hudId].get();
     outputNode = hud.outputNode;
 
     executeSoon(function() {
       testLogEntry(outputNode, "fooBazBaz",
                    { success: successMsg, err: errMsg });
-
       finishTest();
     });
   }
 };
 
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588342_document_focus.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588342_document_focus.js
@@ -20,17 +20,16 @@ function test()
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   notificationBox = gBrowser.getNotificationBox(browser);
   let DOMNodeInserted = false;
 
   document.addEventListener("DOMNodeInserted", function(aEvent) {
-    log("DOMNodeInserted");
     input = notificationBox.querySelector(".jsterm-input-node");
     if (input && !DOMNodeInserted) {
       DOMNodeInserted = true;
       document.removeEventListener(aEvent.type, arguments.callee, false);
       if (!input.getAttribute("focused")) {
         input.addEventListener("focus", function(aEvent) {
           input.removeEventListener(aEvent.type, arguments.callee, false);
           executeSoon(runTest);
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_589162_css_filter.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_589162_css_filter.js
@@ -5,42 +5,49 @@
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "data:text/html,<div style='font-size:3em;" +
-  "foobarCssParser:baz'>test CSS parser filter</div>"
+  "foobarCssParser:baz'>test CSS parser filter</div>";
 
 function onContentLoaded()
 {
   browser.removeEventListener("load", arguments.callee, true);
 
   hudId = HUDService.displaysIndex()[0];
   HUD = HUDService.hudWeakReferences[hudId].get().HUDBox;
   let filterBox = HUD.querySelector(".hud-filter-box");
   let outputNode = HUD.querySelector(".hud-output-node");
 
   let warningFound = "the unknown CSS property warning is displayed";
   let warningNotFound = "could not find the unknown CSS property warning";
 
   testLogEntry(outputNode, "foobarCssParser",
-    { success: warningFound, err: warningNotFound }, true);
+               { success: warningFound, err: warningNotFound }, true);
 
   HUDService.setFilterState(hudId, "cssparser", false);
+  let nodes = HUD.querySelectorAll(".hud-msg-node");
 
-  warningNotFound = "the unknown CSS property warning is not displayed, " +
-    "after filtering";
-  warningFound = "the unknown CSS property warning is still displayed, " +
-    "after filtering";
+  executeSoon(
+    function (){
+      HUDService.setFilterState(hudId, "cssparser", false);
 
-  testLogEntry(outputNode, "foobarCssParser",
-    { success: warningNotFound, err: warningFound }, true, true);
+      warningNotFound = "the unknown CSS property warning is not displayed, " +
+        "after filtering";
+      warningFound = "the unknown CSS property warning is still displayed, " +
+        "after filtering";
+
+      testLogEntry(outputNode, "foobarCssParser",
+                   { success: warningNotFound, err: warningFound }, true, true);
+    }
+  );
 
   finishTest();
 }
 
 /**
  * Unit test for bug 589162:
  * CSS filtering on the console does not work
  */
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
@@ -55,91 +55,63 @@ function test() {
  * @param {Element} aOutputNode the HUD output node.
  * @param {string} aMatchString the string you want to check if it exists in the
  * output node.
  * @param {boolean} [aOnlyVisible=false] find only messages that are visible,
  * not hidden by the filter.
  * @param {boolean} [aFailIfFound=false] fail the test if the string is found in
  * the output node.
  */
-function testLogEntry(aOutputNode, aMatchString, aSuccessErrObj, aOnlyVisible, aFailIfFound)
-{
-  let found = true;
-  let notfound = false;
-  let foundMsg = aSuccessErrObj.success;
-  let notfoundMsg = aSuccessErrObj.err;
-
-  if (aFailIfFound) {
-    found = false;
-    notfound = true;
-    foundMsg = aSuccessErrObj.err;
-    notfoundMsg = aSuccessErrObj.success;
-  }
-
-  let selector = ".hud-group > *";
-
-  // Skip entries that are hidden by the filter.
-  if (aOnlyVisible) {
-    selector += ":not(.hud-filtered-by-type)";
-  }
-
-  let msgs = aOutputNode.querySelectorAll(selector);
-  for (let i = 0, n = msgs.length; i < n; i++) {
-    let message = msgs[i].textContent.indexOf(aMatchString);
-    if (message > -1) {
-      ok(found, foundMsg);
-      return;
-    }
-  }
-
-  ok(notfound, notfoundMsg);
-}
 
 function tab1Loaded(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
-
-  waitForFocus(function () {
+  browser.contentWindow.wrappedJSObject.console.log("FOO");
+  try {
     openConsole();
-    tab2 = gBrowser.addTab(TEST_DUMMY_URI);
-    gBrowser.selectedTab = tab2;
-    gBrowser.selectedBrowser.addEventListener("load", tab2Loaded, true);
-  }, content);
+  }
+  catch (ex) {
+    log(ex);
+    log(ex.stack);
+  }
+
+  tab2 = gBrowser.addTab(TEST_DUMMY_URI);
+  gBrowser.selectedTab = tab2;
+  gBrowser.selectedBrowser.addEventListener("load", tab2Loaded, true);
 }
 
 function tab2Loaded(aEvent) {
   tab2.linkedBrowser.removeEventListener(aEvent.type, arguments.callee, true);
 
-  waitForFocus(function () {
-    HUDService.activateHUDForContext(gBrowser.selectedTab);
+  HUDService.activateHUDForContext(gBrowser.selectedTab);
 
-    tab1.linkedBrowser.addEventListener("load", tab1Reloaded, true);
-    tab1.linkedBrowser.contentWindow.location.reload();
-  }, content);
+  tab1.linkedBrowser.addEventListener("load", tab1Reloaded, true);
+  tab1.linkedBrowser.contentWindow.location.reload();
 }
 
 function tab1Reloaded(aEvent) {
   tab1.linkedBrowser.removeEventListener(aEvent.type, arguments.callee, true);
 
   let hudId1 = HUDService.getHudIdByWindow(tab1.linkedBrowser.contentWindow);
+
   let display1 = HUDService.getOutputNodeById(hudId1);
   let outputNode1 = display1.querySelector(".hud-output-node");
 
   const successMsg1 = "Found the iframe network request in tab1";
   const errorMsg1 = "Failed to find the iframe network request in tab1";
 
   testLogEntry(outputNode1, TEST_IFRAME_URI,
-    { success: successMsg1, err: errorMsg1}, true);
+               { success: successMsg1, err: errorMsg1}, true);
 
   let hudId2 = HUDService.getHudIdByWindow(tab2.linkedBrowser.contentWindow);
   let display2 = HUDService.getOutputNodeById(hudId2);
   let outputNode2 = display2.querySelector(".hud-output-node");
 
   isnot(display1, display2, "the two HUD displays must be different");
   isnot(outputNode1, outputNode2,
-    "the two HUD outputNodes must be different");
+        "the two HUD outputNodes must be different");
 
   const successMsg2 = "The iframe network request is not in tab2";
   const errorMsg2 = "Found the iframe network request in tab2";
 
   testLogEntry(outputNode2, TEST_IFRAME_URI,
                { success: successMsg2, err: errorMsg2}, true, true);
 
   HUDService.deactivateHUDForContext(tab2);
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
@@ -4,42 +4,43 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+let HUD;
 
 let outputItem;
 
 function tabLoad1(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   openConsole();
 
-  let hudId = HUDService.getHudIdByWindow(content);
+  let hudId = HUDService.getHudIdByWindow(browser.contentWindow);
   HUD = HUDService.hudWeakReferences[hudId].get();
 
   let display = HUDService.getOutputNodeById(hudId);
   outputNode = display.querySelector(".hud-output-node");
 
   browser.addEventListener("load", tabLoad2, true);
 
   // Reload so we get some output in the console.
-  content.location.reload();
+  browser.contentWindow.location.reload();
+  log(document);
 }
 
 function tabLoad2(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   outputItem = outputNode.querySelector(".hud-network");
   ok(outputItem, "found a network message");
-
   document.addEventListener("popupshown", networkPanelShown, false);
 
   // Send the mousedown and click events such that the network panel opens.
   EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
   EventUtils.sendMouseEvent({type: "click"}, outputItem);
 }
 
 function networkPanelShown(aEvent) {
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601352_scroll.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601352_scroll.js
@@ -12,27 +12,27 @@ function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   openConsole();
 
   let hudId = HUDService.getHudIdByWindow(content);
   let HUD = HUDService.hudWeakReferences[hudId].get();
 
   let longMessage = "";
-  for (let i = 0; i < 20; i++) {
+  for (let i = 0; i < 50; i++) {
     longMessage += "LongNonwrappingMessage";
   }
 
-  for (let i = 0; i < 100; i++) {
+  for (let i = 0; i < 50; i++) {
     HUD.console.log("test message " + i);
   }
 
   HUD.console.log(longMessage);
 
-  for (let i = 0; i < 100; i++) {
+  for (let i = 0; i < 50; i++) {
     HUD.console.log("test message " + i);
   }
 
   HUD.jsterm.execute("1+1");
 
   executeSoon(function() {
     isnot(HUD.outputNode.scrollTop, 0, "scroll location is not at the top");
 
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
@@ -51,55 +51,64 @@ function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
 
   openConsole();
 
   testConsoleLoggingAPI("log");
   testConsoleLoggingAPI("info");
   testConsoleLoggingAPI("warn");
   testConsoleLoggingAPI("error");
-  testConsoleLoggingAPI("exception");
 
   finishTest();
 }
 
 function testConsoleLoggingAPI(aMethod) {
   let hudId = HUDService.displaysIndex()[0];
   let console = browser.contentWindow.wrappedJSObject.console;
   let hudBox = HUDService.getHeadsUpDisplay(hudId);
   let outputNode = hudBox.querySelector(".hud-output-node");
 
   HUDService.clearDisplay(hudId);
 
-  setStringFilter("foo");
+  setStringFilter(hudId, "foo");
   console[aMethod]("foo-bar-baz");
   console[aMethod]("bar-baz");
-  var count = outputNode.querySelectorAll(".hud-filtered-by-string").length;
-  ok(count == 1, "1 hidden " + aMethod  + " node found");
+
+  var nodes = outputNode.querySelectorAll(".hud-filtered-by-string");
+
+  is(nodes.length, 1, "1 hidden " + aMethod  + " node found (via classList)");
+
   HUDService.clearDisplay(hudId);
 
   // now toggle the current method off - make sure no visible message
-  // nodes are logged
-  setStringFilter("");
+
+  // TODO: move all filtering tests into a separate test file: see bug 608135
+  setStringFilter(hudId, "");
   HUDService.setFilterState(hudId, aMethod, false);
   console[aMethod]("foo-bar-baz");
-  count = outputNode.querySelectorAll(".hud-filtered-by-type").length;
-  is(count, 1, aMethod + " logging turned off, 1 message hidden");
+  nodes = outputNode.querySelectorAll("label");
+
+  is(nodes.length, 1,  aMethod + " logging turned off, 1 message hidden");
+
   HUDService.clearDisplay(hudId);
-  setStringFilter("");
+  HUDService.setFilterState(hudId, aMethod, true);
+  console[aMethod]("foo-bar-baz");
+  nodes = outputNode.querySelectorAll("label");
+
+  is(nodes.length, 1, aMethod + " logging turned on, 1 message shown");
+
+  HUDService.clearDisplay(hudId);
+  setStringFilter(hudId, "");
 
   // test for multiple arguments.
-  HUDService.clearDisplay(hudId);
-  HUDService.setFilterState(hudId, aMethod, true);
   console[aMethod]("foo", "bar");
 
   let node = outputNode.querySelectorAll(".hud-msg-node")[0];
   ok(/foo bar/.test(node.textContent),
     "Emitted both console arguments");
 }
 
-function setStringFilter(aValue) {
-  let hudId = HUDService.displaysIndex()[0];
-  let hudBox = HUDService.getHeadsUpDisplay(hudId);
+function setStringFilter(aId, aValue) {
+  let hudBox = HUDService.getHeadsUpDisplay(aId);
   hudBox.querySelector(".hud-filter-box").value = aValue;
-  HUDService.adjustVisibilityOnSearchStringChange(hudId, aValue);
+  HUDService.adjustVisibilityOnSearchStringChange(aId, aValue);
 }
 
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
@@ -27,61 +27,24 @@ function testOpenWebConsole()
 
   hudId = HUDService.displaysIndex()[0];
   hud = HUDService.hudWeakReferences[hudId].get();
 
   testOwnConsole();
 }
 
 function testConsoleOnPage(console) {
-  // let console = browser.contentWindow.wrappedJSObject.console;
   isnot(console, undefined, "Console object defined on page");
   is(console.foo, "bar", "Custom console is not overwritten");
 }
 
 function testOwnConsole()
 {
   let console = browser.contentWindow.wrappedJSObject.console;
   // Test console on the page. There is already one so it shouldn't be
   // overwritten by the WebConsole's console.
   testConsoleOnPage(console);
 
   // Check that the console object is set on the jsterm object although there
   // is no console object added to the page.
   ok(hud.jsterm.console, "JSTerm console is defined");
-  ok(hud.jsterm.console === hud._console, "JSTerm console is same as HUD console");
-
-  let iframe =
-    browser.contentWindow.document.querySelector("iframe");
-
-  function consoleTester()
-  {
-    testIFrameConsole(iframe);
-  }
-
-  iframe.contentWindow.
-    addEventListener("load", consoleTester ,false);
-
-  iframe.contentWindow.document.location = "http://example.com/";
-
-  function testIFrameConsole(iFrame)
-  {
-    iFrame.contentWindow.removeEventListener("load", consoleTester, true);
-
-    // Test the console in the iFrame.
-    let consoleIFrame = iFrame.wrappedJSObject.contentWindow.console;
-    // TODO: Fix this test. Not sure what it is intending, and this will
-    // change drastically once the lazy console lands
-    // ok(browser.contentWindow.wrappedJSObject.console === hud._console, "Console on the page is hud console");
-
-    // Close the hud and see which console is still around.
-    HUDService.deactivateHUDForContext(tab);
-
-    executeSoon(function () {
-      consoleIFrame = iFrame.contentWindow.console;
-      is(consoleIFrame, undefined, "Console object was removed from iFrame");
-      testConsoleOnPage(browser.contentWindow.wrappedJSObject.console);
-      finishTest();
-  });
+  finishTest();
 }
-
-  browser.contentWindow.wrappedJSObject.loadIFrame();
-}
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
@@ -57,17 +57,16 @@ function testExecutionScope() {
 
   let HUD = HUDService.hudWeakReferences[hudId].get();
   let jsterm = HUD.jsterm;
 
   jsterm.clearOutput();
   jsterm.execute("location;");
 
   let nodes = jsterm.outputNode.querySelectorAll(".hud-msg-node");
-  log(nodes[0].textContent);
   is(nodes.length, 1, "Three children in output");
 
   is(/location;/.test(nodes[0].textContent), true,
      "'location;' written to output");
 
   ok(nodes[0].textContent.indexOf(TEST_URI),
     "command was executed in the window scope");
 
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
@@ -61,25 +61,23 @@ function testNullAndUndefinedOutput() {
   let jsterm = HUD.jsterm;
   outputNode = jsterm.outputNode;
 
   jsterm.clearOutput();
   jsterm.execute("null;");
 
   let nodes = outputNode.querySelectorAll(".hud-msg-node");
   is(nodes.length, 2, "2 nodes in output");
-  log(nodes[1].textContent.toString());
   ok(nodes[1].textContent.indexOf("null") > -1, "'null' printed to output");
 
   jsterm.clearOutput();
   jsterm.execute("undefined;");
 
   nodes = outputNode.querySelectorAll(".hud-msg-node");
   is(nodes.length, 2, "2 nodes in output");
-  log(nodes[1].textContent.toString());
   ok(nodes[1].textContent.indexOf("undefined") > -1, "'undefined' printed to output");
 
   jsterm.clearOutput();
   jsterm.history.splice(0);   // workaround for bug 592552
 
   finishTest();
 }
 
--- a/toolkit/components/console/hudservice/tests/browser/head.js
+++ b/toolkit/components/console/hudservice/tests/browser/head.js
@@ -53,16 +53,28 @@ XPCOMUtils.defineLazyGetter(this, "HUDSe
   }
 });
 
 function log(aMsg)
 {
   dump("*** WebConsoleTest: " + aMsg + "\n");
 }
 
+function pprint(aObj)
+{
+  for (let prop in aObj) {
+    if (typeof aObj[prop] == "function") {
+      log("function " + prop);
+    }
+    else {
+      log(prop + ": " + aObj[prop]);
+    }
+  }
+}
+
 let tab, browser, hudId, hud, hudBox, filterBox, outputNode, cs;
 
 let win = gBrowser.selectedBrowser;
 
 function addTab(aURL)
 {
   gBrowser.selectedTab = gBrowser.addTab();
   content.location = aURL;
@@ -88,36 +100,34 @@ function testLogEntry(aOutputNode, aMatc
   let found = true;
   let notfound = false;
   let foundMsg = aSuccessErrObj.success;
   let notfoundMsg = aSuccessErrObj.err;
 
   if (aFailIfFound) {
     found = false;
     notfound = true;
-    foundMsg = aSuccessErrObj.err;
-    notfoundMsg = aSuccessErrObj.success;
+    foundMsg = aSuccessErrObj.success;
+    notfoundMsg = aSuccessErrObj.err;
   }
 
-  let selector = ".hud-group > *";
-
+  let selector = ".hud-msg-node";
   // Skip entries that are hidden by the filter.
   if (aOnlyVisible) {
     selector += ":not(.hud-filtered-by-type)";
   }
 
   let msgs = aOutputNode.querySelectorAll(selector);
   for (let i = 0, n = msgs.length; i < n; i++) {
     let message = msgs[i].textContent.indexOf(aMatchString);
-  if (message > -1) {
+    if (message > -1) {
       ok(found, foundMsg);
-    return;
+      return;
+    }
   }
-  }
-
   ok(notfound, notfoundMsg);
 }
 
 function openConsole()
 {
   HUDService.activateHUDForContext(tab);
 }
 
--- a/toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html
+++ b/toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html
@@ -1,15 +1,11 @@
 <!DOCTYPE HTML>
 <html dir="ltr" xml:lang="en-US" lang="en-US"><head>
     <title>Console test replaced API</title>
-    <script type="text/javascript">
-      function replaceAPI() {
-        var console = {log: function (msg){}, info: function (msg){}, warn: function (msg){}, error: function (msg){}};
-        window.console = console;
-      }
-    </script>
   </head>
   <body>
     <h1 id="header">Web Console Replace API Test</h1>
-    <button onclick="replaceAPI();">ReplaceAPI</button>
+    <script type="text/javascript">
+      window.console = {log: function (msg){}, info: function (msg){}, warn: function (msg){}, error: function (msg){}};
+    </script>
   </body>
 </html>
--- a/toolkit/components/console/hudservice/tests/browser/test-console.html
+++ b/toolkit/components/console/hudservice/tests/browser/test-console.html
@@ -1,13 +1,12 @@
 <!DOCTYPE HTML>
 <html dir="ltr" xml:lang="en-US" lang="en-US"><head>
     <title>Console test</title>
     <script type="text/javascript">
-      dump("i am dumping this");
       function test() {
         var str = "Dolske Digs Bacon, Now and Forevermore."
         for (var i=0; i < 5; i++) {
           console.log(str);
         } 
       }
       console.info("INLINE SCRIPT:");
       test();
--- a/toolkit/components/console/hudservice/tests/browser/test-own-console.html
+++ b/toolkit/components/console/hudservice/tests/browser/test-own-console.html
@@ -1,21 +1,22 @@
 <!DOCTYPE HTML>
 <html dir="ltr" xml:lang="en-US" lang="en-US">
 <head>
 <script>
-  window.console = {
+  var _console = {
     foo: "bar"
   }
 
-  function loadIFrame(aCallback) {
+  window.console = _console;
+
+  function loadIFrame() {
     var iframe = document.body.querySelector("iframe");
     iframe.addEventListener("load", function() {
       iframe.removeEventListener("load", arguments.callee, true);
-      aCallback(iframe);
     }, true);
 
     iframe.setAttribute("src", "test-console.html");
   }
 </script>
 </head>
 <body>
   <iframe></iframe>