Merging to tip. a=blocking-b7
authorMounir Lamouri <mounir.lamouri@gmail.com>
Thu, 30 Sep 2010 17:10:19 -0700
changeset 54825 b343269c3aa4d72582a07b237352417943922c45
parent 54824 4ace6b349a3cae691204e3e740c807ef4d9faad8
child 54826 669eb2d837d700b21d5f3634759f568efa276a9f
push id16042
push usermlamouri@mozilla.com
push dateFri, 01 Oct 2010 00:12:59 +0000
treeherdermozilla-central@669eb2d837d7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblocking-b7
milestone2.0b7pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merging to tip. a=blocking-b7
Makefile.in
accessible/tests/mochitest/events/test_scroll.xul
accessible/tests/mochitest/test_value.html
browser/base/content/test/browser_bug561636.js
browser/base/content/test/browser_tab_dragdrop2.js
browser/components/preferences/tests/browser_privacypane_1.js
browser/components/preferences/tests/browser_privacypane_2.js
browser/components/preferences/tests/browser_privacypane_3.js
browser/components/preferences/tests/browser_privacypane_4.js
browser/components/preferences/tests/browser_privacypane_5.js
browser/components/preferences/tests/browser_privacypane_6.js
browser/components/preferences/tests/browser_privacypane_7.js
browser/components/preferences/tests/browser_privacypane_8.js
build/macosx/universal/flight.mk
build/mobile/sutagent/android/ASMozStub.java
build/mobile/sutagent/android/AndroidManifest.xml
build/mobile/sutagent/android/DataWorkerThread.java
build/mobile/sutagent/android/DoCommand.java
build/mobile/sutagent/android/RunDataThread.java
build/mobile/sutagent/android/SUTAgentAndroid.java
content/base/src/nsGkAtomList.h
content/html/content/src/nsIConstraintValidation.cpp
content/html/content/test/Makefile.in
content/html/content/test/test_bug600155.html
dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
dom/tests/mochitest/whatwg/test_postMessage_chrome.html
layout/generic/test/file_bug514732_window.xul
layout/generic/test/test_bug514732-2.xul
modules/libpr0n/test/browser/head.js
testing/mochitest/Makefile.in
testing/mochitest/browser-harness.xul
testing/mochitest/chrome-harness.js
testing/mochitest/harness-overlay.xul
testing/mochitest/install.rdf
testing/mochitest/jar.mn
testing/mochitest/runtests.py.in
testing/mochitest/server.js
testing/mochitest/tests/SimpleTest/Makefile.in
testing/testsuite-targets.mk
toolkit/content/tests/chrome/rtlchrome/rtl.manifest
toolkit/crashreporter/test/browser/browser_aboutCrashes.js
toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js
toolkit/crashreporter/test/browser/browser_bug471404.js
xpinstall/tests/browser_auth.js
xpinstall/tests/browser_auth2.js
xpinstall/tests/browser_auth3.js
xpinstall/tests/browser_badhash.js
xpinstall/tests/browser_badhashtype.js
xpinstall/tests/browser_bug540558.js
xpinstall/tests/browser_cancel.js
xpinstall/tests/browser_chrome.js
xpinstall/tests/browser_cookies.js
xpinstall/tests/browser_cookies2.js
xpinstall/tests/browser_cookies3.js
xpinstall/tests/browser_cookies4.js
xpinstall/tests/browser_corrupt.js
xpinstall/tests/browser_empty.js
xpinstall/tests/browser_enabled.js
xpinstall/tests/browser_enabled2.js
xpinstall/tests/browser_enabled3.js
xpinstall/tests/browser_hash.js
xpinstall/tests/browser_installchrome.js
xpinstall/tests/browser_localfile.js
xpinstall/tests/browser_localfile2.js
xpinstall/tests/browser_navigateaway.js
xpinstall/tests/browser_navigateaway2.js
xpinstall/tests/browser_offline.js
xpinstall/tests/browser_opendialog.js
xpinstall/tests/browser_signed_multiple.js
xpinstall/tests/browser_signed_naming.js
xpinstall/tests/browser_signed_tampered.js
xpinstall/tests/browser_signed_trigger.js
xpinstall/tests/browser_signed_untrusted.js
xpinstall/tests/browser_signed_url.js
xpinstall/tests/browser_softwareupdate.js
xpinstall/tests/browser_unsigned_trigger.js
xpinstall/tests/browser_unsigned_url.js
xpinstall/tests/browser_whitelist.js
xpinstall/tests/browser_whitelist2.js
xpinstall/tests/browser_whitelist3.js
xpinstall/tests/browser_whitelist4.js
xpinstall/tests/browser_whitelist5.js
xpinstall/tests/browser_whitelist6.js
xpinstall/tests/harness.js
--- a/Makefile.in
+++ b/Makefile.in
@@ -115,19 +115,16 @@ config.status: $(topsrcdir)/configure
 export::
 	$(RM) -rf $(DIST)/sdk
 	$(MAKE) -C config export
 	$(MAKE) tier_nspr
 
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
-else
-# OS X Universal builds will want to call this, so stub it out
-package-tests:
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 distclean::
 	cat unallmakefiles | $(XARGS) rm -f
 	rm -f unallmakefiles $(DIST_GARBAGE)
 
--- a/accessible/tests/mochitest/events/test_scroll.xul
+++ b/accessible/tests/mochitest/events/test_scroll.xul
@@ -68,20 +68,20 @@
       /*
        * When tests are packed in a .jar, we need to extract them so we 
        * can access the specific url with a file:// protocol which appears
        * to be required by loadURI() (at least a file without an embedded .jar)
        */
       var jar = getJar(rootDir);
       if (jar) {
         var tmpdir = extractJarToTmp(jar);
-        rootDir = "file://" + tmpdir.path;
+        rootDir = "file://" + tmpdir.path + '/';
       }
 
-      var url = rootDir + "/scroll.html#link1";
+      var url = rootDir + "scroll.html#link1";
       var tabBrowser = document.getElementById("tabBrowser");
       tabBrowser.loadURI(url);
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
--- a/accessible/tests/mochitest/test_value.html
+++ b/accessible/tests/mochitest/test_value.html
@@ -34,17 +34,17 @@
       {
         var acc = getAccessible(aID);
         if (!acc)
           return;
         is(acc.value, aValue, "Wrong value for " + aID + "!");
       }
 
       var rootDir = getRootDirectory(window.location.href);
-      var href = rootDir.path + "/foo";
+      var href = rootDir.path + "foo";
 
       // roles that can't live as nsHTMLLinkAccessibles
       testValue("aria_menuitem_link", "");
       testValue("aria_button_link", "");
       testValue("aria_checkbox_link", "");
       testValue("aria_application_link", "");
 
       // roles that can live as nsHTMLLinkAccessibles
--- a/browser/base/content/test/browser_bug561636.js
+++ b/browser/base/content/test/browser_bug561636.js
@@ -350,25 +350,60 @@ function test9()
       checkPopupHide();
 
       // Clean-up
       Services.obs.removeObserver(gObserver, "invalidformsubmit");
       gObserver.notifyInvalidSubmit = function () {};
       gBrowser.removeTab(tab, {animate: false});
 
       // Next test
-      executeSoon(finish);
+      executeSoon(test10);
     });
   };
 
   Services.obs.addObserver(gObserver, "invalidformsubmit", false);
 
   tab.linkedBrowser.addEventListener("load", function(aEvent) {
     tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
 
     isnot(gBrowser.selectedTab, tab,
           "This tab should have been loaded in background");
 
     tab.linkedBrowser.contentDocument.getElementById('s').click();
   }, true);
 
   tab.linkedBrowser.loadURI(uri);
 }
