1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/tests/SimpleTest/TestRunner.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,618 @@ 1.4 +/* -*- js-indent-level: 4 -*- */ 1.5 +/* 1.6 + * e10s event dispatcher from content->chrome 1.7 + * 1.8 + * type = eventName (QuitApplication) 1.9 + * data = json object {"filename":filename} <- for LoggerInit 1.10 + */ 1.11 +function getElement(id) { 1.12 + return ((typeof(id) == "string") ? 1.13 + document.getElementById(id) : id); 1.14 +} 1.15 + 1.16 +this.$ = this.getElement; 1.17 + 1.18 +function contentDispatchEvent(type, data, sync) { 1.19 + if (typeof(data) == "undefined") { 1.20 + data = {}; 1.21 + } 1.22 + 1.23 + var event = new CustomEvent("contentEvent", { 1.24 + bubbles: true, 1.25 + detail: { 1.26 + "sync": sync, 1.27 + "type": type, 1.28 + "data": JSON.stringify(data) 1.29 + } 1.30 + }); 1.31 + document.dispatchEvent(event); 1.32 +} 1.33 + 1.34 +function contentAsyncEvent(type, data) { 1.35 + contentDispatchEvent(type, data, 0); 1.36 +} 1.37 + 1.38 +/* Helper Function */ 1.39 +function extend(obj, /* optional */ skip) { 1.40 + // Extend an array with an array-like object starting 1.41 + // from the skip index 1.42 + if (!skip) { 1.43 + skip = 0; 1.44 + } 1.45 + if (obj) { 1.46 + var l = obj.length; 1.47 + var ret = []; 1.48 + for (var i = skip; i < l; i++) { 1.49 + ret.push(obj[i]); 1.50 + } 1.51 + } 1.52 + return ret; 1.53 +} 1.54 + 1.55 +function flattenArguments(lst/* ...*/) { 1.56 + var res = []; 1.57 + var args = extend(arguments); 1.58 + while (args.length) { 1.59 + var o = args.shift(); 1.60 + if (o && typeof(o) == "object" && typeof(o.length) == "number") { 1.61 + for (var i = o.length - 1; i >= 0; i--) { 1.62 + args.unshift(o[i]); 1.63 + } 1.64 + } else { 1.65 + res.push(o); 1.66 + } 1.67 + } 1.68 + return res; 1.69 +} 1.70 + 1.71 +/** 1.72 + * TestRunner: A test runner for SimpleTest 1.73 + * TODO: 1.74 + * 1.75 + * * Avoid moving iframes: That causes reloads on mozilla and opera. 1.76 + * 1.77 + * 1.78 +**/ 1.79 +var TestRunner = {}; 1.80 +TestRunner.logEnabled = false; 1.81 +TestRunner._currentTest = 0; 1.82 +TestRunner._lastTestFinished = -1; 1.83 +TestRunner._loopIsRestarting = false; 1.84 +TestRunner.currentTestURL = ""; 1.85 +TestRunner.originalTestURL = ""; 1.86 +TestRunner._urls = []; 1.87 +TestRunner._lastAssertionCount = 0; 1.88 +TestRunner._expectedMinAsserts = 0; 1.89 +TestRunner._expectedMaxAsserts = 0; 1.90 + 1.91 +TestRunner.timeout = 5 * 60 * 1000; // 5 minutes. 1.92 +TestRunner.maxTimeouts = 4; // halt testing after too many timeouts 1.93 +TestRunner.runSlower = false; 1.94 +TestRunner.dumpOutputDirectory = ""; 1.95 +TestRunner.dumpAboutMemoryAfterTest = false; 1.96 +TestRunner.dumpDMDAfterTest = false; 1.97 +TestRunner.quiet = false; 1.98 +TestRunner.slowestTestTime = 0; 1.99 +TestRunner.slowestTestURL = ""; 1.100 + 1.101 +TestRunner._expectingProcessCrash = false; 1.102 + 1.103 +/** 1.104 + * Make sure the tests don't hang indefinitely. 1.105 +**/ 1.106 +TestRunner._numTimeouts = 0; 1.107 +TestRunner._currentTestStartTime = new Date().valueOf(); 1.108 +TestRunner._timeoutFactor = 1; 1.109 + 1.110 +TestRunner._checkForHangs = function() { 1.111 + function reportError(win, msg) { 1.112 + if ("SimpleTest" in win) { 1.113 + win.SimpleTest.ok(false, msg); 1.114 + } else if ("W3CTest" in win) { 1.115 + win.W3CTest.logFailure(msg); 1.116 + } 1.117 + } 1.118 + 1.119 + function killTest(win) { 1.120 + if ("SimpleTest" in win) { 1.121 + win.SimpleTest.finish(); 1.122 + } else if ("W3CTest" in win) { 1.123 + win.W3CTest.timeout(); 1.124 + } 1.125 + } 1.126 + 1.127 + if (TestRunner._currentTest < TestRunner._urls.length) { 1.128 + var runtime = new Date().valueOf() - TestRunner._currentTestStartTime; 1.129 + if (runtime >= TestRunner.timeout * TestRunner._timeoutFactor) { 1.130 + var frameWindow = $('testframe').contentWindow.wrappedJSObject || 1.131 + $('testframe').contentWindow; 1.132 + reportError(frameWindow, "Test timed out."); 1.133 + 1.134 + // If we have too many timeouts, give up. We don't want to wait hours 1.135 + // for results if some bug causes lots of tests to time out. 1.136 + if (++TestRunner._numTimeouts >= TestRunner.maxTimeouts) { 1.137 + TestRunner._haltTests = true; 1.138 + 1.139 + TestRunner.currentTestURL = "(SimpleTest/TestRunner.js)"; 1.140 + reportError(frameWindow, TestRunner.maxTimeouts + " test timeouts, giving up."); 1.141 + var skippedTests = TestRunner._urls.length - TestRunner._currentTest; 1.142 + reportError(frameWindow, "Skipping " + skippedTests + " remaining tests."); 1.143 + } 1.144 + 1.145 + // Add a little (1 second) delay to ensure automation.py has time to notice 1.146 + // "Test timed out" log and process it (= take a screenshot). 1.147 + setTimeout(function delayedKillTest() { killTest(frameWindow); }, 1000); 1.148 + 1.149 + if (TestRunner._haltTests) 1.150 + return; 1.151 + } 1.152 + 1.153 + setTimeout(TestRunner._checkForHangs, 30000); 1.154 + } 1.155 +} 1.156 + 1.157 +TestRunner.requestLongerTimeout = function(factor) { 1.158 + TestRunner._timeoutFactor = factor; 1.159 +} 1.160 + 1.161 +/** 1.162 + * This is used to loop tests 1.163 +**/ 1.164 +TestRunner.repeat = 0; 1.165 +TestRunner._currentLoop = 1; 1.166 + 1.167 +TestRunner.expectAssertions = function(min, max) { 1.168 + if (typeof(max) == "undefined") { 1.169 + max = min; 1.170 + } 1.171 + if (typeof(min) != "number" || typeof(max) != "number" || 1.172 + min < 0 || max < min) { 1.173 + throw "bad parameter to expectAssertions"; 1.174 + } 1.175 + TestRunner._expectedMinAsserts = min; 1.176 + TestRunner._expectedMaxAsserts = max; 1.177 +} 1.178 + 1.179 +/** 1.180 + * This function is called after generating the summary. 1.181 +**/ 1.182 +TestRunner.onComplete = null; 1.183 + 1.184 +/** 1.185 + * Adds a failed test case to a list so we can rerun only the failed tests 1.186 + **/ 1.187 +TestRunner._failedTests = {}; 1.188 +TestRunner._failureFile = ""; 1.189 + 1.190 +TestRunner.addFailedTest = function(testName) { 1.191 + if (TestRunner._failedTests[testName] == undefined) { 1.192 + TestRunner._failedTests[testName] = ""; 1.193 + } 1.194 +}; 1.195 + 1.196 +TestRunner.setFailureFile = function(fileName) { 1.197 + TestRunner._failureFile = fileName; 1.198 +} 1.199 + 1.200 +TestRunner.generateFailureList = function () { 1.201 + if (TestRunner._failureFile) { 1.202 + var failures = new SpecialPowersLogger(TestRunner._failureFile); 1.203 + failures.log(JSON.stringify(TestRunner._failedTests)); 1.204 + failures.close(); 1.205 + } 1.206 +}; 1.207 + 1.208 +/** 1.209 + * If logEnabled is true, this is the logger that will be used. 1.210 +**/ 1.211 +TestRunner.logger = LogController; 1.212 + 1.213 +TestRunner.log = function(msg) { 1.214 + if (TestRunner.logEnabled) { 1.215 + TestRunner.logger.log(msg); 1.216 + } else { 1.217 + dump(msg + "\n"); 1.218 + } 1.219 +}; 1.220 + 1.221 +TestRunner.error = function(msg) { 1.222 + if (TestRunner.logEnabled) { 1.223 + TestRunner.logger.error(msg); 1.224 + } else { 1.225 + dump(msg + "\n"); 1.226 + } 1.227 + 1.228 + if (TestRunner.runUntilFailure) { 1.229 + TestRunner._haltTests = true; 1.230 + } 1.231 + 1.232 + if (TestRunner.debugOnFailure) { 1.233 + // You've hit this line because you requested to break into the 1.234 + // debugger upon a testcase failure on your test run. 1.235 + debugger; 1.236 + } 1.237 +}; 1.238 + 1.239 +/** 1.240 + * Toggle element visibility 1.241 +**/ 1.242 +TestRunner._toggle = function(el) { 1.243 + if (el.className == "noshow") { 1.244 + el.className = ""; 1.245 + el.style.cssText = ""; 1.246 + } else { 1.247 + el.className = "noshow"; 1.248 + el.style.cssText = "width:0px; height:0px; border:0px;"; 1.249 + } 1.250 +}; 1.251 + 1.252 +/** 1.253 + * Creates the iframe that contains a test 1.254 +**/ 1.255 +TestRunner._makeIframe = function (url, retry) { 1.256 + var iframe = $('testframe'); 1.257 + if (url != "about:blank" && 1.258 + (("hasFocus" in document && !document.hasFocus()) || 1.259 + ("activeElement" in document && document.activeElement != iframe))) { 1.260 + 1.261 + contentAsyncEvent("Focus"); 1.262 + window.focus(); 1.263 + SpecialPowers.focus(); 1.264 + iframe.focus(); 1.265 + if (retry < 3) { 1.266 + window.setTimeout('TestRunner._makeIframe("'+url+'", '+(retry+1)+')', 1000); 1.267 + return; 1.268 + } 1.269 + 1.270 + TestRunner.log("Error: Unable to restore focus, expect failures and timeouts."); 1.271 + } 1.272 + window.scrollTo(0, $('indicator').offsetTop); 1.273 + iframe.src = url; 1.274 + iframe.name = url; 1.275 + iframe.width = "500"; 1.276 + return iframe; 1.277 +}; 1.278 + 1.279 +/** 1.280 + * Returns the current test URL. 1.281 + * We use this to tell whether the test has navigated to another test without 1.282 + * being finished first. 1.283 + */ 1.284 +TestRunner.getLoadedTestURL = function () { 1.285 + var prefix = ""; 1.286 + // handle mochitest-chrome URIs 1.287 + if ($('testframe').contentWindow.location.protocol == "chrome:") { 1.288 + prefix = "chrome://mochitests"; 1.289 + } 1.290 + return prefix + $('testframe').contentWindow.location.pathname; 1.291 +}; 1.292 + 1.293 +/** 1.294 + * TestRunner entry point. 1.295 + * 1.296 + * The arguments are the URLs of the test to be ran. 1.297 + * 1.298 +**/ 1.299 +TestRunner.runTests = function (/*url...*/) { 1.300 + TestRunner.log("SimpleTest START"); 1.301 + TestRunner.originalTestURL = $("current-test").innerHTML; 1.302 + 1.303 + SpecialPowers.registerProcessCrashObservers(); 1.304 + 1.305 + TestRunner._urls = flattenArguments(arguments); 1.306 + $('testframe').src=""; 1.307 + TestRunner._checkForHangs(); 1.308 + TestRunner.runNextTest(); 1.309 +}; 1.310 + 1.311 +/** 1.312 + * Used for running a set of tests in a loop for debugging purposes 1.313 + * Takes an array of URLs 1.314 +**/ 1.315 +TestRunner.resetTests = function(listURLs) { 1.316 + TestRunner._currentTest = 0; 1.317 + // Reset our "Current-test" line - functionality depends on it 1.318 + $("current-test").innerHTML = TestRunner.originalTestURL; 1.319 + if (TestRunner.logEnabled) 1.320 + TestRunner.log("SimpleTest START Loop " + TestRunner._currentLoop); 1.321 + 1.322 + TestRunner._urls = listURLs; 1.323 + $('testframe').src=""; 1.324 + TestRunner._checkForHangs(); 1.325 + TestRunner.runNextTest(); 1.326 +} 1.327 + 1.328 +/** 1.329 + * Run the next test. If no test remains, calls onComplete(). 1.330 + **/ 1.331 +TestRunner._haltTests = false; 1.332 +TestRunner.runNextTest = function() { 1.333 + if (TestRunner._currentTest < TestRunner._urls.length && 1.334 + !TestRunner._haltTests) 1.335 + { 1.336 + var url = TestRunner._urls[TestRunner._currentTest]; 1.337 + TestRunner.currentTestURL = url; 1.338 + 1.339 + $("current-test-path").innerHTML = url; 1.340 + 1.341 + TestRunner._currentTestStartTime = new Date().valueOf(); 1.342 + TestRunner._timeoutFactor = 1; 1.343 + TestRunner._expectedMinAsserts = 0; 1.344 + TestRunner._expectedMaxAsserts = 0; 1.345 + 1.346 + TestRunner.log("TEST-START | " + url); // used by automation.py 1.347 + 1.348 + TestRunner._makeIframe(url, 0); 1.349 + } else { 1.350 + $("current-test").innerHTML = "<b>Finished</b>"; 1.351 + TestRunner._makeIframe("about:blank", 0); 1.352 + 1.353 + if (parseInt($("pass-count").innerHTML) == 0 && 1.354 + parseInt($("fail-count").innerHTML) == 0 && 1.355 + parseInt($("todo-count").innerHTML) == 0) 1.356 + { 1.357 + // No |$('testframe').contentWindow|, so manually update: ... 1.358 + // ... the log, 1.359 + TestRunner.error("TEST-UNEXPECTED-FAIL | (SimpleTest/TestRunner.js) | No checks actually run."); 1.360 + // ... the count, 1.361 + $("fail-count").innerHTML = 1; 1.362 + // ... the indicator. 1.363 + var indicator = $("indicator"); 1.364 + indicator.innerHTML = "Status: Fail (No checks actually run)"; 1.365 + indicator.style.backgroundColor = "red"; 1.366 + } 1.367 + 1.368 + SpecialPowers.unregisterProcessCrashObservers(); 1.369 + 1.370 + TestRunner.log("TEST-START | Shutdown"); // used by automation.py 1.371 + TestRunner.log("Passed: " + $("pass-count").innerHTML); 1.372 + TestRunner.log("Failed: " + $("fail-count").innerHTML); 1.373 + TestRunner.log("Todo: " + $("todo-count").innerHTML); 1.374 + TestRunner.log("Slowest: " + TestRunner.slowestTestTime + 'ms - ' + TestRunner.slowestTestURL); 1.375 + // If we are looping, don't send this cause it closes the log file 1.376 + if (TestRunner.repeat == 0) { 1.377 + TestRunner.log("SimpleTest FINISHED"); 1.378 + } 1.379 + 1.380 + if (TestRunner.repeat == 0 && TestRunner.onComplete) { 1.381 + TestRunner.onComplete(); 1.382 + } 1.383 + 1.384 + if (TestRunner._currentLoop <= TestRunner.repeat && !TestRunner._haltTests) { 1.385 + TestRunner._currentLoop++; 1.386 + TestRunner.resetTests(TestRunner._urls); 1.387 + TestRunner._loopIsRestarting = true; 1.388 + } else { 1.389 + // Loops are finished 1.390 + if (TestRunner.logEnabled) { 1.391 + TestRunner.log("TEST-INFO | Ran " + TestRunner._currentLoop + " Loops"); 1.392 + TestRunner.log("SimpleTest FINISHED"); 1.393 + } 1.394 + 1.395 + if (TestRunner.onComplete) 1.396 + TestRunner.onComplete(); 1.397 + } 1.398 + TestRunner.generateFailureList(); 1.399 + } 1.400 +}; 1.401 + 1.402 +TestRunner.expectChildProcessCrash = function() { 1.403 + TestRunner._expectingProcessCrash = true; 1.404 +}; 1.405 + 1.406 +/** 1.407 + * This stub is called by SimpleTest when a test is finished. 1.408 +**/ 1.409 +TestRunner.testFinished = function(tests) { 1.410 + // Prevent a test from calling finish() multiple times before we 1.411 + // have a chance to unload it. 1.412 + if (TestRunner._currentTest == TestRunner._lastTestFinished && 1.413 + !TestRunner._loopIsRestarting) { 1.414 + TestRunner.error("TEST-UNEXPECTED-FAIL | " + 1.415 + TestRunner.currentTestURL + 1.416 + " | called finish() multiple times"); 1.417 + TestRunner.updateUI([{ result: false }]); 1.418 + return; 1.419 + } 1.420 + TestRunner._lastTestFinished = TestRunner._currentTest; 1.421 + TestRunner._loopIsRestarting = false; 1.422 + 1.423 + MemoryStats.dump(TestRunner.log, TestRunner._currentTest, 1.424 + TestRunner.currentTestURL, 1.425 + TestRunner.dumpOutputDirectory, 1.426 + TestRunner.dumpAboutMemoryAfterTest, 1.427 + TestRunner.dumpDMDAfterTest); 1.428 + 1.429 + function cleanUpCrashDumpFiles() { 1.430 + if (!SpecialPowers.removeExpectedCrashDumpFiles(TestRunner._expectingProcessCrash)) { 1.431 + TestRunner.error("TEST-UNEXPECTED-FAIL | " + 1.432 + TestRunner.currentTestURL + 1.433 + " | This test did not leave any crash dumps behind, but we were expecting some!"); 1.434 + tests.push({ result: false }); 1.435 + } 1.436 + var unexpectedCrashDumpFiles = 1.437 + SpecialPowers.findUnexpectedCrashDumpFiles(); 1.438 + TestRunner._expectingProcessCrash = false; 1.439 + if (unexpectedCrashDumpFiles.length) { 1.440 + TestRunner.error("TEST-UNEXPECTED-FAIL | " + 1.441 + TestRunner.currentTestURL + 1.442 + " | This test left crash dumps behind, but we " + 1.443 + "weren't expecting it to!"); 1.444 + tests.push({ result: false }); 1.445 + unexpectedCrashDumpFiles.sort().forEach(function(aFilename) { 1.446 + TestRunner.log("TEST-INFO | Found unexpected crash dump file " + 1.447 + aFilename + "."); 1.448 + }); 1.449 + } 1.450 + } 1.451 + 1.452 + function runNextTest() { 1.453 + if (TestRunner.currentTestURL != TestRunner.getLoadedTestURL()) { 1.454 + TestRunner.error("TEST-UNEXPECTED-FAIL | " + 1.455 + TestRunner.currentTestURL + 1.456 + " | " + TestRunner.getLoadedTestURL() + 1.457 + " finished in a non-clean fashion, probably" + 1.458 + " because it didn't call SimpleTest.finish()"); 1.459 + tests.push({ result: false }); 1.460 + } 1.461 + 1.462 + var runtime = new Date().valueOf() - TestRunner._currentTestStartTime; 1.463 + TestRunner.log("TEST-END | " + 1.464 + TestRunner.currentTestURL + 1.465 + " | finished in " + runtime + "ms"); 1.466 + if (TestRunner.slowestTestTime < runtime && TestRunner._timeoutFactor == 1) { 1.467 + TestRunner.slowestTestTime = runtime; 1.468 + TestRunner.slowestTestURL = TestRunner.currentTestURL; 1.469 + } 1.470 + 1.471 + TestRunner.updateUI(tests); 1.472 + 1.473 + var interstitialURL; 1.474 + if ($('testframe').contentWindow.location.protocol == "chrome:") { 1.475 + interstitialURL = "tests/SimpleTest/iframe-between-tests.html"; 1.476 + } else { 1.477 + interstitialURL = "/tests/SimpleTest/iframe-between-tests.html"; 1.478 + } 1.479 + TestRunner._makeIframe(interstitialURL, 0); 1.480 + } 1.481 + 1.482 + SpecialPowers.executeAfterFlushingMessageQueue(function() { 1.483 + cleanUpCrashDumpFiles(); 1.484 + SpecialPowers.flushAllAppsLaunchable(); 1.485 + SpecialPowers.flushPermissions(function () { SpecialPowers.flushPrefEnv(runNextTest); }); 1.486 + }); 1.487 +}; 1.488 + 1.489 +TestRunner.testUnloaded = function() { 1.490 + // If we're in a debug build, check assertion counts. This code is 1.491 + // similar to the code in Tester_nextTest in browser-test.js used 1.492 + // for browser-chrome mochitests. 1.493 + if (SpecialPowers.isDebugBuild) { 1.494 + var newAssertionCount = SpecialPowers.assertionCount(); 1.495 + var numAsserts = newAssertionCount - TestRunner._lastAssertionCount; 1.496 + TestRunner._lastAssertionCount = newAssertionCount; 1.497 + 1.498 + var url = TestRunner._urls[TestRunner._currentTest]; 1.499 + var max = TestRunner._expectedMaxAsserts; 1.500 + var min = TestRunner._expectedMinAsserts; 1.501 + if (numAsserts > max) { 1.502 + TestRunner.error("TEST-UNEXPECTED-FAIL | " + url + " | Assertion count " + numAsserts + " is greater than expected range " + min + "-" + max + " assertions."); 1.503 + TestRunner.updateUI([{ result: false }]); 1.504 + } else if (numAsserts < min) { 1.505 + TestRunner.error("TEST-UNEXPECTED-PASS | " + url + " | Assertion count " + numAsserts + " is less than expected range " + min + "-" + max + " assertions."); 1.506 + TestRunner.updateUI([{ result: false }]); 1.507 + } else if (numAsserts > 0) { 1.508 + TestRunner.log("TEST-KNOWN-FAIL | " + url + " | Assertion count " + numAsserts + " within expected range " + min + "-" + max + " assertions."); 1.509 + } 1.510 + } 1.511 + TestRunner._currentTest++; 1.512 + if (TestRunner.runSlower) { 1.513 + setTimeout(TestRunner.runNextTest, 1000); 1.514 + } else { 1.515 + TestRunner.runNextTest(); 1.516 + } 1.517 +}; 1.518 + 1.519 +/** 1.520 + * Get the results. 1.521 + */ 1.522 +TestRunner.countResults = function(tests) { 1.523 + var nOK = 0; 1.524 + var nNotOK = 0; 1.525 + var nTodo = 0; 1.526 + for (var i = 0; i < tests.length; ++i) { 1.527 + var test = tests[i]; 1.528 + if (test.todo && !test.result) { 1.529 + nTodo++; 1.530 + } else if (test.result && !test.todo) { 1.531 + nOK++; 1.532 + } else { 1.533 + nNotOK++; 1.534 + } 1.535 + } 1.536 + return {"OK": nOK, "notOK": nNotOK, "todo": nTodo}; 1.537 +} 1.538 + 1.539 +/** 1.540 + * Print out table of any error messages found during looped run 1.541 + */ 1.542 +TestRunner.displayLoopErrors = function(tableName, tests) { 1.543 + if(TestRunner.countResults(tests).notOK >0){ 1.544 + var table = $(tableName); 1.545 + var curtest; 1.546 + if (table.rows.length == 0) { 1.547 + //if table headers are not yet generated, make them 1.548 + var row = table.insertRow(table.rows.length); 1.549 + var cell = row.insertCell(0); 1.550 + var textNode = document.createTextNode("Test File Name:"); 1.551 + cell.appendChild(textNode); 1.552 + cell = row.insertCell(1); 1.553 + textNode = document.createTextNode("Test:"); 1.554 + cell.appendChild(textNode); 1.555 + cell = row.insertCell(2); 1.556 + textNode = document.createTextNode("Error message:"); 1.557 + cell.appendChild(textNode); 1.558 + } 1.559 + 1.560 + //find the broken test 1.561 + for (var testnum in tests){ 1.562 + curtest = tests[testnum]; 1.563 + if( !((curtest.todo && !curtest.result) || (curtest.result && !curtest.todo)) ){ 1.564 + //this is a failed test or the result of todo test. Display the related message 1.565 + row = table.insertRow(table.rows.length); 1.566 + cell = row.insertCell(0); 1.567 + textNode = document.createTextNode(TestRunner.currentTestURL); 1.568 + cell.appendChild(textNode); 1.569 + cell = row.insertCell(1); 1.570 + textNode = document.createTextNode(curtest.name); 1.571 + cell.appendChild(textNode); 1.572 + cell = row.insertCell(2); 1.573 + textNode = document.createTextNode((curtest.diag ? curtest.diag : "" )); 1.574 + cell.appendChild(textNode); 1.575 + } 1.576 + } 1.577 + } 1.578 +} 1.579 + 1.580 +TestRunner.updateUI = function(tests) { 1.581 + var results = TestRunner.countResults(tests); 1.582 + var passCount = parseInt($("pass-count").innerHTML) + results.OK; 1.583 + var failCount = parseInt($("fail-count").innerHTML) + results.notOK; 1.584 + var todoCount = parseInt($("todo-count").innerHTML) + results.todo; 1.585 + $("pass-count").innerHTML = passCount; 1.586 + $("fail-count").innerHTML = failCount; 1.587 + $("todo-count").innerHTML = todoCount; 1.588 + 1.589 + // Set the top Green/Red bar 1.590 + var indicator = $("indicator"); 1.591 + if (failCount > 0) { 1.592 + indicator.innerHTML = "Status: Fail"; 1.593 + indicator.style.backgroundColor = "red"; 1.594 + } else if (passCount > 0) { 1.595 + indicator.innerHTML = "Status: Pass"; 1.596 + indicator.style.backgroundColor = "#0d0"; 1.597 + } else { 1.598 + indicator.innerHTML = "Status: ToDo"; 1.599 + indicator.style.backgroundColor = "orange"; 1.600 + } 1.601 + 1.602 + // Set the table values 1.603 + var trID = "tr-" + $('current-test-path').innerHTML; 1.604 + var row = $(trID); 1.605 + 1.606 + // Only update the row if it actually exists (autoUI) 1.607 + if (row != null) { 1.608 + var tds = row.getElementsByTagName("td"); 1.609 + tds[0].style.backgroundColor = "#0d0"; 1.610 + tds[0].innerHTML = parseInt(tds[0].innerHTML) + parseInt(results.OK); 1.611 + tds[1].style.backgroundColor = results.notOK > 0 ? "red" : "#0d0"; 1.612 + tds[1].innerHTML = parseInt(tds[1].innerHTML) + parseInt(results.notOK); 1.613 + tds[2].style.backgroundColor = results.todo > 0 ? "orange" : "#0d0"; 1.614 + tds[2].innerHTML = parseInt(tds[2].innerHTML) + parseInt(results.todo); 1.615 + } 1.616 + 1.617 + //if we ran in a loop, display any found errors 1.618 + if (TestRunner.repeat > 0) { 1.619 + TestRunner.displayLoopErrors('fail-table', tests); 1.620 + } 1.621 +}