Bug 1014062 - Expose harness parameters via SimpleTest, always use the harness, pass keep-open for single test runs with mach. r=ted, f=bz, a=test-only
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 22 May 2014 20:09:21 +0100
changeset 217477 7e49a60f84f163f1a4914ffa87d948c51875bba7
parent 217476 ea403b4aa951f6b1362fcfc60ad552193cffb348
child 217478 365caff46c3f4bcc8b25b8bcd83fc73952121a07
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted, test-only
bugs1014062
milestone33.0a2
Bug 1014062 - Expose harness parameters via SimpleTest, always use the harness, pass keep-open for single test runs with mach. r=ted, f=bz, a=test-only
content/xul/templates/tests/chrome/test_tmpl_storage_dynamicparameters.xul
layout/base/tests/chrome/test_bug495648.xul
testing/mochitest/browser-test.js
testing/mochitest/mach_commands.py
testing/mochitest/server.js
testing/mochitest/static/harness.css
testing/mochitest/tests/Harness_sanity/mochitest.ini
testing/mochitest/tests/Harness_sanity/test_sanityParams.html
testing/mochitest/tests/SimpleTest/SimpleTest.js
testing/mochitest/tests/SimpleTest/TestRunner.js
testing/mochitest/tests/SimpleTest/setup.js
testing/mochitest/tests/browser/browser.ini
testing/mochitest/tests/browser/browser_parameters.js
--- a/content/xul/templates/tests/chrome/test_tmpl_storage_dynamicparameters.xul
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_dynamicparameters.xul
@@ -21,18 +21,16 @@
     <listitem anyid="true" label="Emu"/>
     <listitem anyid="true" label="Raven"/>
   </data>
 
 <script src="templates_shared.js"/>
 
 <script>
 <![CDATA[
-SimpleTest.expectAssertions(1, 2);
-
 SimpleTest.waitForExplicitFinish();
 
 copyToProfile('animals.sqlite');
 
 function test_storage_template()
 {
   var root = document.getElementById("root");
   expectedOutput = document.getElementById("output");
--- a/layout/base/tests/chrome/test_bug495648.xul
+++ b/layout/base/tests/chrome/test_bug495648.xul
@@ -12,17 +12,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <body xmlns="http://www.w3.org/1999/xhtml">
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=495648"
      target="_blank">Mozilla Bug 495648</a>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
-  SimpleTest.expectAssertions(18, 24);
+  SimpleTest.expectAssertions(15, 24);
 
   /** Test for Bug 495648 **/
   var uri = window.location.href.replace(/test_bug495648.xul/, "bug495648.rdf");
 
   function doTest() {
     var list = document.getElementById('l');
     var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
     var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -87,16 +87,19 @@ function Tester(aTests, aDumper, aCallba
   var simpleTestScope = {};
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromePowers.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/SimpleTest.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/MemoryStats.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/chrome-harness.js", simpleTestScope);
   this.SimpleTest = simpleTestScope.SimpleTest;
+
+  this.SimpleTest.harnessParameters = gConfig;
+
   this.MemoryStats = simpleTestScope.MemoryStats;
   this.Task = Task;
   this.Task.Debugging.maintainStack = true;
   this.Promise = Components.utils.import("resource://gre/modules/Promise.jsm", null).Promise;
   this.Assert = Components.utils.import("resource://testing-common/Assert.jsm", null).Assert;
 
   this.SimpleTestOriginal = {};
   SIMPLETEST_OVERRIDES.forEach(m => {
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -343,19 +343,20 @@ class MochitestRunner(MozbuildObject):
                 print('No tests could be found in the path specified. Please '
                     'specify a path that is a test file or is a directory '
                     'containing tests.')
                 return 1
 
             manifest = TestManifest()
             manifest.tests.extend(tests)
 
+            if (len(tests) == 1):
+                options.closeWhenDone = False
+
             options.manifestFile = manifest
-            if len(test_paths) == 1 and len(tests) == 1:
-                options.testPath = test_paths[0]
 
         if rerun_failures:
             options.testManifest = failure_file_path
 
         if debugger:
             options.debugger = debugger
 
         if debugger_args:
--- a/testing/mochitest/server.js
+++ b/testing/mochitest/server.js
@@ -668,17 +668,17 @@ function testListing(metadata, response)
           DIV({class: "clear"}),
           DIV({id: "current-test"},
             B("Currently Executing: ",
               SPAN({id: "current-test-path"}, "_")
             )
           ),
           DIV({class: "clear"}),
           DIV({class: "frameholder"},
-            IFRAME({scrolling: "no", id: "testframe", width: "500", height: "300"})
+            IFRAME({scrolling: "no", id: "testframe"})
           ),
           DIV({class: "clear"}),
           DIV({class: "toggle"},
             A({href: "#", id: "toggleNonTests"}, "Show Non-Tests"),
             BR()
           ),
 
           (
--- a/testing/mochitest/static/harness.css
+++ b/testing/mochitest/static/harness.css
@@ -90,8 +90,38 @@ div#current-test {
   padding: .5em;
   margin: 0;
 }
 
 #pass, #fail {
   margin: 0;
   padding: .5em;
 }
+
+#testframe {
+  width: 500px;
+  height: 300px;
+}
+
+
+body[singletest=true] table,
+body[singletest=true] h2,
+body[singletest=true] p,
+body[singletest=true] br,
+body[singletest=true] .clear,
+body[singletest=true] .toggle,
+body[singletest=true] #current-test,
+body[singletest=true] .status {
+  display: none;
+}
+
+
+body[singletest=true],
+body[singletest=true] .container,
+body[singletest=true] .frameholder,
+body[singletest=true] #testframe {
+  display: flex;
+  flex: 1 1 auto;
+  height: 100%;
+  box-sizing: border-box;
+  margin: 0;
+}
+
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -1,13 +1,14 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g'
 [test_sanity.html]
 [test_sanityException.html]
 [test_sanityException2.html]
+[test_sanityParams.html]
 [test_sanityWindowSnapshot.html]
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
 support-files = file_SpecialPowersFrame1.html
 [test_SpecialPowersPushPermissions.html]
 [test_SpecialPowersPushPrefEnv.html]
 [test_SimpletestGetTestFileURL.html]
 [test_SpecialPowersLoadChromeScript.html]
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/Harness_sanity/test_sanityParams.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for exposing test suite information</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+ok(SimpleTest.harnessParameters, "Should have parameters.");
+</script>
+</body>
+</html>
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -45,16 +45,20 @@ var isPrimaryTestWindow = !!parent.TestR
                 parentRunner = w.wrappedJSObject.TestRunner;
             }
         }
         if (!window.SpecialPowers) {
             window.SpecialPowers = w.SpecialPowers;
         }
         w = ancestor(w);
     }
+
+    if (parentRunner) {
+        SimpleTest.harnessParameters = parentRunner.getParameterInfo();
+    }
 })();
 
 /* Helper functions pulled out of various MochiKit modules */
 if (typeof(repr) == 'undefined') {
     this.repr = function(o) {
         if (typeof(o) == "undefined") {
             return "undefined";
         } else if (o === null) {
@@ -835,17 +839,19 @@ SimpleTest.finish = function() {
                                + "functions at least once.  Make sure you use "
                                + "SimpleTest.waitForExplicitFinish() if you need "
                                + "it.)");
         }
 
         if (parentRunner) {
             /* We're running in an iframe, and the parent has a TestRunner */
             parentRunner.testFinished(SimpleTest._tests);
-        } else {
+        }
+
+        if (!parentRunner || parentRunner.showTestReport) {
             SpecialPowers.flushAllAppsLaunchable();
             SpecialPowers.flushPermissions(function () {
               SpecialPowers.flushPrefEnv(function() {
                 SimpleTest.showReport();
               });
             });
         }
     }
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -428,31 +428,46 @@ TestRunner.getLoadedTestURL = function (
     var prefix = "";
     // handle mochitest-chrome URIs
     if ($('testframe').contentWindow.location.protocol == "chrome:") {
       prefix = "chrome://mochitests";
     }
     return prefix + $('testframe').contentWindow.location.pathname;
 };
 
+TestRunner.setParameterInfo = function (params) {
+    this._params = params;
+};
+
+TestRunner.getParameterInfo = function() {
+    return this._params;
+};
+
 /**
  * TestRunner entry point.
  *
  * The arguments are the URLs of the test to be ran.
  *
 **/
 TestRunner.runTests = function (/*url...*/) {
     TestRunner.structuredLogger.info("SimpleTest START");
     TestRunner.originalTestURL = $("current-test").innerHTML;
 
     SpecialPowers.registerProcessCrashObservers();
 
     TestRunner._urls = flattenArguments(arguments);
 
-    $('testframe').src="";
+    var singleTestRun = this._urls.length <= 1 && TestRunner.repeat <= 1;
+    TestRunner.showTestReport = singleTestRun;
+    var frame = $('testframe');
+    frame.src="";
+    if (singleTestRun) {
+        document.body.setAttribute("singletest", singleTestRun);
+        frame.removeAttribute("scrolling");
+    }
     TestRunner._checkForHangs();
     TestRunner.runNextTest();
 };
 
 /**
  * Used for running a set of tests in a loop for debugging purposes
  * Takes an array of URLs
 **/
@@ -487,17 +502,20 @@ TestRunner.runNextTest = function() {
         TestRunner._expectedMinAsserts = 0;
         TestRunner._expectedMaxAsserts = 0;
 
         TestRunner.structuredLogger.testStart(url);
 
         TestRunner._makeIframe(url, 0);
     } else {
         $("current-test").innerHTML = "<b>Finished</b>";
-        TestRunner._makeIframe("about:blank", 0);
+        // Only unload the last test to run if we're running more than one test.
+        if (TestRunner._urls.length > 1) {
+            TestRunner._makeIframe("about:blank", 0);
+        }
 
         var passCount = parseInt($("pass-count").innerHTML, 10);
         var failCount = parseInt($("fail-count").innerHTML, 10);
         var todoCount = parseInt($("todo-count").innerHTML, 10);
 
         if (passCount === 0 &&
             failCount === 0 &&
             todoCount === 0)
@@ -630,16 +648,22 @@ TestRunner.testFinished = function(tests
 
         if (TestRunner.slowestTestTime < runtime && TestRunner._timeoutFactor == 1) {
           TestRunner.slowestTestTime = runtime;
           TestRunner.slowestTestURL = TestRunner.currentTestURL;
         }
 
         TestRunner.updateUI(tests);
 
+        // Don't show the interstitial if we just run one test with no repeats:
+        if (TestRunner._urls.length == 1 && TestRunner.repeat <= 1) {
+            TestRunner.testUnloaded();
+            return;
+        }
+
         var interstitialURL;
         if ($('testframe').contentWindow.location.protocol == "chrome:") {
             interstitialURL = "tests/SimpleTest/iframe-between-tests.html";
         } else {
             interstitialURL = "/tests/SimpleTest/iframe-between-tests.html";
         }
         TestRunner._makeIframe(interstitialURL, 0);
     }
--- a/testing/mochitest/tests/SimpleTest/setup.js
+++ b/testing/mochitest/tests/SimpleTest/setup.js
@@ -168,16 +168,17 @@ RunSet.runtests = function(e) {
   if (params.shuffle) {
     for (var i = my_tests.length-1; i > 0; --i) {
       var j = Math.floor(Math.random() * i);
       var tmp = my_tests[j];
       my_tests[j] = my_tests[i];
       my_tests[i] = tmp;
     }
   }
+  TestRunner.setParameterInfo(params);
   TestRunner.runTests(my_tests);
 }
 
 RunSet.reloadAndRunAll = function(e) {
   e.preventDefault();
   //window.location.hash = "";
   var addParam = "";
   if (params.autorun) {
--- a/testing/mochitest/tests/browser/browser.ini
+++ b/testing/mochitest/tests/browser/browser.ini
@@ -1,16 +1,17 @@
 [DEFAULT]
 support-files =
   head.js
 
 [browser_add_task.js]
 [browser_async.js]
 [browser_head.js]
 [browser_pass.js]
+[browser_parameters.js]
 [browser_popupNode.js]
 [browser_popupNode_check.js]
 [browser_privileges.js]
 [browser_sanityException.js]
 [browser_sanityException2.js]
 [browser_getTestFile.js]
 support-files =
   test-dir/*
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/browser/browser_parameters.js
@@ -0,0 +1,4 @@
+function test() {
+  ok(SimpleTest.harnessParameters, "Should have parameters");
+}
+