Bug 367393 - Add a packed MochiKit that contains only SimpleTest dependencies- harness. r=jmaher, a=test-only
authorMalini Das <mdas@mozilla.com>
Fri, 12 Aug 2011 12:21:35 -0400
changeset 74313 f1113713ce039ac0f0af397962d58d9b9674bb27
parent 74312 997256d4e070a07ea648ad5f554ae9302651ab01
child 74314 67f6f1908b0f4cb8c00d3de763787fdb8fe8eeeb
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersjmaher, test-only
bugs367393
milestone8.0a1
Bug 367393 - Add a packed MochiKit that contains only SimpleTest dependencies- harness. r=jmaher, a=test-only
dom/tests/mochitest/dom-level1-core/DOMTestCase.js
dom/tests/mochitest/dom-level1-core/exclusions.js
dom/tests/mochitest/dom-level2-core/DOMTestCase.js
dom/tests/mochitest/dom-level2-core/exclusions.js
dom/tests/mochitest/dom-level2-html/DOMTestCase.js
layout/base/tests/bug613807-1.html
testing/mochitest/browser-harness.xul
testing/mochitest/chrome-harness.js
testing/mochitest/harness-overlay.xul
testing/mochitest/jar.mn
testing/mochitest/plain-loop.html
testing/mochitest/server.js
testing/mochitest/tests/SimpleTest/EventUtils.js
testing/mochitest/tests/SimpleTest/LogController.js
testing/mochitest/tests/SimpleTest/Makefile.in
testing/mochitest/tests/SimpleTest/SimpleTest.js
testing/mochitest/tests/SimpleTest/TestRunner.js
testing/mochitest/tests/SimpleTest/setup.js
--- a/dom/tests/mochitest/dom-level1-core/DOMTestCase.js
+++ b/dom/tests/mochitest/dom-level1-core/DOMTestCase.js
@@ -649,9 +649,49 @@ SimpleTest._logResult = function(test, p
       } else {
         if (todoTests[docName]) {
           parentRunner.logger.log("expected error in todo testcase | " + test.name);
         } else {
           parentRunner.logger.error(msg);
         }
       } 
   }
-}
\ No newline at end of file
+}
+
+function testFails (test) {
+  if (!test.result) {
+    test.todo = true;
+    return true;
+  }
+  return false;
+}
+
+function markTodos() {
+  if (todoTests[docName]) {
+    // mark the failures as todos
+    var tests = SimpleTest._tests;
+    var failures = [];
+    var o;
+    for (var i = 0; i < tests.length; i++) {
+      o = tests[i];
+      if (testFails(o)) {
+        failures.push(o);
+      } 
+    }
+    // shouldn't be 0 failures
+    todo(SimpleTest._tests != 0 && failures == 0, "test marked todo should fail somewhere");
+  }
+}
+
+function runJSUnitTests() {
+  try {
+    var tests = exposeTestFunctionNames(); 
+    for (var i = 0; i < tests.length; i++) {
+      window[tests[i]](); 
+    }   
+  } catch (ex) {
+    if (todoTests[docName]) {
+      todo(false, "Text threw exception: " + ex);
+    } else { 
+      ok(false, "Test threw exception: " + ex);
+    }
+  }
+}
--- a/dom/tests/mochitest/dom-level1-core/exclusions.js
+++ b/dom/tests/mochitest/dom-level1-core/exclusions.js
@@ -86,10 +86,20 @@ var modTests = ["hc_elementwrongdocument
                 "nodeappendchildnewchilddiffdocument", "nodeinsertbeforenewchilddiffdocument", "nodereplacechildnewchilddiffdocument"];
 // These tests rely on an implementation of document.createEntityReference.
 var createEntityRef = ["documentinvalidcharacterexceptioncreateentref",
                        "documentinvalidcharacterexceptioncreateentref1",
                        "hc_attrgetvalue2", "hc_nodevalue03"];
 
 
 var todoTests = {};
+function concat(lst/*...*/) {
+  var f = [];
+  if (arguments !== null) {
+    f = arguments[0];
+  }
+  for (var i = 1; i < arguments.length; i++) {
+    f = f.concat(arguments[i]);
+  }
+  return f;
+}
 var exclusions = concat(dtdTests, indexErrTests, attributeModTests, modTests, createEntityRef);
 for (var excludedTestName in exclusions) { todoTests[exclusions[excludedTestName]] = true; }
--- a/dom/tests/mochitest/dom-level2-core/DOMTestCase.js
+++ b/dom/tests/mochitest/dom-level2-core/DOMTestCase.js
@@ -663,33 +663,42 @@ SimpleTest.waitForExplicitFinish();
 addLoadEvent(function(){ setUpPage(); });
 function testFails (test) {
   if (!test.result) {
     test.todo = true;
     return true;
   }
   return false;
 }
