Bug 429690: add ability to run browser tests individually, r=Mossop
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -37,27 +37,29 @@
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<window id="browserTestHarness"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="TestStart();"
- title="Browser chrome tests">
+ title="Browser chrome tests"
+ width="1024">
<script src="chrome://mochikit/content/tests/SimpleTest/MozillaFileLogger.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/quit.js"/>
<style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
#results {
margin: 5px;
background-color: window;
-moz-user-select: text;
}
#summary {
+ color: white;
border: 2px solid black;
}
#summary.success {
background-color: green;
}
#summary.failure {
@@ -82,17 +84,17 @@
function TestStart() {
gConfig = readConfig();
// If MochiTest was started with the --test-path flag specifying a subset
// of tests to run, put that path in the label of the "Run Tests" button
// so the tester knows which tests will run when they press that button.
if (gConfig.testPath)
document.getElementById("runTestsButton").label =
- "Run " + gConfig.testPath + " Tests";
+ "Run " + gConfig.testPath + " tests";
if (gConfig.autoRun)
setTimeout(runAllTests, 0);
}
function readConfig() {
var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
@@ -182,37 +184,53 @@
function listTests() {
const Cc = Components.classes; const Ci = Components.interfaces;
var ioSvc = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var testsDir = getChromeDir();
testsDir.appendRelativePath("browser");
+
+ var requestPath = "chrome://mochikit/content/browser";
+ var fileNameRegexp = /browser_.+\.js$/;
+
if (gConfig.testPath) {
var testsDirURI = ioSvc.newFileURI(testsDir);
testsDir = ioSvc.newURI(gConfig.testPath, null, testsDirURI)
.QueryInterface(Ci.nsIFileURL).file;
+
+ // Invalid testPath...
+ if (!testsDir.exists())
+ return [];
+
+ // If we were passed a specific file, run only that test.
+ if (testsDir.isFile()) {
+ if (fileNameRegexp.test(testsDir.leafName))
+ return [new browserTestFile(requestPath + "/" + gConfig.testPath)];
+
+ // We were passed a file that's not a test...
+ return [];
+ }
+
+ // otherwise, we were passed a directory of tests
+ requestPath += "/" + gConfig.testPath;
}
- /** load server.js in so we can share template functions **/
+ // 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);
- var requestPath = "chrome://mochikit/content/browser";
- if (gConfig.testPath)
- requestPath += "/" + gConfig.testPath;
+ var [links, ] = srvScope.list(requestPath, testsDir, true);
+ var fileNames = [];
+ srvScope.arrayOfTestFiles(links, fileNames, fileNameRegexp);
- var [links, count] = srvScope.list(requestPath, testsDir, true);
- var fileNames = [];
- srvScope.arrayOfTestFiles(links, fileNames, /browser_.+\.js$/);
-
- return fileNames.map(function (f) new browserTestFile(f));;
+ return fileNames.map(function (f) new browserTestFile(f));
}
function setStatus(aStatusString) {
document.getElementById("status").value = aStatusString;
}
function runAllTests() {
var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
@@ -221,20 +239,27 @@
setStatus("Running...");
testWin.focus();
var Tester = new testWin.Tester(listTests(), testsFinished);
Tester.start();
}
+ function sum(a, b) {
+ return a + b;
+ }
+
function getHTMLLogFromTests(aTests) {
+ if (!aTests.length)
+ return "<div id=\"summary\" class=\"success\">No tests to run. " +
+ "Did you pass an invalid --test-path?</div>";
+
var log = "";
- function sum(a, b){ return a + b; }
var passCount = aTests.map(function (f) f.passCount).reduce(sum);
var failCount = aTests.map(function (f) f.failCount).reduce(sum);
var todoCount = aTests.map(function (f) f.todoCount).reduce(sum);
log += "<div id=\"summary\" class=\"";
log += failCount == 0 ? "success" : "failure";
log += "\">\n<p>Passed: " + passCount + "</p>\n" +
"<p>Failed: " + failCount + "</p>\n" +
"<p>Todo: " + todoCount + "</p>\n</div>\n<div id=\"log\">\n";
@@ -250,17 +275,17 @@
var log = aTests.map(function (f) {
var output = f.path + "\n";
if (f.log)
output += f.log + "\n";
return output;
}).join("");
log += "\nBrowser Chrome Test Summary\n";
- function sum(a, b){ return a + b; }
+
var passCount = aTests.map(function (f) f.passCount).reduce(sum);
var failCount = aTests.map(function (f) f.failCount).reduce(sum);
var todoCount = aTests.map(function (f) f.todoCount).reduce(sum);
log += "\tPass: " + passCount + "\n\tFail: " + failCount + "\n\tTodo: " + todoCount + "\n";
return log;
}
@@ -290,11 +315,11 @@
// UI
document.getElementById("results").innerHTML = getHTMLLogFromTests(aTests);
setStatus("Done.");
}
]]></script>
<button id="runTestsButton" onclick="runAllTests();" label="Run All Tests"/>
<label id="status"/>
<scrollbox flex="1" style="overflow: auto" align="stretch">
- <div id="results" xmlns="http://www.w3.org/1999/xhtml"/>
+ <div id="results" xmlns="http://www.w3.org/1999/xhtml" flex="1"/>
</scrollbox>
</window>
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -37,17 +37,20 @@ Tester.prototype = {
get done() {
return this.currentTestIndex == this.tests.length - 1;
},
step: function Tester_step() {
this.currentTestIndex++;
},
start: function Tester_start() {
- this.execTest();
+ if (this.tests.length)
+ this.execTest();
+ else
+ this.finish();
},
finish: function Tester_finish() {
// Tests complete, notify the callback and return
this.callback(this.tests);
this.callback = null;
this.tests = null;
},