Bug 481406: Include console messages in the log. r=sdwilsh
☠☠ backed out by 30aa3539cedc ☠ ☠
authorDave Townsend <dtownsend@oxymoronical.com>
Wed, 20 May 2009 10:18:27 +0100
changeset 28804 ddd616e583093f3079a7a6c29f55ef39bdf27fff
parent 28803 2ad7177c98bda1039e72f6165764bbe6d8b94a02
child 28805 30aa3539cedca522384c7a574ecfab59902cb40b
push idunknown
push userunknown
push dateunknown
reviewerssdwilsh
bugs481406
milestone1.9.2a1pre
Bug 481406: Include console messages in the log. r=sdwilsh
testing/mochitest/browser-harness.xul
testing/mochitest/browser-test.js
testing/mochitest/tests/browser/browser_pass.js
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -148,44 +148,29 @@
 
     function browserTestFile(aTestFile) {
       this.path = aTestFile;
       this.tests = [];
       this.scope = null;
     }
     browserTestFile.prototype = {
       get passCount() {
-        return this.tests.filter(function (t) !t.todo && t.pass).length;
+        return this.tests.filter(function (t) !t.info && !t.todo && t.pass).length;
       },
       get todoCount() {
-        return this.tests.filter(function (t) t.todo && t.pass).length;
+        return this.tests.filter(function (t) !t.info && t.todo && t.pass).length;
       },
       get failCount() {
-        return this.tests.filter(function (t) !t.pass).length;
+        return this.tests.filter(function (t) !t.info && !t.pass).length;
       },
       get log() {
-        var path = this.path;
-        return this.tests.map(function (t) {
-                                  return t.result + " | " + path + " | " + t.msg;
-                              }).join("\n");
+        return this.tests.map(function (t) t.log).join("\n");
       },
       get htmlLog() {
-        let txtToHTML = Cc["@mozilla.org/txttohtmlconv;1"].
-                        getService(Ci.mozITXTToHTMLConv);
-        function _entityEncode(str) {
-          return txtToHTML.scanTXT(str, Ci.mozITXTToHTMLConv.kEntities);
-        }
-        var path = _entityEncode( this.path );
-        return this.tests.map(function (t) {
-                                  var result = "<p class=\"result ";
-                                  result += t.pass ? "passed" : "failed";
-                                  result += "\">" + t.result + " | " + path +
-                                    " | " + _entityEncode( t.msg ) + "</p>";
-                                  return result;
-                              }).join("\n");
+        return this.tests.map(function (t) t.htmlLog).join("\n");
       }
     };
 
     // Returns an array of chrome:// URLs to all the test files
     function listTests() {
       const Cc = Components.classes; const Ci = Components.interfaces;
 
       var ioSvc = Cc["@mozilla.org/network/io-service;1"].
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -2,16 +2,20 @@
 const TIMEOUT_SECONDS = 30;
 
 if (Cc === undefined) {
   var Cc = Components.classes;
   var Ci = Components.interfaces;
 }
 window.addEventListener("load", testOnLoad, false);
 
+let txtToHTML = Cc["@mozilla.org/txttohtmlconv;1"].
+                getService(Ci.mozITXTToHTMLConv);
+function entityEncode(str) txtToHTML.scanTXT(str, Ci.mozITXTToHTMLConv.kEntities);
+
 function testOnLoad() {
   window.removeEventListener("load", testOnLoad, false);
 
   // Make sure to launch the test harness for the first opened window only
   var prefs = Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
   if (prefs.prefHasUserValue("testing.browserTestHarness.running"))
     return;
@@ -25,44 +29,53 @@ function testOnLoad() {
   sstring.data = location.search;
   ww.openWindow(window, "chrome://mochikit/content/browser-harness.xul", "browserTest",
                 "chrome,centerscreen,dialog,resizable,titlebar,toolbar=no,width=800,height=600", sstring);
 }
 
 function Tester(aTests, aCallback) {
   this.tests = aTests;
   this.callback = aCallback;
+  this._cs = Cc["@mozilla.org/consoleservice;1"].
+             getService(Ci.nsIConsoleService);
 }
 Tester.prototype = {
   checker: null,
   currentTestIndex: -1,
   get currentTest() {
     return this.tests[this.currentTestIndex];
   },
   get done() {
     return this.currentTestIndex == this.tests.length - 1;
   },
   step: function Tester_step() {
     this.currentTestIndex++;
   },
 
   start: function Tester_start() {
+    this._cs.registerListener(this);
     if (this.tests.length)
       this.execTest();
     else
       this.finish();
   },
 
   finish: function Tester_finish() {
     // Tests complete, notify the callback and return
+    this._cs.unregisterListener(this);
     this.callback(this.tests);
     this.callback = null;
     this.tests = null;
   },
 
+  observe: function Tester_observe(aConsoleMessage) {
+    var msg = "Console message: " + aConsoleMessage.message;
+    this.currentTest.tests.push(new testMessage(this.currentTest.path, msg));
+  },
+
   execTest: function Tester_execTest() {
     if (this.done) {
       this.finish();
       return;
     }
 
     // Move to the next test (or first test).
     this.step();
@@ -73,84 +86,124 @@ Tester.prototype = {
     var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                        getService(Ci.mozIJSSubScriptLoader);
     try {
       scriptLoader.loadSubScript(this.currentTest.path, this.currentTest.scope);
 
       // Run the test
       this.currentTest.scope.test();
     } catch (ex) {
-      this.currentTest.tests.push(new testResult(false, "Exception thrown", ex, false));
+      this.currentTest.tests.push(new testResult(this.currentTest.path, false, "Exception thrown", ex, false));
       this.currentTest.scope.done = true;
     }
 
     // If the test ran synchronously, move to the next test, otherwise the test
     // will trigger the next test when it is done.
     if (this.currentTest.scope.done) {
       this.execTest();
     }
     else {
       var self = this;
       this.currentTest.scope.waitTimer = setTimeout(function() {
-        self.currentTest.tests.push(new testResult(false, "Timed out", "", false));
+        self.currentTest.tests.push(new testResult(self.currentTest.path, false, "Timed out", "", false));
         self.currentTest.scope.waitTimer = null;
         self.execTest();
       }, TIMEOUT_SECONDS * 1000);
     }
+  },
+
+  QueryInterface: function(aIID) {
+    if (aIID.equals(Ci.nsIConsoleListener) ||
+        aIID.equals(Ci.nsISupports))
+      return this;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
   }
 };
 
-function testResult(aCondition, aName, aDiag, aIsTodo) {
-  aName = aName || "";
-
+function testResult(aPath, aCondition, aName, aDiag, aIsTodo) {
+  this.info = false;
+  this.path = aPath;
   this.pass = !!aCondition;
   this.todo = aIsTodo;
-  this.msg = aName;
+  this.msg = aName || "";
   if (this.pass) {
     if (aIsTodo)
       this.result = "TEST-KNOWN-FAIL";
     else
       this.result = "TEST-PASS";
   } else {
     if (aDiag)
       this.msg += " - " + aDiag;
     if (aIsTodo)
       this.result = "TEST-UNEXPECTED-PASS";
     else
       this.result = "TEST-UNEXPECTED-FAIL";
   }
 }
 
+testResult.prototype = {
+  get log() {
+    return this.result + " | " + this.path + " | " + this.msg;
+  },
+
+  get htmlLog() {
+    return "<p class=\"result " + (this.pass ? "passed" : "failed") + "\">" +
+           this.result + " | " + entityEncode(this.path) + " | " +
+           entityEncode(this.msg) + "</p>";
+  }
+}
+
+function testMessage(aPath, aMessage) {
+  this.info = true;
+  this.path = aPath;
+  this.msg = aMessage || "";
+}
+
+testMessage.prototype = {
+  get log() {
+    return "TEST-INFO | " + this.path + " | " + this.msg;
+  },
+
+  get htmlLog() {
+    return "<p class=\"info\">TEST-INFO | " + entityEncode(this.path) + " | " +
+           entityEncode(this.msg) + "</p>";
+  }
+}
+
 function testScope(aTester, aTests) {
   var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                      getService(Ci.mozIJSSubScriptLoader);
   scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", this.EventUtils);
 
   this.tester = aTester;
   this.tests = aTests;
 
   var self = this;
   this.ok = function test_ok(condition, name, diag) {
-    self.tests.push(new testResult(condition, name, diag, false));
+    self.tests.push(new testResult(self.tester.currentTest.path, condition, name, diag, false));
   };
   this.is = function test_is(a, b, name) {
     self.ok(a == b, name, "Got " + a + ", expected " + b);
   };
   this.isnot = function test_isnot(a, b, name) {
     self.ok(a != b, name, "Didn't expect " + a + ", but got it");
   };
   this.todo = function test_todo(condition, name, diag) {
-    self.tests.push(new testResult(!condition, name, diag, true));
+    self.tests.push(new testResult(self.tester.currentTest.path, !condition, name, diag, true));
   };
   this.todo_is = function test_todo_is(a, b, name) {
     self.todo(a == b, name, "Got " + a + ", expected " + b);
   };
   this.todo_isnot = function test_todo_isnot(a, b, name) {
     self.todo(a != b, name, "Didn't expect " + a + ", but got it");
   };
+  this.info = function(message) {
+    self.tests.push(new testMessage(self.tester.currentTest.path, message));
+  }
 
   this.executeSoon = function test_executeSoon(func) {
     let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
 
     tm.mainThread.dispatch({
       run: function() {
         func();
       }
--- a/testing/mochitest/tests/browser/browser_pass.js
+++ b/testing/mochitest/tests/browser/browser_pass.js
@@ -1,11 +1,12 @@
 function test() {
   ok(true, "pass ok");
   is(true, true, "pass is");
   isnot(false, true, "pass isnot");
   todo(false, "pass todo");
   todo_is(false, true, "pass todo_is");
   todo_isnot(true, true, "pass todo_isnot");
+  info("info message");
 
   var func = is;
   func(true, true, "pass indirect is");
 }