+
 function markTodos() {
   if (todoTests[docName]) {
     // mark the failures as todos
-    var failures = filter(testFails, SimpleTest._tests);
+    var tests = SimpleTest._tests;
+    var failures = [];
+    var o;
+    for (var i = 0; i < tests.length; i++) {
+      o = tests[i];
+      if (testFails(o)) {
+        failures.push(o);
+      } 
+    }
     // shouldn't be 0 failures
     todo(SimpleTest._tests != 0 && failures == 0, "test marked todo should fail somewhere");
   }
 }
 
 function runJSUnitTests() {
   builder = createConfiguredBuilder();
   try {
-   forEach(exposeTestFunctionNames(), 
-     function (testName) { 
-       window[testName](); 
-     }
-   );
+    var tests = exposeTestFunctionNames(); 
+    for (var i = 0; i < tests.length; i++) {
+      window[tests[i]](); 
+    }   
   } catch (ex) {
     if (todoTests[docName]) {
       todo(false, "Text threw exception: " + ex);
     } else { 
       ok(false, "Test threw exception: " + ex);
     }
   }
-}
\ No newline at end of file
+}
+
--- a/dom/tests/mochitest/dom-level2-core/exclusions.js
+++ b/dom/tests/mochitest/dom-level2-core/exclusions.js
@@ -57,14 +57,25 @@ dtdTests = ["attrgetownerelement01", "do
 
 bug371552 = ["elementhasattributens02"];
 wrongDocError = ["elementsetattributenodens05", "namednodemapsetnameditemns03",
                  "setAttributeNodeNS05", "setNamedItemNS02"];
 attrAppendChild = ["elementsetattributenodens06", "importNode01"];
 bogusPrefix = ["nodesetprefix05", "nodesetprefix09", "prefix06", "prefix07"];
 prefixReplacement = ["setAttributeNodeNS04"];
 
+function concat(lst/*...*/) {
+  var f = [];
+  if (arguments !== null) {
+    f = arguments[0];
+  }
+  for (var i = 1; i < arguments.length; i++) {
+    f = f.concat(arguments[i]);
+  }
+  return f;
+}
+
 var todoTests = {};
 var exclusions = concat(dtdTests, bug371552, wrongDocError, attrAppendChild,
                         bogusPrefix, prefixReplacement);
 for (var excludedTestName in exclusions) { 
   todoTests[exclusions[excludedTestName]] = true; 
 }
--- a/dom/tests/mochitest/dom-level2-html/DOMTestCase.js
+++ b/dom/tests/mochitest/dom-level2-html/DOMTestCase.js
@@ -663,33 +663,41 @@ SimpleTest.waitForExplicitFinish();
 addLoadEvent(function(){ setUpPage(); });
 function testFails (test) {
   if (!test.result) {
     test.todo = true;
     return true;
   }
   return false;
 }
+
 function markTodos() {
   if (todoTests[docName]) {
     // mark the failures as todos
-    var failures = filter(testFails, SimpleTest._tests);
+    var tests = SimpleTest._tests;
+    var failures = [];
+    var o;
+    for (var i = 0; i < tests.length; i++) {
+      o = tests[i];
+      if (testFails(o)) {
+        failures.push(o);
+      } 
+    }
     // shouldn't be 0 failures
     todo(SimpleTest._tests != 0 && failures == 0, "test marked todo should fail somewhere");
   }
 }
 
 function runJSUnitTests() {
   builder = createConfiguredBuilder();
   try {
-   forEach(exposeTestFunctionNames(), 
-     function (testName) { 
-       window[testName](); 
-     }
-   );
+    var tests = exposeTestFunctionNames(); 
+    for (var i = 0; i < tests.length; i++) {
+      window[tests[i]](); 
+   }   
   } catch (ex) {
     //if (todoTests[docName]) {
     //  todo(false, "Text threw exception: " + ex);
     //} else { 
       ok(false, "Test threw exception: " + ex);
     //}
   }
 }
--- a/layout/base/tests/bug613807-1.html
+++ b/layout/base/tests/bug613807-1.html
@@ -2,16 +2,50 @@
 <html>
 <head>
   <script type="text/javascript" src="/MochiKit/packed.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <body>
 <textarea id="t" rows="4"></textarea>
 <script>
+  if (typeof(addLoadEvent) == 'undefined') {
+    _newCallStack = function(path) {
+      var rval = function () {
+        var callStack = arguments.callee.callStack;
+        for (var i = 0; i < callStack.length; i++) {
+          if (callStack[i].apply(this, arguments) === false) {
+            break;
+          }
+        }
+        try {
+          this[path] = null;
+        } catch (e) {
+          // pass
+        }
+      };
+      rval.callStack = [];
+      return rval;
+    };
+    function addLoadEvent(func) {
+      var existing = window["onload"];
+      var regfunc = existing;
+      if (!(typeof(existing) == 'function'
+            && typeof(existing.callStack) == "object"
+            && existing.callStack !== null)) {
+        regfunc = _newCallStack("onload");
+        if (typeof(existing) == 'function') {
+          regfunc.callStack.push(existing);
+        }
+        window["onload"] = regfunc;
+      }
+      regfunc.callStack.push(func);
+    };
+  }
+
   addLoadEvent(function() {
     var area = document.getElementById('t');
     area.focus();
 
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     const nsIDOMWindowUtils = Components.interfaces.nsIDOMWindowUtils;
 
     // start composition
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -40,16 +40,17 @@
    - ***** END LICENSE BLOCK ***** -->
 
 <window id="browserTestHarness"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="TestStart();"
         title="Browser chrome tests"
         width="1024">
   <script src="chrome://mochikit/content/tests/SimpleTest/MozillaLogger.js"/>
+  <script src="chrome://mochikit/content/tests/SimpleTest/LogController.js"/>
   <script src="chrome://mochikit/content/tests/SimpleTest/quit.js"/>
   <script src="chrome://mochikit/content/chrome-harness.js"/>
   <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
     #results {
       margin: 5px;
       background-color: window;
       -moz-user-select: text;
     }
--- a/testing/mochitest/chrome-harness.js
+++ b/testing/mochitest/chrome-harness.js
@@ -210,17 +210,16 @@ function getFileListing(basePath, testPa
     var extraPath = testPath;
     
     var fileNameRegexp = /(browser|test)_.+\.(xul|html|js)$/;
 
     // Invalid testPath...
     if (!testsDir.exists())
       return [];
 
-    // If we were passed a speComponents.interfacesfic file, run only that test.
     if (testsDir.isFile()) {
       if (fileNameRegexp.test(testsDir.leafName))
         var singlePath = basePath + '/' + testPath;
         var links = {};
         links[singlePath] = true;
         return [links, null];
 
       // We were passed a file that's not a test...
--- a/testing/mochitest/harness-overlay.xul
+++ b/testing/mochitest/harness-overlay.xul
@@ -7,16 +7,18 @@
          xmlns:html="http://www.w3.org/1999/xhtml"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
 <window>
   <script type="application/javascript"
           src="chrome://mochikit/content/MochiKit/packed.js" />
   <script type="text/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/LogController.js"/>
+  <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/TestRunner.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/MozillaLogger.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/quit.js" />
   <script type="application/javascript"
           src="chrome://mochikit/content/chrome-harness.js" />
   <script type="text/javascript"
@@ -40,17 +42,17 @@ function loadTests()
   scriptLoader.loadSubScript('chrome://mochikit/content/server.js',
                              srvScope);
 
   // generate our test list
   srvScope.makeTags();
   var tableContent = srvScope.linksToTableRows(links, 0);
 
   function populate() {
-    $("test-table").innerHTML += tableContent;
+    document.getElementById("test-table").innerHTML += tableContent;
   }
   gTestList = eval(srvScope.jsonArrayOfTestFiles(links));
   populate();
 
   hookup();
 }
 
     window.addEventListener("load", loadTests, false);
--- a/testing/mochitest/jar.mn
+++ b/testing/mochitest/jar.mn
@@ -12,16 +12,17 @@ mochikit.jar:
   content/redirect.html (redirect.html)
   content/redirect.js (redirect.js)
   content/server.js (server.js)
   content/dynamic/getMyDirectory.sjs (dynamic/getMyDirectory.sjs)
   content/static/harness.css (static/harness.css)
   content/tests/SimpleTest/EventUtils.js (tests/SimpleTest/EventUtils.js)
   content/tests/SimpleTest/ChromeUtils.js (tests/SimpleTest/ChromeUtils.js)
   content/tests/SimpleTest/MozillaLogger.js (tests/SimpleTest/MozillaLogger.js)
+  content/tests/SimpleTest/LogController.js (tests/SimpleTest/LogController.js)
   content/tests/SimpleTest/PluginUtils.js (tests/SimpleTest/PluginUtils.js)
   content/tests/SimpleTest/quit.js (tests/SimpleTest/quit.js)
   content/tests/SimpleTest/setup.js (tests/SimpleTest/setup.js)
   content/tests/SimpleTest/SimpleTest.js (tests/SimpleTest/SimpleTest.js)
   content/tests/SimpleTest/test.css (tests/SimpleTest/test.css)
   content/tests/SimpleTest/TestRunner.js (tests/SimpleTest/TestRunner.js)
   content/tests/SimpleTest/WindowSnapshot.js (tests/SimpleTest/WindowSnapshot.js)
   content/tests/SimpleTest/mockObjects.js (../../toolkit/content/tests/browser/common/mockObjects.js)
--- a/testing/mochitest/plain-loop.html
+++ b/testing/mochitest/plain-loop.html
@@ -1,27 +1,28 @@
 <html>
 <head>
   <link rel="stylesheet" type="text/css" href="/static/harness.css" />
   <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/LogController.js"></script>        
   <script type="text/javascript" src="/tests/SimpleTest/TestRunner.js"></script>        
   <script type="text/javascript" src="/tests/SimpleTest/MozillaFileLogger.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/setup.js"></script>
   </head>
   <script type="text/javascript">
 
 function loadTests()
 {
   var links = {};
   var params = {};
   if (window.parseQueryString) {
     params = parseQueryString(location.search.substring(1), true);
   }
 
-  var table = $("test-table");
+  var table = document.getElementById("test-table");
   var row = table.rows[1];
   row.id = 'tr-' + params.testname;
   row.cells[3].innerHTML= "<a href=" + params.testname + ">" + params.testname + "</a>";
 
   TestRunner.loopTest(params.testname);
 }
 </script>
 
--- a/testing/mochitest/server.js
+++ b/testing/mochitest/server.js
@@ -610,27 +610,28 @@ function testListing(metadata, response)
   var tests = jsonArrayOfTestFiles(links);
   response.write(
     HTML(
       HEAD(
         TITLE("MochiTest | ", metadata.path),
         LINK({rel: "stylesheet",
               type: "text/css", href: "/static/harness.css"}
         ),
-        SCRIPT({type: "text/javascript", src: "/MochiKit/packed.js"}),
+        SCRIPT({type: "text/javascript",
+                 src: "/tests/SimpleTest/LogController.js"}),
         SCRIPT({type: "text/javascript",
                  src: "/tests/SimpleTest/TestRunner.js"}),
         SCRIPT({type: "text/javascript",
                  src: "/tests/SimpleTest/MozillaLogger.js"}),
         SCRIPT({type: "text/javascript",
                  src: "/tests/SimpleTest/quit.js"}),
         SCRIPT({type: "text/javascript",
                  src: "/tests/SimpleTest/setup.js"}),
         SCRIPT({type: "text/javascript"},
-               "connect(window, 'onload', hookup); gTestList=" + tests + ";"
+               "window.onload =  hookup; gTestList=" + tests + ";"
         )
       ),
       BODY(
         DIV({class: "container"},
           H2("--> ", A({href: "#", id: "runtests"}, "Run Tests"), " <--"),
             P({style: "float: right;"},
             SMALL(
               "Based on the ",
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -11,16 +11,23 @@
  * Send a mouse event to the node aTarget (aTarget can be an id, or an
  * actual node) . The "event" passed in to aEvent is just a JavaScript
  * object with the properties set that the real mouse event object should
  * have. This includes the type of the mouse event.
  * E.g. to send an click event to the node with id 'node' you might do this:
  *
  * sendMouseEvent({type:'click'}, 'node');
  */
+function getElement(id) {
+  return ((typeof(id) == "string") ?
+    document.getElementById(id) : id); 
+};   
+
+this.$ = this.getElement;
+
 function sendMouseEvent(aEvent, aTarget, aWindow) {
   if (['click', 'mousedown', 'mouseup', 'mouseover', 'mouseout'].indexOf(aEvent.type) == -1) {
     throw new Error("sendMouseEvent doesn't know about event type '"+aEvent.type+"'");
   }
 
   if (!aWindow) {
     aWindow = window;
   }
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/SimpleTest/LogController.js
@@ -0,0 +1,127 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var LogController = {}; //create the logger object
+
+LogController.counter = 0; //current log message number
+LogController.listeners = [];
+LogController.logLevel = {
+    FATAL: 50,
+    ERROR: 40,
+    WARNING: 30,
+    INFO: 20,
+    DEBUG: 10
+};
+
+/* set minimum logging level */
+LogController.logLevelAtLeast = function(minLevel) {
+    if (typeof(minLevel) == 'string') {
+        minLevel = LogController.logLevel[minLevel];
+    }
+    return function (msg) {
+        var msgLevel = msg.level;
+        if (typeof(msgLevel) == 'string') {
+            msgLevel = LogController.logLevel[msgLevel];
+        }
+        return msgLevel >= minLevel;
+    };
+};
+
+/* creates the log message with the given level and info */
+LogController.createLogMessage = function(level, info) {
+    var msg = {};
+    msg.num = LogController.counter;
+    msg.level = level;
+    msg.info = info;
+    msg.timestamp = new Date();
+    return msg;
+};
+
+/* helper method to return a sub-array */
+LogController.extend = function (args, skip) {
+    var ret = [];
+    for (var i = skip; i<args.length; i++) {
+        ret.push(args[i]);
+    }
+    return ret;
+};
+
+/* logs message with given level. Currently used locally by log() and error() */
+LogController.logWithLevel = function(level, message/*, ...*/) {
+    var msg = LogController.createLogMessage(
+        level,
+        LogController.extend(arguments, 1)
+    );
+    LogController.dispatchListeners(msg);
+    LogController.counter += 1;
+};
+
+/* log with level INFO */
+LogController.log = function(message/*, ...*/) {
+    LogController.logWithLevel('INFO', message);
+};
+
+/* log with level ERROR */
+LogController.error = function(message/*, ...*/) {
+    LogController.logWithLevel('ERROR', message);
+};
+
+/* send log message to listeners */
+LogController.dispatchListeners = function(msg) {
+    for (var k in LogController.listeners) {
+        var pair = LogController.listeners[k];
+        if (pair.ident != k || (pair[0] && !pair[0](msg))) {
+            continue;
+        }
+        pair[1](msg);
+    }
+};
+
+/* add a listener to this log given an identifier, a filter (can be null) and the listener object */
+LogController.addListener = function(ident, filter, listener) {
+    if (typeof(filter) == 'string') {
+        filter = LogController.logLevelAtLeast(filter);
+    } else if (filter !== null && typeof(filter) !== 'function') {
+        throw new Error("Filter must be a string, a function, or null");
+    }
+    var entry = [filter, listener];
+    entry.ident = ident;
+    LogController.listeners[ident] = entry;
+};
+
+/* remove a listener from this log */
+LogController.removeListener = function(ident) {
+    delete LogController.listeners[ident];
+};
--- a/testing/mochitest/tests/SimpleTest/Makefile.in
+++ b/testing/mochitest/tests/SimpleTest/Makefile.in
@@ -38,16 +38,17 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = testing/mochitest/tests/SimpleTest
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 _SIMPLETEST_FILES =	MozillaLogger.js \
+			LogController.js \
 			quit.js \
 			SimpleTest.js \
 			test.css \
 			TestRunner.js \
 			setup.js \
 			EventUtils.js \
 			ChromeUtils.js \
 			WindowSnapshot.js \
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -27,16 +27,165 @@ if (parent) {
 // running in e10s build and need to use IPC?
 var ipcMode = false;
 if (parentRunner) {
     ipcMode = parentRunner.ipcMode;
 } else if (typeof SpecialPowers != 'undefined') {
     ipcMode = SpecialPowers.hasContentProcesses();
 }
 
+/* Helper functions pulled out of various MochiKit modules */
+var reprRegistry = [];
+
+if (typeof(repr) == 'undefined') {
+    function repr(o) {
+        if (typeof(o) == "undefined") {
+            return "undefined";
+        } else if (o === null) {
+            return "null";
+        }
+        try {
+            if (typeof(o.__repr__) == 'function') {
+                return o.__repr__();
+            } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
+                return o.repr();
+            }
+            return reprRegistry.match(o);
+        } catch (e) {
+            try {
+                if (typeof(o.NAME) == 'string' && (
+                        o.toString == Function.prototype.toString ||
+                        o.toString == Object.prototype.toString
+                    )) {
+                    return o.NAME;
+                }
+            } catch (e) {
+            }
+        }
+        try {
+            var ostring = (o + "");
+        } catch (e) {
+            return "[" + typeof(o) + "]";
+        }
+        if (typeof(o) == "function") {
+            o = ostring.replace(/^\s+/, "");
+            var idx = o.indexOf("{");
+            if (idx != -1) {
+                o = o.substr(0, idx) + "{...}";
+            }
+        }
+        return ostring;
+    };
+} 
+
+/* This returns a function that applies the previously given parameters.
+ * This is used by SimpleTest.showReport
+ */
+if (typeof(partial) == 'undefined') {
+    function partial(func) {
+        var args = [];
+        for (var i = 1; i < arguments.length; i++) {
+            args.push(arguments[i]);
+        }
+        return function() {
+            if (arguments.length > 0) {
+                for (var i = 1; i < arguments.length; i++) {
+                    args.push(arguments[i]);
+                }
+            }
+            func(args);
+        };
+    };
+}
+
+if (typeof(getElement) == 'undefined') {
+    function getElement(id) {
+        return ((typeof(id) == "string") ?
+            document.getElementById(id) : id); 
+    };
+    this.$ = this.getElement;
+}
+
+SimpleTest._newCallStack = function(path) {
+    var rval = function () {
+        var callStack = arguments.callee.callStack;
+        for (var i = 0; i < callStack.length; i++) {
+            if (callStack[i].apply(this, arguments) === false) {
+                break;
+            }
+        }
+        try {
+            this[path] = null;
+        } catch (e) {
+            // pass
+        }
+    };
+    rval.callStack = [];
+    return rval;
+};
+
+if (typeof(addLoadEvent) == 'undefined') {
+    function addLoadEvent(func) {
+        var existing = window["onload"];
+        var regfunc = existing;
+        if (!(typeof(existing) == 'function'
+                && typeof(existing.callStack) == "object"
+                && existing.callStack !== null)) {
+            regfunc = SimpleTest._newCallStack("onload");
+            if (typeof(existing) == 'function') {
+                regfunc.callStack.push(existing);
+            }
+            window["onload"] = regfunc;
+        }
+        regfunc.callStack.push(func);
+    };
+}
+
+function createEl(type, attrs, html) {
+    //use createElementNS so the xul/xhtml tests have no issues
+    var el;
+    if (!document.body) {
+        el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
+    }
+    else {
+        el = document.createElement(type);
+    }
+    if (attrs !== null && attrs !== undefined) {
+        for (var k in attrs) {
+            el.setAttribute(k, attrs[k]);
+        }
+    }
+    if (html !== null && html !== undefined) {
+        el.appendChild(document.createTextNode(html));
+    }
+    return el;
+}
+
+/* lots of tests use this as a helper to get css properties */
+if (typeof(computedStyle) == 'undefined') {
+    function computedStyle(elem, cssProperty) {
+        elem = getElement(elem);
+        if (elem.currentStyle) {
+            return elem.currentStyle[cssProperty];
+        }
+        if (typeof(document.defaultView) == 'undefined' || document === null) {
+            return undefined;
+        }
+        var style = document.defaultView.getComputedStyle(elem, null);
+        if (typeof(style) == 'undefined' || style === null) {
+            return undefined;
+        }
+        
+        var selectorCase = cssProperty.replace(/([A-Z])/g, '-$1'
+            ).toLowerCase();
+            
+        return style.getPropertyValue(selectorCase);
+    };
+}
+
 /**
  * Check for OOP test plugin
 **/
 SimpleTest.testPluginIsOOP = function () {
     var testPluginIsOOP = false;
     if (navigator.platform.indexOf("Mac") == 0) {
         if (SpecialPowers.XPCOMABI.match(/x86-/)) {
             try {
@@ -71,25 +220,23 @@ SimpleTest.ok = function (condition, nam
     SimpleTest._logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
     SimpleTest._tests.push(test);
 };
 
 /**
  * Roughly equivalent to ok(a==b, name)
 **/
 SimpleTest.is = function (a, b, name) {
-    var repr = MochiKit.Base.repr;
     var pass = (a == b);
     var diag = pass ? repr(a) + " should equal " + repr(b)
                     : "got " + repr(a) + ", expected " + repr(b)
     SimpleTest.ok(pass, name, diag);
 };
 
 SimpleTest.isnot = function (a, b, name) {
-    var repr = MochiKit.Base.repr;
     var pass = (a != b);
     var diag = pass ? repr(a) + " should not equal " + repr(b)
                     : "didn't expect " + repr(a) + ", but got it";
     SimpleTest.ok(pass, name, diag);
 };
 
 //  --------------- Test.Builder/Test.More todo() -----------------
 
@@ -126,108 +273,132 @@ SimpleTest.info = function(name, message
     this._logResult({result:true, name:name, diag:message}, "TEST-INFO");
 };
 
 /**
  * Copies of is and isnot with the call to ok replaced by a call to todo.
 **/
 
 SimpleTest.todo_is = function (a, b, name) {
-    var repr = MochiKit.Base.repr;
     var pass = (a == b);
     var diag = pass ? repr(a) + " should equal " + repr(b)
                     : "got " + repr(a) + ", expected " + repr(b);
     SimpleTest.todo(pass, name, diag);
 };
 
 SimpleTest.todo_isnot = function (a, b, name) {
-    var repr = MochiKit.Base.repr;
     var pass = (a != b);
     var diag = pass ? repr(a) + " should not equal " + repr(b)
                     : "didn't expect " + repr(a) + ", but got it";
     SimpleTest.todo(pass, name, diag);
 };
 
 
 /**
  * Makes a test report, returns it as a DIV element.
 **/
 SimpleTest.report = function () {
-    var DIV = MochiKit.DOM.DIV;
     var passed = 0;
     var failed = 0;
     var todo = 0;
 
     // Report tests which did not actually check anything.
     if (SimpleTest._tests.length == 0)
       // ToDo: Do s/todo/ok/ when all the tests are fixed. (Bug 483407)
       SimpleTest.todo(false, "[SimpleTest.report()] No checks actually run.");
 
-    var results = MochiKit.Base.map(
-        function (test) {
-            var cls, msg;
+    var tallyAndCreateDiv = function (test) {
+            var cls, msg, div;
             var diag = test.diag ? " - " + test.diag : "";
             if (test.todo && !test.result) {
                 todo++;
                 cls = "test_todo";
                 msg = "todo | " + test.name + diag;
             } else if (test.result && !test.todo) {
                 passed++;
                 cls = "test_ok";
                 msg = "passed | " + test.name + diag;
             } else {
                 failed++;
                 cls = "test_not_ok";
                 msg = "failed | " + test.name + diag;
             }
-            return DIV({"class": cls}, msg);
-        },
-        SimpleTest._tests
-    );
+          div = createEl('div', {'class': cls}, msg);
+          return div;
+        };
+    var results = [];
+    for (var d=0; d<SimpleTest._tests.length; d++) {
+        results.push(tallyAndCreateDiv(SimpleTest._tests[d]));
+    }
 
     var summary_class = failed != 0 ? 'some_fail' :
                           passed == 0 ? 'todo_only' : 'all_pass';
 
-    return DIV({'class': 'tests_report'},
-        DIV({'class': 'tests_summary ' + summary_class},
-            DIV({'class': 'tests_passed'}, "Passed: " + passed),
-            DIV({'class': 'tests_failed'}, "Failed: " + failed),
-            DIV({'class': 'tests_todo'}, "Todo: " + todo)),
-        results
-    );
+    var div1 = createEl('div', {'class': 'tests_report'});
+    var div2 = createEl('div', {'class': 'tests_summary ' + summary_class});
+    var div3 = createEl('div', {'class': 'tests_passed'}, 'Passed: ' + passed);
+    var div4 = createEl('div', {'class': 'tests_failed'}, 'Failed: ' + failed);
+    var div5 = createEl('div', {'class': 'tests_todo'}, 'Todo: ' + todo);
+    div2.appendChild(div3);
+    div2.appendChild(div4);
+    div2.appendChild(div5);
+    div1.appendChild(div2);
+    for (var t=0; t<results.length; t++) {
+        //iterate in order
+        div1.appendChild(results[t]);
+    }
+    return div1;
 };
 
 /**
  * Toggle element visibility
 **/
 SimpleTest.toggle = function(el) {
-    if (MochiKit.Style.computedStyle(el, 'display') == 'block') {
+    if (computedStyle(el, 'display') == 'block') {
         el.style.display = 'none';
     } else {
         el.style.display = 'block';
     }
 };
 
 /**
  * Toggle visibility for divs with a specific class.
 **/
 SimpleTest.toggleByClass = function (cls, evt) {
-    var elems = getElementsByTagAndClassName('div', cls);
-    MochiKit.Base.map(SimpleTest.toggle, elems);
+    var children = document.getElementsByTagName('div');
+    var elements = [];
+    for (var i=0; i<children.length; i++) {
+        var child = children[i];
+        var clsName = child.className;
+        if (!clsName) {
+            continue;
+        }    
+        var classNames = clsName.split(' ');
+        for (var j = 0; j < classNames.length; j++) {
+            if (classNames[j] == cls) {
+                elements.push(child);
+                break;
+            }    
+        }    
+    }
+    for (var t=0; t<elements.length; t++) {
+        //TODO: again, for-in loop over elems seems to break this
+        SimpleTest.toggle(elements[t]);
+    }
     if (evt)
         evt.preventDefault();
 };
 
 /**
  * Shows the report in the browser
 **/
 SimpleTest.showReport = function() {
-    var togglePassed = A({'href': '#'}, "Toggle passed checks");
-    var toggleFailed = A({'href': '#'}, "Toggle failed checks");
-    var toggleTodo = A({'href': '#'}, "Toggle todo checks");
+    var togglePassed = createEl('a', {'href': '#'}, "Toggle passed checks");
+    var toggleFailed = createEl('a', {'href': '#'}, "Toggle failed checks");
+    var toggleTodo = createEl('a',{'href': '#'}, "Toggle todo checks");
     togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
     toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
     toggleTodo.onclick = partial(SimpleTest.toggleByClass, 'test_todo');
     var body = document.body;  // Handles HTML documents
     if (!body) {
         // Do the XML thing.
         body = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml",
                                                "body")[0];
@@ -239,23 +410,23 @@ SimpleTest.showReport = function() {
             body.insertBefore(el, firstChild);
         };
     } else {
         addNode = function (el) {
             body.appendChild(el)
         };
     }
     addNode(togglePassed);
-    addNode(SPAN(null, " "));
+    addNode(createEl('span', null, " "));
     addNode(toggleFailed);
-    addNode(SPAN(null, " "));
+    addNode(createEl('span', null, " "));
     addNode(toggleTodo);
     addNode(SimpleTest.report());
     // Add a separator from the test content.
-    addNode(HR());
+    addNode(createEl('hr'));
 };
 
 /**
  * Tells SimpleTest to don't finish the test when the document is loaded,
  * useful for asynchronous tests.
  *
  * When SimpleTest.waitForExplicitFinish is called,
  * explicit SimpleTest.finish() is required.
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -1,14 +1,21 @@
 /*
  * e10s event dispatcher from content->chrome
  *
  * type = eventName (QuitApplication, LoggerInit, LoggerClose, Logger, GetPref, SetPref)
  * data = json object {"filename":filename} <- for LoggerInit
  */
+function getElement(id) {
+    return ((typeof(id) == "string") ?
+        document.getElementById(id) : id); 
+};   
+
+this.$ = this.getElement;
+
 function contentDispatchEvent(type, data, sync) {
   if (typeof(data) == "undefined") {
     data = {};
   }
 
   var element = document.createEvent("datacontainerevent");
   element.initEvent("contentEvent", true, false);
   element.setData("sync", sync);
@@ -20,16 +27,49 @@ function contentDispatchEvent(type, data
 function contentSyncEvent(type, data) {
   contentDispatchEvent(type, data, 1);
 }
 
 function contentAsyncEvent(type, data) {
   contentDispatchEvent(type, data, 0);
 }
 
+/* Helper Function */
+function extend(obj, /* optional */skip) {        
+    // Extend an array with an array-like object starting
+    // from the skip index
+    if (!skip) {
+        skip = 0;
+    }
+    if (obj) {
+        var l = obj.length;
+        var ret = [];
+        for (var i = skip; i < l; i++) {
+            ret.push(obj[i]);
+        }
+    }
+    return ret;
+};
+
+function flattenArguments(lst/* ...*/) {
+    var res = [];
+    var args = extend(arguments);
+    while (args.length) {
+        var o = args.shift();
+        if (o && typeof(o) == "object" && typeof(o.length) == "number") {
+            for (var i = o.length - 1; i >= 0; i--) {
+                args.unshift(o[i]);
+            }
+        } else {
+            res.push(o);
+        }
+    }
+    return res;
+};
+
 /**
  * TestRunner: A test runner for SimpleTest
  * TODO:
  *
  *  * Avoid moving iframes: That causes reloads on mozilla and opera.
  *
  *
 **/
@@ -73,17 +113,17 @@ TestRunner._checkForHangs = function() {
       }
 
       frameWindow.SimpleTest.finish();
 
       if (TestRunner._haltTests)
         return;
     }
 
-    TestRunner.deferred = callLater(30, TestRunner._checkForHangs);
+    setTimeout(TestRunner._checkForHangs, 30000);
   }
 }
 
 TestRunner.requestLongerTimeout = function(factor) {
     TestRunner._timeoutFactor = factor;
 }
 
 /**
@@ -95,17 +135,17 @@ TestRunner._currentLoop = 0;
 /**
  * This function is called after generating the summary.
 **/
 TestRunner.onComplete = null;
 
 /**
  * If logEnabled is true, this is the logger that will be used.
 **/
-TestRunner.logger = MochiKit.Logging.logger;
+TestRunner.logger = LogController;
 
 TestRunner.log = function(msg) {
     if (TestRunner.logEnabled) {
         TestRunner.logger.log(msg);
     } else {
         dump(msg + "\n");
     }
 };
--- a/testing/mochitest/tests/SimpleTest/setup.js
+++ b/testing/mochitest/tests/SimpleTest/setup.js
@@ -32,17 +32,56 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 TestRunner.logEnabled = true;
-TestRunner.logger = new Logger();
+TestRunner.logger = LogController;
+
+/* Helper function */
+parseQueryString = function(encodedString, useArrays) {
+  // strip a leading '?' from the encoded string
+  var qstr = (encodedString[0] == "?") ? encodedString.substring(1) : 
+                                         encodedString;
+  var pairs = qstr.replace(/\+/g, "%20").split(/(\&amp\;|\&\#38\;|\&#x26;|\&)/);
+  var o = {};
+  var decode;
+  if (typeof(decodeURIComponent) != "undefined") {
+    decode = decodeURIComponent;
+  } else {
+    decode = unescape;
+  }
+  if (useArrays) {
+    for (var i = 0; i < pairs.length; i++) {
+      var pair = pairs[i].split("=");
+      if (pair.length !== 2) {
+        continue;
+      }
+      var name = decode(pair[0]);
+      var arr = o[name];
+      if (!(arr instanceof Array)) {
+        arr = [];
+        o[name] = arr;
+      }
+      arr.push(decode(pair[1]));
+    }
+  } else {
+    for (i = 0; i < pairs.length; i++) {
+      pair = pairs[i].split("=");
+      if (pair.length !== 2) {
+        continue;
+      }
+      o[decode(pair[0])] = decode(pair[1]);
+    }
+  }
+  return o;
+};
 
 // Check the query string for arguments
 var params = parseQueryString(location.search.substring(1), true);
 
 var config = {};
 if (window.readConfig) {
   config = readConfig();
 }
@@ -190,28 +229,28 @@ function makeInvisible(elem) {
 function isVisible(elem) {
     // you may also want to check for
     // getElement(elem).style.display == "none"
     return !hasElementClass(elem, "invisible");
 };
 
 function toggleNonTests (e) {
   e.preventDefault();
-  var elems = getElementsByTagAndClassName("*", "non-test");
+  var elems = document.getElementsClassName("non-test");
   for (var i="0"; i<elems.length; i++) {
     toggleVisible(elems[i]);
   }
   if (isVisible(elems[0])) {
     $("toggleNonTests").innerHTML = "Hide Non-Tests";
   } else {
     $("toggleNonTests").innerHTML = "Show Non-Tests";
   }
 }
 
 // hook up our buttons
 function hookup() {
-  connect("runtests", "onclick", RunSet, "reloadAndRunAll");
-  connect("toggleNonTests", "onclick", toggleNonTests);
+  document.getElementById('runtests').onclick = RunSet.reloadAndRunAll;
+  document.getElementById('toggleNonTests').onclick = toggleNonTests; 
   // run automatically if autorun specified
   if (params.autorun) {
     RunSet.runall();
   }
 }