+
+/**
+ * In this test, we check that the author defined error message is shown.
+ */
+function test10()
+{
+  let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input x-moz-errormessage='foo' required id='i'><input id='s' type='submit'></form>";
+  let tab = gBrowser.addTab();
+
+  gInvalidFormPopup.addEventListener("popupshown", function() {
+    gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false);
+
+    let doc = gBrowser.contentDocument;
+    is(doc.activeElement, doc.getElementById('i'),
+       "First invalid element should be focused");
+
+    checkPopupShow();
+
+    is(gInvalidFormPopup.firstChild.nodeValue, "foo",
+       "The panel should show the author defined error message");
+
+    // Clean-up and next test.
+    gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
+    executeSoon(finish);
+  }, false);
+
+  tab.linkedBrowser.addEventListener("load", function(aEvent) {
+    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+
+    gBrowser.contentDocument.getElementById('s').click();
+  }, true);
+
+  gBrowser.selectedTab = tab;
+  gBrowser.selectedTab.linkedBrowser.loadURI(uri);
+}
--- a/browser/base/content/test/browser_tab_dragdrop2.js
+++ b/browser/base/content/test/browser_tab_dragdrop2.js
@@ -6,18 +6,18 @@ function test()
   var level2 = false;
   function test1() {
     // Load the following URI (which runs some child popup tests) in a new window (B),
     // then add a blank tab to B and call replaceTabWithWindow to detach the URI tab
     // into yet a new window (C), then close B.
     // Now run the tests again and then close C.
     // The test results does not matter, all this is just to exercise some code to
     // catch assertions or crashes.
-    var uri = "chrome://mochikit/content/browser/" +
-              "browser/base/content/test/browser_tab_dragdrop2_frame1.xul";
+    var chromeroot = getRootDirectory(gTestPath);
+    var uri = chromeroot + "browser_tab_dragdrop2_frame1.xul";
     let window_B = openDialog(location, "_blank", "chrome,all,dialog=no,left=200,top=200,width=200,height=200", uri);
     window_B.addEventListener("load", function(aEvent) {
       window_B.removeEventListener("load", arguments.callee, false);
       if (level1) return; level1=true;
       executeSoon(function () {
         window_B.gBrowser.addEventListener("load", function(aEvent) {
           window_B.removeEventListener("load", arguments.callee, true);
           if (level2) return; level2=true;
--- a/browser/components/preferences/tests/browser_privacypane_1.js
+++ b/browser/components/preferences/tests/browser_privacypane_1.js
@@ -38,19 +38,19 @@
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
 
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_pane_visibility,
     test_dependent_elements,
     test_dependent_cookie_elements,
     test_dependent_clearonclose_elements,
     test_dependent_prefs,
 
--- a/browser/components/preferences/tests/browser_privacypane_2.js
+++ b/browser/components/preferences/tests/browser_privacypane_2.js
@@ -38,19 +38,19 @@
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
 
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_historymode_retention("remember", undefined),
     test_historymode_retention("dontremember", "remember"),
     test_historymode_retention("custom", "dontremember"),
     // custom without any micro-prefs changed won't retain
     test_historymode_retention("remember", "dontremember"),
     test_historymode_retention("custom", "remember"),
--- a/browser/components/preferences/tests/browser_privacypane_3.js
+++ b/browser/components/preferences/tests/browser_privacypane_3.js
@@ -37,19 +37,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_custom_retention("rememberHistory", "remember"),
     test_custom_retention("rememberHistory", "custom"),
     test_custom_retention("rememberDownloads", "remember"),
     test_custom_retention("rememberDownloads", "custom"),
     test_custom_retention("rememberForms", "remember"),
     test_custom_retention("rememberForms", "custom"),
--- a/browser/components/preferences/tests/browser_privacypane_4.js
+++ b/browser/components/preferences/tests/browser_privacypane_4.js
@@ -37,19 +37,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_custom_retention("acceptCookies", "remember"),
     test_custom_retention("acceptCookies", "custom"),
     test_custom_retention("acceptThirdParty", "remember"),
     test_custom_retention("acceptThirdParty", "custom"),
     test_custom_retention("keepCookiesUntil", "remember", 1),
     test_custom_retention("keepCookiesUntil", "custom", 2),
--- a/browser/components/preferences/tests/browser_privacypane_5.js
+++ b/browser/components/preferences/tests/browser_privacypane_5.js
@@ -37,19 +37,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_locbar_suggestion_retention(-1, undefined),
     test_locbar_suggestion_retention(1, -1),
     test_locbar_suggestion_retention(2, 1),
     test_locbar_suggestion_retention(0, 2),
     test_locbar_suggestion_retention(0, 0),
 
--- a/browser/components/preferences/tests/browser_privacypane_6.js
+++ b/browser/components/preferences/tests/browser_privacypane_6.js
@@ -37,19 +37,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_privatebrowsing_toggle,
     enter_private_browsing, // once again, test with PB initially enabled
     test_privatebrowsing_toggle,
 
     // don't reset preferences, will pick up where we left off in browser_privacypane_7.js
   ]);
--- a/browser/components/preferences/tests/browser_privacypane_7.js
+++ b/browser/components/preferences/tests/browser_privacypane_7.js
@@ -37,19 +37,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     test_privatebrowsing_ui,
     enter_private_browsing, // once again, test with PB initially enabled
     test_privatebrowsing_ui,
 
     // reset all preferences to their default values once we're done
     reset_preferences
--- a/browser/components/preferences/tests/browser_privacypane_8.js
+++ b/browser/components/preferences/tests/browser_privacypane_8.js
@@ -36,19 +36,19 @@
 
 function test() {
   let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                getService(Ci.mozIJSSubScriptLoader);
   let rootDir = getRootDirectory(gTestPath);
   let jar = getJar(rootDir);
   if (jar) {
     let tmpdir = extractJarToTmp(jar);
-    rootDir = "file://" + tmpdir.path;
+    rootDir = "file://" + tmpdir.path + '/';
   }
-  loader.loadSubScript(rootDir + "/privacypane_tests.js", this);
+  loader.loadSubScript(rootDir + "privacypane_tests.js", this);
 
   run_test_subset([
     // history mode should be initialized to remember
     test_historymode_retention("remember", undefined),
 
     // history mode should remain remember; toggle acceptCookies checkbox
     test_custom_retention("acceptCookies", "remember"),
 
--- a/build/macosx/universal/flight.mk
+++ b/build/macosx/universal/flight.mk
@@ -116,18 +116,18 @@ postflight_all:
           --unify-with-sort "\.manifest$$" \
           --unify-with-sort "components\.list$$" \
 	  $(DIST_ARCH_1)/$(MOZ_PKG_APPNAME)/$(APPNAME) \
 	  $(DIST_ARCH_2)/$(MOZ_PKG_APPNAME)/$(APPNAME) \
 	  $(DIST_UNI)/$(MOZ_PKG_APPNAME)/$(APPNAME)
 # A universal .dmg can now be produced by making in either architecture's
 # INSTALLER_DIR.
 # Now, repeat the process for the test package.
-	$(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= package-tests
-	$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= package-tests
+	$(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests
+	$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests
 	rm -rf $(DIST_UNI)/test-package-stage
 # automation.py differs because it hardcodes a path to
 # dist/bin. It doesn't matter which one we use.
 	if test -d $(DIST_ARCH_1)/test-package-stage -a                 \
                 -d $(DIST_ARCH_2)/test-package-stage; then              \
            cp $(DIST_ARCH_1)/test-package-stage/mochitest/automation.py \
              $(DIST_ARCH_2)/test-package-stage/mochitest/;              \
            cp $(DIST_ARCH_1)/test-package-stage/reftest/automation.py   \
--- a/build/mobile/sutagent/android/ASMozStub.java
+++ b/build/mobile/sutagent/android/ASMozStub.java
@@ -106,9 +106,17 @@ public class ASMozStub extends android.a
 		
 		NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
 		notificationManager.cancel(1959);
 		
 		Toast.makeText(this, "Listener Service destroyed...", Toast.LENGTH_LONG).show();
 		
 		System.exit(0);
 		}
+	
+	public void SendToDataChannel(String strToSend)
+		{
+		if (runDataThrd.isAlive())
+			{
+			runDataThrd.SendToDataChannel(strToSend);
+			}
+		}
 }
--- a/build/mobile/sutagent/android/AndroidManifest.xml
+++ b/build/mobile/sutagent/android/AndroidManifest.xml
@@ -1,15 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.mozilla.SUTAgentAndroid"
       android:versionCode="1"
       android:versionName="1.0" android:sharedUserId="org.mozilla.sharedID">
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
         <activity android:name=".SUTAgentAndroid"
+                  android:screenOrientation="nosensor"
                   android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <receiver android:name=".SUTStartupIntentReceiver">
             <intent-filter>
@@ -20,17 +21,17 @@
         <service android:name=".service.ASMozStub">
 		    <intent-filter>
 			    <action android:name="com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE" />
 		    </intent-filter>
 	    </service>
 
     </application>
     
-    <uses-sdk android:minSdkVersion="5"/>
+    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="8"/>
 
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 <uses-permission android:name="android.permission.REBOOT"></uses-permission>
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
 <uses-permission android:name="android.permission.RESTART_PACKAGES"></uses-permission>
@@ -54,9 +55,14 @@
 
 
 
 
 <uses-permission android:name="android.permission.STATUS_BAR"></uses-permission>
 
 <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
 
+
+
+<uses-permission android:name="android.permission.SET_TIME"></uses-permission>
+
+
 </manifest> 
\ No newline at end of file
--- a/build/mobile/sutagent/android/DataWorkerThread.java
+++ b/build/mobile/sutagent/android/DataWorkerThread.java
@@ -50,28 +50,44 @@ import java.util.Calendar;
 // import com.mozilla.SUTAgentAndroid.DoCommand;
 import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
 
 public class DataWorkerThread extends Thread
 {
 	private RunDataThread theParent = null;
 	private Socket socket	= null;
 	boolean bListening	= true;
+	PrintWriter out = null;
+	SimpleDateFormat sdf = null;
 
 	public DataWorkerThread(RunDataThread theParent, Socket workerSocket)
 		{
 		super("DataWorkerThread");
 		this.theParent = theParent;
 		this.socket = workerSocket;
+		this.sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
 		}
 
 	public void StopListening()
 		{
 		bListening = false;
 		}
+	
+	public void SendString(String strToSend)
+		{
+		if (this.out != null)
+			{
+			Calendar cal = Calendar.getInstance();
+			String strOut = sdf.format(cal.getTime());
+			strOut += " " + strToSend + "\r\n";
+		
+			out.write(strOut);
+			out.flush();
+			}
+		}
 
 	private String readLine(BufferedInputStream in)
 		{
 		String sRet = "";
 		int nByte = 0;
 		char cChar = 0;
 	
 		try 
@@ -130,23 +146,22 @@ public class DataWorkerThread extends Th
 		String	sRet = "";
 		long lEndTime = System.currentTimeMillis() + 60000;
 		
 		try {
 			while(bListening)
 				{
 				OutputStream cmdOut = socket.getOutputStream();
 				InputStream cmdIn = socket.getInputStream();
-				PrintWriter out = new PrintWriter(cmdOut, true);
+				this.out = new PrintWriter(cmdOut, true);
 				BufferedInputStream in = new BufferedInputStream(cmdIn);
 				String inputLine, outputLine;
 				DoCommand dc = new DoCommand(theParent.svc);
 				
 	    		Calendar cal = Calendar.getInstance();
-	    		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
 	    		sRet = sdf.format(cal.getTime());
 	    		sRet += " trace output";
 
 				out.println(sRet);
 				out.flush();
 				int nAvail = cmdIn.available();
 				cmdIn.skip(nAvail);
 				
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -55,17 +55,19 @@ import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.List;
+import java.util.TimeZone;
 import java.util.Timer;
 import java.util.zip.Adler32;
 import java.util.zip.CheckedInputStream;
 import java.util.zip.CheckedOutputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
@@ -90,16 +92,17 @@ import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.StatFs;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.WindowManager;
 
 public class DoCommand {
@@ -108,31 +111,32 @@ public class DoCommand {
 	Process	pProc;
 	OutputStream sutIn;
 	InputStream	sutErr;
 	InputStream	sutOut;
 	AlertLooperThread alrt = null;
 	ContextWrapper	contextWrapper = null;
 	
 	String	currentDir = "/";
-	String	sErrorPrefix = "##AGENT-ERROR## ";
+	String	sErrorPrefix = "##AGENT-WARNING## ";
 	
-	private final String prgVersion = "SUTAgentAndroid Version 0.80";
+	private final String prgVersion = "SUTAgentAndroid Version 0.85";
 	
 	public enum Command
 		{
 		RUN ("run"),
 		EXEC ("exec"),
 		ARUN ("arun"),
 		KILL ("kill"),
 		PS ("ps"),
 		DEVINFO ("info"),
 		OS ("os"),
 		ID ("id"),
 		UPTIME ("uptime"),
+		SETTIME ("settime"),
 		SYSTIME ("systime"),
 		SCREEN ("screen"),
 		MEMORY ("memory"),
 		POWER ("power"),
 		PROCESS ("process"),
 		GETAPPROOT ("getapproot"),
 		TESTROOT ("testroot"),
 		ALRT ("alrt"),
@@ -210,20 +214,28 @@ public class DoCommand {
 		cCmd = Command.getCmd(Argv[0]);
 		
 		switch(cCmd)
 			{
 			case VER:
 				strReturn = prgVersion;
 				break;
 				
+			case CLOK:
+				strReturn = GetClok();
+				break;
+				
 			case UPDT:
 				strReturn = StartUpdateOMatic(Argv[1], Argv[2]);
 				break;
 			
+			case SETTIME:
+				strReturn = SetSystemTime(Argv[1], Argv[2], cmdOut);
+				break;
+			
 			case CWD:
 				try {
 					strReturn = new java.io.File(currentDir).getCanonicalPath();
 					} 
 				catch (IOException e)
 					{
 					e.printStackTrace();
 					}
@@ -239,17 +251,17 @@ public class DoCommand {
 			case LS:
 				strReturn = PrintDir(((Argc > 1) ? Argv[1] : currentDir));
 				break;
 				
 			case GETAPPROOT:
 				if (Argc == 2)
 					strReturn = GetAppRoot(Argv[1]);
 				else
-					strReturn = sErrorPrefix + "Wrong number of arguments for cd command!";
+					strReturn = sErrorPrefix + "Wrong number of arguments for getapproot command!";
 				break;
 				
 			case TESTROOT:
 				strReturn = GetTestRoot();
 				break;
 				
 			case DEAD:
 				if (Argc == 2)
@@ -1924,16 +1936,94 @@ public class DoCommand {
 		String sRet = "";
 		Calendar cal = Calendar.getInstance();
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
 		sRet = sdf.format(cal.getTime());
 	
 		return (sRet);
 		}
 	
+	public String SetSystemTime(String sDate, String sTime, OutputStream out)
+		{
+//		Debug.waitForDebugger();
+		String sRet = "";
+		
+//		Intent	prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS);
+//		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//		contextWrapper.startActivity(prgIntent);
+		
+		// 2010/09/22 
+		// 15:41:00
+		// 0123456789012345678
+		
+		if (((sDate != null) && (sTime != null)) && 
+			(sDate.contains("/") || sDate.contains(".")) &&
+			(sTime.contains(":")))
+			{
+			int year = Integer.parseInt(sDate.substring(0,4));
+			int month = Integer.parseInt(sDate.substring(5,7));
+			int day = Integer.parseInt(sDate.substring(8,10));
+			
+			int hour = Integer.parseInt(sTime.substring(0,2));
+			int mins = Integer.parseInt(sTime.substring(3,5));
+			int secs = Integer.parseInt(sTime.substring(6,8));
+
+			Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+			cal.set(year, month - 1, day, hour, mins, secs);
+			long lMillisecs = cal.getTime().getTime();
+			
+//			boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs);
+			String sM = Long.toString(lMillisecs);
+//			long lm = 1285175618316L;
+			String sTest = cal.getTime().toGMTString();
+			String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3);
+			String [] theArgs = new String [3];
+		
+			theArgs[0] = "su";
+			theArgs[1] = "-c";
+			theArgs[2] = "date -u " + sMillis;
+		
+			try 
+				{
+				pProc = Runtime.getRuntime().exec(theArgs);
+				RedirOutputThread outThrd = new RedirOutputThread(pProc, null);
+				outThrd.start();
+				outThrd.join(10000);
+				sRet = GetSystemTime();
+				}
+			catch (IOException e) 
+				{
+				sRet = e.getMessage();
+				e.printStackTrace();
+				} 
+			catch (InterruptedException e)
+				{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+				}
+			}
+		else
+			{
+			sRet = "Invalid argument(s)";
+			}
+
+		return (sRet);
+		}
+
+	public String GetClok()
+		{
+		long lMillisecs = System.currentTimeMillis();
+		String sRet = "";
+		
+		if (lMillisecs > 0)
+			sRet = Long.toString(lMillisecs);
+		
+		return(sRet);
+		}
+	
 	public String GetUptime()
 		{
 		String sRet = "";
 		long lHold = 0;
 		long lUptime = SystemClock.elapsedRealtime();
 		int	nDays = 0;
 		int	nHours = 0;
 		int nMinutes = 0;
@@ -2135,16 +2225,19 @@ public class DoCommand {
 		String [] theArgs = new String [3];
 	
 		theArgs[0] = "su";
 		theArgs[1] = "-c";
 		theArgs[2] = "reboot";
 	
 		try 
 			{
+			// Tell all of the data channels we are rebooting
+			((ASMozStub)this.contextWrapper).SendToDataChannel("Rebooting ...");
+			
 			pProc = Runtime.getRuntime().exec(theArgs);
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(10000);
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
@@ -2546,16 +2639,19 @@ public class DoCommand {
 			"ls                       - print directory on device\n" +
 			"tmpd                     - print temp directory on device\n" +
 			"ping [hostname/ipaddr]   - ping a network device\n" +
 			"unzp zipfile destdir     - unzip the zipfile into the destination dir\n" +
 			"zip zipfile src          - zip the source file/dir into zipfile\n" +
 			"rebt                     - reboot device\n" +
 			"inst /path/filename.apk  - install the referenced apk file\n" +
 			"uninst packagename       - uninstall the referenced package\n" +
+			"updt pkgname pkgfile     - unpdate the referenced package\n" +
+			"clok                     - the current device time expressed as the number of millisecs since epoch\n" +
+			"settime date time        - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
 			"rebt                     - reboot device\n" +
 			"quit                     - disconnect SUTAgent\n" +
 			"exit                     - close SUTAgent\n" +
 			"ver                      - SUTAgent version\n" +
 			"help                     - you're reading it";
 		return (sRet);
 		}
 }
--- a/build/mobile/sutagent/android/RunDataThread.java
+++ b/build/mobile/sutagent/android/RunDataThread.java
@@ -61,16 +61,29 @@ public class RunDataThread extends Threa
 		this.SvrSocket = socket;
 		this.svc = service;
 		}
 	
 	public void StopListening()
 		{
 		bListening = false;
 		}
+	
+	public void SendToDataChannel(String strToSend)
+		{
+		int nNumWorkers = theWorkers.size();
+		for (int lcv = 0; lcv < nNumWorkers; lcv++)
+			{
+			if (theWorkers.get(lcv).isAlive())
+				{
+				theWorkers.get(lcv).SendString(strToSend);
+				}
+			}
+		return;
+		}
 
 	public void run() {
 		try {
 			SvrSocket.setSoTimeout(5000);
 			while (bListening)
 				{
 				try 
 					{
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -60,16 +60,17 @@ import android.content.IntentFilter;
 import android.net.Uri;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.BatteryManager;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.PowerManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -128,17 +129,19 @@ public class SUTAgentAndroid extends Act
 		}
     
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState)
     	{
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
-        
+
+//        Debug.waitForDebugger();
+
 //        long lHeapSize = VMRuntime.getRuntime().getMinimumHeapSize();
 //        lHeapSize = 16000000;
 //        VMRuntime.getRuntime().setMinimumHeapSize(lHeapSize);
         
         // Keep phone from locking or remove lock on screen
         KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
         if (km != null)
         	{
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -582,16 +582,17 @@ GK_ATOM(modifiers, "modifiers")
 GK_ATOM(monochrome, "monochrome")
 GK_ATOM(mousedown, "mousedown")
 GK_ATOM(mousemove, "mousemove")
 GK_ATOM(mouseout, "mouseout")
 GK_ATOM(mouseover, "mouseover")
 GK_ATOM(mousethrough, "mousethrough")
 GK_ATOM(mouseup, "mouseup")
 GK_ATOM(moz_opaque, "moz-opaque")
+GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
 GK_ATOM(msthemecompatible, "msthemecompatible")
 GK_ATOM(multicol, "multicol")
 GK_ATOM(multiple, "multiple")
 GK_ATOM(name, "name")
 GK_ATOM(_namespace, "namespace")
 GK_ATOM(namespaceAlias, "namespace-alias")
 GK_ATOM(namespaceUri, "namespace-uri")
 GK_ATOM(NaN, "NaN")
--- a/content/html/content/src/nsIConstraintValidation.cpp
+++ b/content/html/content/src/nsIConstraintValidation.cpp
@@ -73,17 +73,26 @@ nsIConstraintValidation::GetValidity(nsI
 }
 
 NS_IMETHODIMP
 nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage)
 {
   aValidationMessage.Truncate();
 
   if (IsCandidateForConstraintValidation() && !IsValid()) {
-    if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
+    nsCOMPtr<nsIContent> content = do_QueryInterface(this);
+    NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
+
+    nsAutoString authorMessage;
+    content->GetAttr(kNameSpaceID_None, nsGkAtoms::x_moz_errormessage,
+                     authorMessage);
+
+    if (!authorMessage.IsEmpty()) {
+      aValidationMessage.Assign(authorMessage);
+    } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
       aValidationMessage.Assign(mCustomValidity);
     } else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) {
       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG);
     } else if (GetValidityState(VALIDITY_STATE_VALUE_MISSING)) {
       GetValidationMessage(aValidationMessage, VALIDITY_STATE_VALUE_MISSING);
     } else if (GetValidityState(VALIDITY_STATE_TYPE_MISMATCH)) {
       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TYPE_MISMATCH);
     } else if (GetValidityState(VALIDITY_STATE_PATTERN_MISMATCH)) {
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -225,12 +225,13 @@ include $(topsrcdir)/config/rules.mk
 		test_bug595449.html \
 		test_bug595457.html \
 		test_bug557087-1.html \
 		test_bug557087-2.html \
 		test_bug557087-3.html \
 		test_bug557087-4.html \
 		test_bug557087-5.html \
 		test_bug557087-6.html \
+		test_bug600155.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug600155.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=600155
+-->
+<head>
+  <title>Test for Bug 600155</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=600155">Mozilla Bug 600155</a>
+<p id="display"></p>
+<div id='content' style='display:none;'>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 600155 **/
+
+var subjectForConstraintValidation = [ "button", "input", "select", "textarea" ];
+var content = document.getElementById('content');
+
+for each (var eName in subjectForConstraintValidation) {
+  var e = document.createElement(eName);
+  content.appendChild(e);
+  e.setAttribute("x-moz-errormessage", "foo");
+  if ("required" in e) {
+    e.required = true;
+  } else {
+    e.setCustomValidity("bar");
+  }
+
+  // At this point, the element is invalid.
+  is(e.validationMessage, "foo",
+     "the validation message should be the author one");
+
+  content.removeChild(e);
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
+++ b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
@@ -1,32 +1,39 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>postMessage chrome message receiver</title>
   <script type="application/javascript">
+    var gPrePath = "";
+
     function receiveMessage(evt)
     {
-      // Content cannot post to chrome without privileges
-      window.parent.postMessage("SHOULD NOT GET THIS!", "*");
+      if (evt.data.substring(0,9) == "chrome://") {
+        gPrePath = evt.data;
+        respond("path-is-set");
+      } else {
+        // Content cannot post to chrome without privileges
+        window.parent.postMessage("SHOULD NOT GET THIS!", "*");
 
-      var msg = "post-to-content-response";
+        var msg = "post-to-content-response";
 
-      if (evt.source !== null)
-        msg += " wrong-source(" + evt.source + ")";
-      if (!evt.isTrusted)
-        msg += " unexpected-untrusted-event";
-      if (evt.type !== "message")
-        msg += " wrong-type(" + evt.type + ")";
-      if (evt.origin !== "chrome://mochikit")
-        msg += " wrong-origin(" + evt.origin + ")";
-      if (evt.data !== "post-to-content")
-        msg += " wrong-message(" + evt.data + ")";
+        if (evt.source !== null)
+          msg += " wrong-source(" + evt.source + ")";
+        if (!evt.isTrusted)
+          msg += " unexpected-untrusted-event";
+        if (evt.type !== "message")
+          msg += " wrong-type(" + evt.type + ")";
+        if (evt.origin !== gPrePath)
+          msg += " wrong-origin(" + evt.origin + ")";
+        if (evt.data !== "post-to-content")
+          msg += " wrong-message(" + evt.data + ")";
 
-      respond(msg);
+        respond(msg);
+      }
     }
     
     function respond(msg)
     {
       // ...so get privileges and test that this works with privileges
       netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
       window.parent.postMessage(msg, "*");
     }
--- a/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
+++ b/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
@@ -40,16 +40,20 @@ function finish()
 function messageReceiver(evt)
 {
   ok(evt instanceof MessageEvent, "umm, how did we get this?");
   is(evt.type, "message", "expected events of type 'message'");
   is(evt.lastEventId, "", "postMessage creates events with empty lastEventId");
 
   switch (evt.data)
   {
+    case "path-is-set":
+      chromePathIsSet(evt);
+      break;
+      
     case "post-to-self":
       checkSelf(evt);
       break;
       
     case "post-to-content-response":
       receiveContent(evt);
       break;
 
@@ -68,21 +72,26 @@ function messageReceiver(evt)
 function checkSelf(evt)
 {
   var prepath = getChromePrePath(window.location.href);
 
   is(evt.isTrusted, true, "should have sent a trusted event");
   is(evt.origin, prepath, "wrong origin for chrome: URL");
   is(evt.source, null, "chrome posters get a null source, for security");
 
+  window.frames.contentDomain.postMessage(prepath, "*");
+}
+
+
+function chromePathIsSet(evt)
+{
   window.frames.contentDomain.postMessage("post-to-content",
                                           "http://example.org");
 }
 
-
 /*************
  * RECEIVERS *
  *************/
 
 function receiveContent(evt)
 {
   is(evt.isTrusted, true, "should have sent a trusted event");
   is(evt.origin, "http://example.org", "content response event has wrong URI");
--- a/layout/generic/test/file_bug514732_window.xul
+++ b/layout/generic/test/file_bug514732_window.xul
@@ -4,17 +4,17 @@
 <window id="514732Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="setTimeout(nextTest,0);"
         title="bug 514732 test">
 
   <script type="application/javascript"
-          src="chrome://mochikit/content/chrome/docshell/test/chrome/docshell_helpers.js">
+          src="chrome://mochikit/content/tests/SimpleTest/docshell_helpers.js">
   </script>
 
   <script type="application/javascript"><![CDATA[
   
     // Define the generator-iterator for the tests.
     var tests = testIterator();
 
     ////
--- a/layout/generic/test/test_bug514732-2.xul
+++ b/layout/generic/test/test_bug514732-2.xul
@@ -9,18 +9,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <window title="Mozilla Bug 514732"
   xmlns:html="http://www.w3.org/1999/xhtml"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <title>Test for Bug 514732</title>
   <script type="application/javascript"
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
-          src=
-          "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+          src= "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
   </script>
 
 <body  xmlns="http://www.w3.org/1999/xhtml">
 <a target="_blank"
    href="https://bugzilla.mozilla.org/show_bug.cgi?id=514732">
    Mozilla Bug 514732</a>
 <p id="display"></p>
 <div id="content" style="display: none">
--- a/modules/libpr0n/test/browser/head.js
+++ b/modules/libpr0n/test/browser/head.js
@@ -1,16 +1,18 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 const RELATIVE_DIR = "modules/libpr0n/test/browser/";
 const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
 const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR;
-const CHROMEROOT = "chrome://mochikit/content/browser/" + RELATIVE_DIR;
+
+var chrome_root = getRootDirectory(gTestPath);
+const CHROMEROOT = chrome_root;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function getImageLoading(doc, id) {
   var htmlImg = doc.getElementById(id);
   return htmlImg.QueryInterface(Ci.nsIImageLoadingContent);
 }
 
--- a/testing/mochitest/Makefile.in
+++ b/testing/mochitest/Makefile.in
@@ -46,16 +46,29 @@ include $(DEPTH)/config/autoconf.mk
 DIRS =	MochiKit \
 	static \
 	dynamic \
 	tests \
 	chrome \
 	ssltunnel \
 	$(NULL)
 
+
+NO_JS_MANIFEST = 1
+MOZ_CHROME_FILE_FORMAT = jar
+DIST_FILES = install.rdf
+
+# Used in install.rdf
+USE_EXTENSION_MANIFEST = 1
+
+XPI_NAME = mochijar
+
+# we turn this off for UNIVERSAL_BINARY
+CHROME_JAR = 1
+
 include $(topsrcdir)/config/rules.mk
 # We're installing to _tests/testing/mochitest, so this is the depth
 # necessary for relative objdir paths.
 TARGET_DEPTH = ../../..
 include $(topsrcdir)/build/automation-build.mk
 
 # files that get copied into $objdir/_tests/
 _SERV_FILES = 	\
@@ -103,16 +116,19 @@ include $(topsrcdir)/build/automation-bu
 		pywebsocket/mod_pywebsocket/handshake/__init__.py \
 		pywebsocket/mod_pywebsocket/handshake/_base.py \
 		pywebsocket/mod_pywebsocket/handshake/draft75.py \
 		pywebsocket/mod_pywebsocket/handshake/handshake.py \
 		$(NULL)
 
 _DEST_DIR = $(DEPTH)/_tests/$(relativesrcdir)
 
+libs:: 
+	(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - mochijar) | (cd $(_DEST_DIR) && tar -xf -)
+
 libs:: $(_PYWEBSOCKET_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(_DEST_DIR)/pywebsocket
 
 libs:: $(_MOD_PYWEBSOCKET_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(_DEST_DIR)/pywebsocket/mod_pywebsocket
 
 libs:: $(_HANDSHAKE_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(_DEST_DIR)/pywebsocket/mod_pywebsocket/handshake
@@ -170,16 +186,35 @@ else
 TEST_HARNESS_PLUGINS := \
   $(DLL_PREFIX)nptest$(DLL_SUFFIX)
 endif
 
 # Rules for staging the necessary harness bits for a test package
 PKG_STAGE = $(DIST)/test-package-stage
 DIST_BIN = $(DIST)/bin
 
+PKG_CHROMEJAR = $(PKG_STAGE)/mochitest/content/
+
+ifdef CHROME_JAR
+stage-chromejar:
+	$(NSINSTALL) -D $(PKG_CHROMEJAR)
+	cp -RL $(DEPTH)/_tests/testing/mochitest/browser $(PKG_CHROMEJAR)
+	cp -RL $(DEPTH)/_tests/testing/mochitest/chrome $(PKG_CHROMEJAR)
+ifdef ACCESSIBILITY
+	cp -RL $(DEPTH)/_tests/testing/mochitest/a11y $(PKG_CHROMEJAR)
+endif
+	@(cd $(PKG_STAGE)/mochitest && zip -r tests.jar content/)
+	@(rm -rf $(PKG_CHROMEJAR))
+
+stage-package: stage-chromejar
+endif
+
+$(_DEST_DIR):
+	$(NSINSTALL) -D $@
+
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/mochitest && $(NSINSTALL) -D $(PKG_STAGE)/bin/plugins
 	@(cd $(DEPTH)/_tests/testing/mochitest/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/mochitest && tar -xf -)
 	@(cd $(DIST_BIN) && tar $(TAR_CREATE_FLAGS) - $(TEST_HARNESS_BINS)) | (cd $(PKG_STAGE)/bin && tar -xf -)
 	@(cd $(DIST_BIN)/components && tar $(TAR_CREATE_FLAGS) - $(TEST_HARNESS_COMPONENTS)) | (cd $(PKG_STAGE)/bin/components && tar -xf -)
 	@(cd $(topsrcdir)/build/pgo/certs && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/certs && tar -xf -)
 ifdef MOZ_PLUGINS
 	@(cd $(DIST_BIN)/plugins && tar $(TAR_CREATE_FLAGS) - $(TEST_HARNESS_PLUGINS)) | (cd $(PKG_STAGE)/bin/plugins && tar -xf -)
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -203,25 +203,41 @@
           return "<p class=\"" + class + "\">" + t.result + " | " + path +
                  " | " + _entityEncode(t.msg) + "</p>";
         }).join("\n");
       }
     };
 
     // Returns an array of browserTest objects for all the selected tests
     function listTests() {
+      var baseURL = 'chrome://mochitests/content';
+      var testsURI = Components.classes["@mozilla.org/file/directory_service;1"]
+                          .getService(Components.interfaces.nsIProperties)
+                          .get("ProfD", Components.interfaces.nsILocalFile);
+      testsURI.append("tests.manifest");
+      var ioSvc = Components.classes["@mozilla.org/network/io-service;1"].
+                  getService(Components.interfaces.nsIIOService);
+      var manifestFile = ioSvc.newFileURI(testsURI)
+                      .QueryInterface(Components.interfaces.nsIFileURL).file;
+
+      Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar).
+        autoRegister(manifestFile);
 
       // load server.js in so we can share template functions
       var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                          getService(Ci.mozIJSSubScriptLoader);
       var srvScope = {};
-      var baseURL = 'chrome://mochikit/content';
       scriptLoader.loadSubScript('chrome://mochikit/content/server.js', srvScope);
 
-      var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope);
+      var jar = getJar(baseURL);
+      if (jar != null) {
+        var [links, singleTestPath] = getMochitestJarListing(baseURL, gConfig.testPath, "browser");
+      } else {
+        var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope);
+      }
 
       var fileNames = [];
       var fileNameRegexp = /browser_.+\.js$/;
       srvScope.arrayOfTestFiles(links, fileNames, fileNameRegexp);
       return fileNames.map(function (f) new browserTest(f));
     }
 
     function setStatus(aStatusString) {
--- a/testing/mochitest/chrome-harness.js
+++ b/testing/mochitest/chrome-harness.js
@@ -103,52 +103,55 @@ function getMochitestJarListing(basePath
   var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"].
                   createInstance(Components.interfaces.nsIZipReader);
   var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
                     getService(Components.interfaces.nsIFileProtocolHandler);
 
   var fileName = fileHandler.getFileFromURLSpec(getResolvedURI(basePath).JARFile.spec);
   zReader.open(fileName);
   //hardcoded 'content' as that is the root dir in the mochikit.jar file
+  var idx = basePath.indexOf('/content');
+  var basePath = basePath.slice(0, idx);
+
   var base = "content/" + dir + "/";
 
   var singleTestPath;
   if (testPath) {
     var extraPath = testPath;
     var pathToCheck = base + testPath;
     if (zReader.hasEntry(pathToCheck)) {
       var pathEntry = zReader.getEntry(pathToCheck);
       if (pathEntry.isDirectory) {
         base = pathToCheck;
       } else {
-        singleTestPath = '/' + base + testPath;
+        singleTestPath = basePath + '/' + base + testPath;
         var singleObject = {};
         singleObject[singleTestPath] = true;
         return [singleObject, singleTestPath];
       }
     }
     else if (zReader.hasEntry(pathToCheck + "/")) {
       base = pathToCheck + "/";
     }
   }
-  var [links, count] = zList(base, zReader, true);
+  var [links, count] = zList(base, zReader, basePath, true);
   return [links, null];
 }
 
 /*
  * Replicate the server.js list() function with a .jar file
  *
  * base: string value of base directory we are testing
  * zReader: handle to opened nsIZipReader object
  * recurse: true|false if we do subdirs
  *
  * returns:
  *  [json object of {dir:{subdir:{file:true, file:true, ...}}}, count of tests]
  */
-function zList(base, zReader, recurse) {
+function zList(base, zReader, baseJarName, recurse) {
   var dirs = zReader.findEntries(base + "*");
   var links = {};
   var count = 0;
   var fileArray = [];
   
   while(dirs.hasMore()) {
     var entryName = dirs.getNext();
     if (entryName.substr(-1) == '/' && entryName.split('/').length == (base.split('/').length + 1) ||
@@ -157,22 +160,22 @@ function zList(base, zReader, recurse) {
     }
   }
   fileArray.sort();
   count = fileArray.length;
   for (var i=0; i < fileArray.length; i++) {
     var myFile = fileArray[i];
     if (myFile.substr(-1) === '/' && recurse) {
       var childCount = 0;
-      [links[myFile], childCount] = zList(myFile, zReader, recurse);
+      [links[myFile], childCount] = zList(myFile, zReader, baseJarName, recurse);
       count += childCount;
     } else {
       if (myFile.indexOf("SimpleTest") == -1) {
         //we add the '/' so we don't try to run content/content/chrome
-        links['/' + myFile] = true;
+        links[baseJarName + '/' + myFile] = true;
       }
     }
   }
   return [links, count];
 }
 
 /**
  * basePath: the URL base path to search from such as chrome://mochikit/content/a11y
@@ -229,18 +232,24 @@ function getFileListing(basePath, testPa
 
 //used by tests to determine their directory based off window.location.path
 function getRootDirectory(path, chromeURI) {
   if (chromeURI === undefined)
   {
     chromeURI = getChromeURI(path);
   }
   var myURL = chromeURI.QueryInterface(Components.interfaces.nsIURL);
+  var mydir = myURL.directory;
 
-  return chromeURI.prePath + myURL.directory;
+  if (mydir.match('/$') != '/')
+  {
+    mydir += '/';
+  }
+
+  return chromeURI.prePath + mydir;
 }
 
 //used by tests to determine their directory based off window.location.path
 function getChromePrePath(path, chromeURI) {
 
   if (chromeURI === undefined) {
     chromeURI = getChromeURI(path);
   }
@@ -272,17 +281,17 @@ function getJar(uri) {
  */
 function extractJarToTmp(jar) {
   var tmpdir = Components.classes["@mozilla.org/file/directory_service;1"]
                       .getService(Components.interfaces.nsIProperties)
                       .get("ProfD", Components.interfaces.nsILocalFile);
   tmpdir.append("mochikit.tmp");
   // parseInt is used because octal escape sequences cause deprecation warnings
   // in strict mode (which is turned on in debug builds)
-  tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
+  tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
 
   var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"].
                   createInstance(Components.interfaces.nsIZipReader);
 
   var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
                     getService(Components.interfaces.nsIFileProtocolHandler);
 
   var fileName = fileHandler.getFileFromURLSpec(jar.JARFile.spec);
@@ -300,17 +309,17 @@ function extractJarToTmp(jar) {
   /* Create dir structure first, no guarantee about ordering of directories and
    * files returned from findEntries.
    */
   var dirs = zReader.findEntries(filepath + '*/');
   while (dirs.hasMore()) {
     var targetDir = buildRelativePath(dirs.getNext(), tmpdir, filepath);
     // parseInt is used because octal escape sequences cause deprecation warnings
     // in strict mode (which is turned on in debug builds)
-    targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
+    targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
   }
 
   //now do the files
   var files = zReader.findEntries(filepath + "*");
   while (files.hasMore()) {
     var fname = files.getNext();
     if (fname.substr(-1) != '/') {
       var targetFile = buildRelativePath(fname, tmpdir, filepath);
--- a/testing/mochitest/harness-overlay.xul
+++ b/testing/mochitest/harness-overlay.xul
@@ -12,86 +12,69 @@
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/TestRunner.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/MozillaFileLogger.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/quit.js" />
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/setup.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/chrome-harness.js" />
   <script type="application/javascript;version=1.7"><![CDATA[
-    function loadTests()
-    {
-      window.removeEventListener("load", loadTests, false);
+
+function loadTests()
+{
+  window.removeEventListener("load", loadTests, false);
 
-      var dir = document.documentElement.getAttribute('directory');
-      var url = "chrome://mochikit/content/" + dir + "/";
-      // Find our chrome dir
-      var ios = Cc["@mozilla.org/network/io-service;1"].
-                  getService(Ci.nsIIOService);
-      var chromeURI = ios.newURI("chrome://mochikit/content/",
-                                 null, null);
-      var resolvedURI = Cc["@mozilla.org/chrome/chrome-registry;1"].
-                          getService(Ci.nsIChromeRegistry).
-                          convertChromeURL(chromeURI);
-      var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].
-                          getService(Ci.nsIFileProtocolHandler);
-      var chromeDir = fileHandler.getFileFromURLSpec(resolvedURI.spec);
-      chromeDir = chromeDir.parent.QueryInterface(Ci.nsILocalFile);
-      chromeDir.appendRelativePath(dir);
+  var baseurl = 'chrome://mochitests/content';
+  var testsURI = Components.classes["@mozilla.org/file/directory_service;1"]
+                      .getService(Components.interfaces.nsIProperties)
+                      .get("ProfD", Components.interfaces.nsILocalFile);
+  testsURI.append("tests.manifest");
+  var ioSvc = Components.classes["@mozilla.org/network/io-service;1"].
+              getService(Components.interfaces.nsIIOService);
+  var manifestFile = ioSvc.newFileURI(testsURI)
+                  .QueryInterface(Components.interfaces.nsIFileURL).file;
+
+  Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar).
+    autoRegister(manifestFile);
+
+  var dir = document.documentElement.getAttribute('directory');
 
-      var singleTestPath;
-      if ("testPath" in params && params.testPath) {
-        var extraPath = params.testPath;
-        var pathToCheck = chromeDir.clone().QueryInterface(Ci.nsILocalFile);
-        var pathIsFile = false;
-        try {
-          var pathParts = extraPath.toString().split("/");
-          for each (var part in pathParts) {
-            pathToCheck.append(part);
-          }          
-          if (pathToCheck.isDirectory()) {
-            for each (var part in pathParts) {
-              chromeDir.append(part);
-            }          
-            url += extraPath + "/";
-          }
-          else {
-            pathIsFile = true;
-          }
-        }
-        catch (e) {
-          pathIsFile = true;
-        }
-        if (pathIsFile) {
-          singleTestPath = url + params.testPath;
-        }
-      }
-      // load server.js in so we can share template functions
-      var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
-                           getService(Ci.mozIJSSubScriptLoader);
-      var srvScope = {};
-      scriptLoader.loadSubScript("chrome://mochikit/content/server.js",
-                                 srvScope);
+  // load server.js in so we can share template functions
+  var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+                       getService(Ci.mozIJSSubScriptLoader);
+  var srvScope = {};
+  scriptLoader.loadSubScript('chrome://mochikit/content/server.js',
+                             srvScope);
+  // generate our test list
+  srvScope.makeTags();
+
+  var singleTestPath;
+  var links;
 
-      // generate our test list
-      srvScope.makeTags();
-      var [links, count] = srvScope.list(url, chromeDir, true);
-      var tableContent = srvScope.linksToTableRows(links, 0);
-      function populate() {
-        $("test-table").innerHTML += tableContent;
-      }
-      gTestList = eval(srvScope.jsonArrayOfTestFiles(links));
-      populate();
-      hookup();
+  if (getResolvedURI(baseurl).JARFile) {
+    [links, singleTestPath] = getMochitestJarListing(baseurl, params.testPath, dir);
+  } else {
+    [links, singleTestPath] = getFileListing(baseurl, params.testPath, dir, srvScope);
+  }
+  
+  var tableContent = srvScope.linksToTableRows(links, 0);
 
-      // if we got passed a test path, just run that single test
-      if (singleTestPath)
-        window.location.href = singleTestPath;
-    }
+  function populate() {
+    $("test-table").innerHTML += tableContent;
+  }
+  gTestList = eval(srvScope.jsonArrayOfTestFiles(links));
+  populate();
+  hookup();
+
+  if (singleTestPath)
+    window.location.href = singleTestPath;
+}
 
     window.addEventListener("load", loadTests, false);
   ]]>
   </script>
 
   <vbox>   
     <button label="Run Chrome Tests" id="runtests" flex="1"/>
 
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/install.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>mochikit@mozilla.org</em:id>
+    <em:version>1.0</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+#expand        <em:minVersion>__MOZILLA_VERSION_U__</em:minVersion>
+#expand        <em:maxVersion>__MOZILLA_VERSION_U__</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <!-- Front End MetaData -->
+    <em:name>Mochitest</em:name>
+    <em:description>Mochikit test harness</em:description>
+    <em:creator>Joel Maher</em:creator>
+  </Description>
+</RDF>
+
+
+
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/jar.mn
@@ -0,0 +1,39 @@
+mochikit.jar:
+% content mochikit %content/
+  content/browser-harness.xul (browser-harness.xul)
+  content/browser-test.js (browser-test.js)
+  content/browser-test-overlay.xul (browser-test-overlay.xul)
+  content/chrome-harness.js (chrome-harness.js)
+  content/harness-a11y.xul (harness-a11y.xul)
+  content/harness-overlay.xul (harness-overlay.xul)
+  content/harness.xul (harness.xul)
+  content/ipc.js (ipc.js)
+  content/ipc-overlay.xul (ipc-overlay.xul)
+  content/mozprefs.js (mozprefs.js)
+  content/redirect-a11y.html (redirect-a11y.html)
+  content/redirect.html (redirect.html)
+  content/redirect.js (redirect.js)
+  content/server.js (server.js)
+  content/dynamic/getMyDirectory.sjs (dynamic/getMyDirectory.sjs)
+  content/static/bug100533_iframe.html (static/bug100533_iframe.html)
+  content/static/bug100533_load.html (static/bug100533_load.html)
+  content/static/bug277724_iframe1.html (static/bug277724_iframe1.html)
+  content/static/bug277724_iframe2.xhtml (static/bug277724_iframe2.xhtml)
+  content/static/bug340800_iframe.txt (static/bug340800_iframe.txt)
+  content/static/bug344830_testembed.svg (static/bug344830_testembed.svg)
+  content/static/harness.css (static/harness.css)
+  content/static/nnc_lockup.gif (static/nnc_lockup.gif)
+  content/tests/SimpleTest/EventUtils.js (tests/SimpleTest/EventUtils.js)
+  content/tests/SimpleTest/MozillaFileLogger.js (tests/SimpleTest/MozillaFileLogger.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)
+  content/tests/SimpleTest/docshell_helpers.js (../..//docshell/test/chrome/docshell_helpers.js)
+
+  content/MochiKit/packed.js (MochiKit/packed.js)
+
--- a/testing/mochitest/runtests.py.in
+++ b/testing/mochitest/runtests.py.in
@@ -37,16 +37,17 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 """
 Runs the Mochitest test harness.
 """
 
+from __future__ import with_statement
 from datetime import datetime
 import optparse
 import os
 import os.path
 import sys
 import time
 import shutil
 from urllib import quote_plus as encodeURIComponent
@@ -338,17 +339,17 @@ class MochitestServer:
 
   def stop(self):
     try:
       c = urllib2.urlopen(self.shutdownURL)
       c.read()
       c.close()
 
       rtncode = self._process.poll()
-      if (rtncode == None):
+      if rtncode is None:
         self._process.terminate()
     except:
       self._process.kill()
 
 class WebSocketServer(object):
   "Class which encapsulates the mod_pywebsocket server"
 
   def __init__(self, automation, options, scriptdir):
@@ -563,26 +564,28 @@ class Mochitest(object):
   def runTests(self, options):
     """ Prepare, configure, run tests and cleanup """
     debuggerInfo = getDebuggerInfo(self.oldcwd, options.debugger, options.debuggerArgs,
                       options.debuggerInteractive);
 
     self.leak_report_file = os.path.join(options.profilePath, "runtests_leaks.log")
 
     browserEnv = self.buildBrowserEnv(options)
-    if (browserEnv == None):
+    if browserEnv is None:
       return 1
 
     manifest = self.buildProfile(options)
+    if manifest is None:
+      return 1
     self.startWebServer(options)
     self.startWebSocketServer(options)
 
     testURL = self.buildTestPath(options)
     self.buildURLOptions(options)
-    if (len(self.urlOpts) > 0):
+    if len(self.urlOpts) > 0:
       testURL += "?" + "&".join(self.urlOpts)
 
     # Remove the leak detection file so it can't "leak" to the tests run.
     # The file is not there if leak logging was not enabled in the application build.
     if os.path.exists(self.leak_report_file):
       os.remove(self.leak_report_file)
 
     # then again to actually run mochitest
@@ -610,17 +613,18 @@ class Mochitest(object):
     if options.vmwareRecording:
       self.stopVMwareRecording();
 
     self.stopWebServer(options)
     self.stopWebSocketServer(options)
     processLeakLog(self.leak_report_file, options.leakThreshold)
     self.automation.log.info("\nINFO | runtests.py | Running tests: end.")
 
-    self.cleanup(manifest, options)
+    if manifest is not None:
+      self.cleanup(manifest, options)
     return status
 
   def makeTestConfig(self, options):
     "Creates a test configuration file for customizing test execution."
     def boolString(b):
       if b:
         return "true"
       return "false"
@@ -668,37 +672,63 @@ toolbar#nav-bar {
 
     # register our chrome dir
     chrometestDir = os.path.abspath(".") + "/"
     if self.automation.IS_WIN32:
       chrometestDir = "file:///" + chrometestDir.replace("\\", "/")
 
     temp_file = os.path.join(tempfile.mkdtemp(), "mochikit.manifest")
     manifestFile = open(temp_file, "w")
-    manifestFile.write("content mochikit " + chrometestDir + " contentaccessible=yes\n")
 
+    browser_chrome = ""
     if options.browserChrome:
-      manifestFile.write("""overlay chrome://navigator/content/navigator.xul chrome://mochikit/content/browser-test-overlay.xul
+      browser_chrome = """overlay chrome://navigator/content/navigator.xul chrome://mochikit/content/browser-test-overlay.xul
 overlay chrome://browser/content/browser.xul chrome://mochikit/content/browser-test-overlay.xul
-""")
-    elif ((options.chrome == False) and (options.a11y == False)):
+"""
+    elif (options.chrome == False) and (options.a11y == False):
       #only do the ipc-overlay.xul for mochitest-plain.  
       #Currently there are focus issues in chrome tests and issues with new windows and dialogs when using ipc
-      manifestFile.write("overlay chrome://browser/content/browser.xul chrome://mochikit/content/ipc-overlay.xul")
+      browser_chrome += "overlay chrome://browser/content/browser.xul chrome://mochikit/content/ipc-overlay.xul\n"
+
+    jarDir = 'mochijar'
+    if not os.path.exists(os.path.join(self.SCRIPT_DIRECTORY, jarDir)):
+      print "TEST-UNEXPECTED-FAIL | invalid setup: missing mochikit extension"
+      return None
+
+    if self.installTestsJar(options):
+      manifestFile.write("content mochitests jar:tests.jar!/content/\n");
+    else:
+      manifestFile.write("content mochitests %s contentaccessible=yes\n" % chrometestDir)
+    self.installChromeJar(jarDir, browser_chrome, options)
       
     manifestFile.close()
 
     return self.installChromeFile(temp_file, options)
 
+  def installChromeJar(self, jarDirName, browser_chrome, options):
+    """
+      copy mochijar directory to profile as an extension so we have chrome://mochikit for all harness code
+    """
+    jarDir = os.path.join(options.profilePath, 'extensions', 'mochikit@mozilla.org')
+    shutil.copytree(os.path.join(self.SCRIPT_DIRECTORY, jarDirName), jarDir)
+    with open(os.path.join(jarDir, "chrome.manifest"), 'a') as mfile:
+      mfile.write(browser_chrome)
+
+    return jarDir
+
+  def installTestsJar(self, options):
+    """ copy tests.jar to the profile directory so we can auto register it in the .xul harness """
+    if os.path.exists(os.path.join(self.SCRIPT_DIRECTORY, 'tests.jar')):
+      shutil.copy(os.path.join(self.SCRIPT_DIRECTORY, 'tests.jar'), options.profilePath)
+      return True
+    return False
+
   def installChromeFile(self, filename, options):
-    (path, leaf) = os.path.split(options.app)
-    manifestdir = os.path.join(path, "distribution", "bundles", "mochitest")
-    if not os.path.exists(manifestdir):
-      os.makedirs(manifestdir)
-    manifest = os.path.join(manifestdir, "chrome.manifest")
+    """ copy tests.manifest to the profile directory so we can auto register with tests.jar """
+    manifest = os.path.join(options.profilePath, 'tests.manifest')
     shutil.copy(filename, manifest)
     return manifest
 
   def copyExtraFilesToProfile(self, options):
     "Copy extra files or dirs specified on the command line to the testing profile."
     for f in options.extraProfileFiles:
       abspath = self.getFullPath(f)
       dest = os.path.join(options.profilePath, os.path.basename(abspath))
--- a/testing/mochitest/server.js
+++ b/testing/mochitest/server.js
@@ -453,17 +453,22 @@ function list(requestPath, directory, re
  * is a test case to be executed in the harness, or just
  * a supporting file.
  */
 function isTest(filename, pattern)
 {
   if (pattern)
     return pattern.test(filename);
 
-  return filename.indexOf("test_") > -1 &&
+  // File name is a URL style path to a test file, make sure that we check for
+  // tests that start with test_.
+  testPattern = /^test_/;
+  pathPieces = filename.split('/');
+    
+  return testPattern.test(pathPieces[pathPieces.length - 1]) &&
          filename.indexOf(".js") == -1 &&
          filename.indexOf(".css") == -1 &&
          !/\^headers\^$/.test(filename);
 }
 
 /**
  * Transform nested hashtables of paths to nested HTML lists.
  */
--- a/testing/mochitest/tests/SimpleTest/Makefile.in
+++ b/testing/mochitest/tests/SimpleTest/Makefile.in
@@ -50,13 +50,14 @@ include $(topsrcdir)/config/rules.mk
 			SimpleTest.js \
 			test.css \
 			TestRunner.js \
 			setup.js \
 			EventUtils.js \
 			WindowSnapshot.js \
 			PluginUtils.js \
 			$(DEPTH)/toolkit/content/tests/browser/common/mockObjects.js \
+                        $(DEPTH)/docshell/test/chrome/docshell_helpers.js \
 			$(NULL)
 
 libs:: $(_SIMPLETEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/$(relativesrcdir)
 
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -137,18 +137,23 @@ ifndef UNIVERSAL_BINARY
 PKG_STAGE = $(DIST)/test-package-stage
 package-tests: stage-mochitest stage-reftest stage-xpcshell stage-jstests stage-mozmill stage-jetpack
 else
 # This staging area has been built for us by universal/flight.mk
 PKG_STAGE = $(DIST)/universal/test-package-stage
 endif
 
 package-tests:
+	@rm -f "$(DIST)/$(PKG_PATH)$(TEST_PACKAGE)"
+ifndef UNIVERSAL_BINARY
 	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
-	@rm -f "$(DIST)/$(PKG_PATH)$(TEST_PACKAGE)"
+else
+	#building tests.jar (bug 543800) fails on unify, so we build tests.jar after unify is run
+	$(MAKE) -C $(DEPTH)/testing/mochitest stage-chromejar PKG_STAGE=$(DIST)/universal
+endif
 	cd $(PKG_STAGE) && \
 	  zip -r9D "$(call core_abspath,$(DIST)/$(PKG_PATH)$(TEST_PACKAGE))" *
 
 ifeq (Android, $(OS_TARGET))
 package-tests: stage-android
 endif
 
 make-stage-dir:
--- a/toolkit/content/tests/chrome/rtlchrome/rtl.manifest
+++ b/toolkit/content/tests/chrome/rtlchrome/rtl.manifest
@@ -1,10 +1,5 @@
-content rtlchrome /content
+content rtlchrome /
 
 # Override intl.css with our own CSS file
 override chrome://global/locale/intl.css chrome://rtlchrome/rtl.css
 override chrome://global/locale/global.dtd chrome://rtlchrome/rtl.dtd
-
-
-# Override intl.css with our own CSS file
-override chrome://global/locale/intl.css chrome://mochikit/content/chrome/toolkit/content/tests/chrome/rtlchrome/rtl.css
-override chrome://global/locale/global.dtd chrome://mochikit/content/chrome/toolkit/content/tests/chrome/rtlchrome/rtl.dtd
--- a/toolkit/crashreporter/test/browser/browser_aboutCrashes.js
+++ b/toolkit/crashreporter/test/browser/browser_aboutCrashes.js
@@ -1,14 +1,14 @@
 // load our utility script
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
 
 var rootDir = getRootDirectory(gTestPath);
-scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this);
+scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
 
 function check_crash_list(tab, crashes) {
   let doc = gBrowser.getBrowserForTab(tab).contentDocument;
   let crashlinks = doc.getElementById("tbody").getElementsByTagName("a");
   is(crashlinks.length, crashes.length, "about:crashes lists correct number of crash reports");
   for(let i = 0; i < crashes.length; i++) {
     is(crashlinks[i].firstChild.textContent, crashes[i].id, i + ": crash ID is correct");
   }
--- a/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js
+++ b/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js
@@ -1,14 +1,14 @@
 // load our utility script
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
 
 var rootDir = getRootDirectory(gTestPath);
-scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this);
+scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
 
 function cleanup_and_finish() {
   try {
     cleanup_fake_appdir();
   } catch(ex) {}
   Services.prefs.clearUserPref("breakpad.reportURL");
   gBrowser.removeTab(gBrowser.selectedTab);
   finish();
--- a/toolkit/crashreporter/test/browser/browser_bug471404.js
+++ b/toolkit/crashreporter/test/browser/browser_bug471404.js
@@ -1,14 +1,14 @@
 // load our utility script
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
 
 var rootDir = getRootDirectory(gTestPath);
-scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this);
+scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
 
 function check_clear_visible(tab, aVisible) {
   let doc = gBrowser.getBrowserForTab(tab).contentDocument;
   let visible = false;
   let button = doc.getElementById("clear-reports");
   if (button) {
     let style = doc.defaultView.getComputedStyle(button, "");
     if (style.display != "none" &&
--- a/xpinstall/tests/browser_auth.js
+++ b/xpinstall/tests/browser_auth.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install succeeds when authentication is required
 // This verifies bug 312473
 function test() {
   Harness.authenticationCallback = get_auth_info;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_auth2.js
+++ b/xpinstall/tests/browser_auth2.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when authentication is required and bad
 // credentials are given
 // This verifies bug 312473
 function test() {
   Harness.authenticationCallback = get_auth_info;
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_auth3.js
+++ b/xpinstall/tests/browser_auth3.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when authentication is required and it is
 // canceled
 // This verifies bug 312473
 function test() {
   Harness.authenticationCallback = get_auth_info;
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_badhash.js
+++ b/xpinstall/tests/browser_badhash.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when an invalid hash is included
 // This verifies bug 302284
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_badhashtype.js
+++ b/xpinstall/tests/browser_badhashtype.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when an unknown hash type is included
 // This verifies bug 302284
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_bug540558.js
+++ b/xpinstall/tests/browser_bug540558.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that calling InstallTrigger.installChrome works
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_cancel.js
+++ b/xpinstall/tests/browser_cancel.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that cancelling an in progress download works.
 var gManager = null;
 
 function test() {
   waitForExplicitFinish();
   gManager = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
--- a/xpinstall/tests/browser_chrome.js
+++ b/xpinstall/tests/browser_chrome.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that starting a download from chrome works and bypasses the whitelist
 function test() {
   waitForExplicitFinish();
   var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
                          .createInstance(Components.interfaces.nsIXPInstallManager);
   xpimgr.initManagerFromChrome([ TESTROOT + "unsigned.xpi" ],
--- a/xpinstall/tests/browser_cookies.js
+++ b/xpinstall/tests/browser_cookies.js
@@ -1,12 +1,15 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test that an install that requires cookies to be sent fails when no cookies
 // are set
 // This verifies bug 462739
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_cookies2.js
+++ b/xpinstall/tests/browser_cookies2.js
@@ -1,12 +1,15 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test that an install that requires cookies to be sent succeeds when cookies
 // are set
 // This verifies bug 462739
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_cookies3.js
+++ b/xpinstall/tests/browser_cookies3.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test that an install that requires cookies to be sent succeeds when cookies
 // are set and third party cookies are disabled.
 // This verifies bug 462739
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_cookies4.js
+++ b/xpinstall/tests/browser_cookies4.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test that an install that requires cookies to be sent fails when cookies
 // are set and third party cookies are disabled and the request is to a third
 // party.
 // This verifies bug 462739
 function test() {
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_corrupt.js
+++ b/xpinstall/tests/browser_corrupt.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when the xpi is corrupt.
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_empty.js
+++ b/xpinstall/tests/browser_empty.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails when there is no install script present.
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_enabled.js
+++ b/xpinstall/tests/browser_enabled.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an InstallTrigger.enabled is working
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function() {
--- a/xpinstall/tests/browser_enabled2.js
+++ b/xpinstall/tests/browser_enabled2.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an InstallTrigger.enabled is working
 function test() {
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("xpinstall.enabled", false);
 
--- a/xpinstall/tests/browser_enabled3.js
+++ b/xpinstall/tests/browser_enabled3.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an InstallTrigger.install call fails when xpinstall is disabled
 function test() {
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("xpinstall.enabled", false);
 
--- a/xpinstall/tests/browser_hash.js
+++ b/xpinstall/tests/browser_hash.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install succeeds when a valid hash is included
 // This verifies bug 302284
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_installchrome.js
+++ b/xpinstall/tests/browser_installchrome.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that calling InstallTrigger.installChrome works
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_localfile.js
+++ b/xpinstall/tests/browser_localfile.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an local file works when loading the url
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_localfile2.js
+++ b/xpinstall/tests/browser_localfile2.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install fails if the url is a local file when requested from
 // web content
 function test() {
   waitForExplicitFinish();
 
   var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
--- a/xpinstall/tests/browser_navigateaway.js
+++ b/xpinstall/tests/browser_navigateaway.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that navigating away from the initiating page during the install
 // doesn't break the install.
 // This verifies bug 473060
 function test() {
   Harness.downloadProgressCallback = download_progress;
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_navigateaway2.js
+++ b/xpinstall/tests/browser_navigateaway2.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that closing the initiating page during the install doesn't break the
 // install.
 // This verifies bugs 473060 and 475347
 function test() {
   Harness.downloadProgressCallback = download_progress;
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_offline.js
+++ b/xpinstall/tests/browser_offline.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that going offline cancels an in progress download.
 function test() {
   Harness.downloadProgressCallback = download_progress;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_opendialog.js
+++ b/xpinstall/tests/browser_opendialog.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Test whether an install succeeds when the progress dialog is already open.
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_signed_multiple.js
+++ b/xpinstall/tests/browser_signed_multiple.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing two signed add-ons in the same trigger works.
 // This verifies bug 453545
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_signed_naming.js
+++ b/xpinstall/tests/browser_signed_naming.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that the correct signer is presented for combinations of O and CN present.
 // The signed files have (when present) O=Mozilla Testing, CN=Object Signer
 // This verifies bug 372980
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
--- a/xpinstall/tests/browser_signed_tampered.js
+++ b/xpinstall/tests/browser_signed_tampered.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing a signed add-on that has been tampered with after signing.
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_signed_trigger.js
+++ b/xpinstall/tests/browser_signed_trigger.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an signed add-on through an InstallTrigger call in web
 // content.
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_signed_untrusted.js
+++ b/xpinstall/tests/browser_signed_untrusted.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an add-on signed by an untrusted certificate through an
 // InstallTrigger call in web content.
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_signed_url.js
+++ b/xpinstall/tests/browser_signed_url.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an signed add-on by navigating directly to the url
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_softwareupdate.js
+++ b/xpinstall/tests/browser_softwareupdate.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests that calling InstallTrigger.startSoftwareUpdate works
 function test() {
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/xpinstall/tests/browser_unsigned_trigger.js
+++ b/xpinstall/tests/browser_unsigned_trigger.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through an InstallTrigger call in web
 // content.
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_unsigned_url.js
+++ b/xpinstall/tests/browser_unsigned_url.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on by navigating directly to the url
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installEndedCallback = check_xpi_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_whitelist.js
+++ b/xpinstall/tests/browser_whitelist.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through an InstallTrigger call in web
 // content. This should be blocked by the whitelist check.
 // This verifies bug 252830
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installBlockedCallback = allow_blocked;
--- a/xpinstall/tests/browser_whitelist2.js
+++ b/xpinstall/tests/browser_whitelist2.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through an InstallTrigger call in web
 // content. This should be blocked by the whitelist check because the source
 // is not whitelisted, even though the target is.
 function test() {
   Harness.installBlockedCallback = allow_blocked;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_whitelist3.js
+++ b/xpinstall/tests/browser_whitelist3.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through a navigation. Should not be
 // blocked since the referer is whitelisted.
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_whitelist4.js
+++ b/xpinstall/tests/browser_whitelist4.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through a navigation. Should be
 // blocked since the referer is not whitelisted even though the target is.
 function test() {
   Harness.installBlockedCallback = allow_blocked;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
--- a/xpinstall/tests/browser_whitelist5.js
+++ b/xpinstall/tests/browser_whitelist5.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through a startSoftwareUpdate call in web
 // content. This should be blocked by the whitelist check.
 // This verifies bug 252830
 function test() {
   Harness.installBlockedCallback = allow_blocked;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/browser_whitelist6.js
+++ b/xpinstall/tests/browser_whitelist6.js
@@ -1,12 +1,14 @@
 // Load in the test harness
 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                              .getService(Components.interfaces.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this);
+
+var rootDir = getRootDirectory(window.location.href);
+scriptLoader.loadSubScript(rootDir + "harness.js", this);
 
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through an installChrome call in web
 // content. This should be blocked by the whitelist check.
 // This verifies bug 252830
 function test() {
   Harness.installBlockedCallback = allow_blocked;
   Harness.installsCompletedCallback = finish_test;
--- a/xpinstall/tests/harness.js
+++ b/xpinstall/tests/harness.js
@@ -1,15 +1,25 @@
 const TESTROOT = "http://example.com/browser/xpinstall/tests/";
 const TESTROOT2 = "http://example.org/browser/xpinstall/tests/";
-const CHROMEROOT = "chrome://mochikit/content/browser/xpinstall/tests/"
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 const PROMPT_URL = "chrome://global/content/commonDialog.xul";
 const ADDONS_URL = "chrome://mozapps/content/extensions/extensions.xul";
 
+var rootDir = getRootDirectory(gTestPath);
+var path = rootDir.split('/');
+var chromeName = path[0] + '//' + path[2];
+var croot = chromeName + "/content/browser/xpinstall/tests/";
+var jar = getJar(croot);
+if (jar) {
+  var tmpdir = extractJarToTmp(jar);
+  croot = 'file://' + tmpdir.path + '/';
+}
+const CHROMEROOT = croot;
+
 /**
  * This is a test harness designed to handle responding to UI during the process
  * of installing an XPI. A test can set callbacks to hear about specific parts
  * of the sequence.
  * Before use setup must be called and finish must be called afterwards.
  */
 var Harness = {
   // If set then the install is expected to be blocked by the whitelist. The