Index: LayoutTests/fast/harness/dashboard.html |
diff --git a/LayoutTests/fast/harness/dashboard.html b/LayoutTests/fast/harness/dashboard.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bbba5cecfcf1e0a41998c89875ef504bfe6df49d |
--- /dev/null |
+++ b/LayoutTests/fast/harness/dashboard.html |
@@ -0,0 +1,808 @@ |
+<!DOCTYPE html> |
+<style> |
+html { |
+ height: 100%; |
+} |
+body { |
+ margin: 0; |
+ font-family: Helvetica, sans-serif; |
+ font-size: 11pt; |
+ display: -webkit-flex; |
+ -webkit-flex-direction: column; |
+ height: 100%; |
+} |
+ |
+body > * { |
+ margin-left: 4px; |
+ margin-top: 4px; |
+} |
+ |
+h1 { |
+ font-size: 14pt; |
+ margin-top: 1.5em; |
+} |
+ |
+p { |
+ margin-bottom: 0.3em; |
+} |
+ |
+tr { |
+ background-color: white; |
+} |
+ |
+tr:hover { |
+ background-color: #999999; |
+} |
+ |
+tr:not(.results-row) td { |
+ white-space: nowrap; |
+} |
+ |
+tr:not(.results-row) td:first-of-type { |
+ white-space: normal; |
+} |
+ |
+td:not(:first-of-type) { |
+ text-transform: lowercase; |
+} |
+ |
+td { |
+ padding: 1px 4px; |
+} |
+ |
+th:empty, td:empty { |
+ padding: 0; |
+} |
+ |
+th { |
+ -webkit-user-select: none; |
+ -moz-user-select: none; |
+} |
+ |
+.content-container { |
+ -webkit-flex: 1; |
+ min-height: -webkit-min-content; |
+ overflow: auto; |
+} |
+ |
+.note { |
+ color: gray; |
+ font-size: smaller; |
+} |
+ |
+.results-row { |
+ background-color: white; |
+} |
+ |
+.results-row iframe, .results-row img { |
+ width: 800px; |
+ height: 600px; |
+} |
+ |
+.results-row[data-expanded="false"] { |
+ display: none; |
+} |
+ |
+#toolbar { |
+ position: fixed; |
+ padding: 4px; |
+ top: 2px; |
+ right: 2px; |
+ text-align: right; |
+ background-color: rgba(255, 255, 255, 0.85); |
+ border: 1px solid silver; |
+ border-radius: 4px; |
+} |
+ |
+.expand-button { |
+ background-color: white; |
+ width: 11px; |
+ height: 12px; |
+ border: 1px solid gray; |
+ display: inline-block; |
+ margin: 0 3px 0 0; |
+ position: relative; |
+ cursor: default; |
+} |
+ |
+.current { |
+ color: red; |
+} |
+ |
+.current .expand-button { |
+ border-color: red; |
+} |
+ |
+.expand-button-text { |
+ position: absolute; |
+ top: -0.3em; |
+ left: 1px; |
+} |
+ |
+tbody .flag { |
+ display: none; |
+} |
+ |
+tbody.flagged .flag { |
+ display: inline; |
+} |
+ |
+.stopped-running-early-message { |
+ border: 3px solid #d00; |
+ font-weight: bold; |
+ display: inline-block; |
+ padding: 3px; |
+} |
+ |
+.result-container { |
+ display: inline-block; |
+ border: 1px solid gray; |
+ margin: 4px; |
+} |
+ |
+.result-container iframe, .result-container img { |
+ border: 0; |
+ vertical-align: top; |
+} |
+ |
+.label { |
+ padding-left: 3px; |
+ font-weight: bold; |
+ font-size: small; |
+ background-color: silver; |
+} |
+ |
+.pixel-zoom-container { |
+ position: fixed; |
+ top: 0; |
+ left: 0; |
+ width: 96%; |
+ margin: 10px; |
+ padding: 10px; |
+ display: -webkit-box; |
+ display: -moz-box; |
+ pointer-events: none; |
+ background-color: silver; |
+ border-radius: 20px; |
+ border: 1px solid gray; |
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.75); |
+} |
+ |
+.pixel-zoom-container > * { |
+ -webkit-box-flex: 1; |
+ -moz-box-flex: 1; |
+ border: 1px solid black; |
+ margin: 4px; |
+ overflow: hidden; |
+ background-color: white; |
+} |
+ |
+.pixel-zoom-container .scaled-image-container { |
+ position: relative; |
+ overflow: hidden; |
+ width: 100%; |
+ height: 400px; |
+} |
+ |
+.scaled-image-container > img { |
+ position: absolute; |
+ top: 0; |
+ left: 0; |
+ image-rendering: -webkit-optimize-contrast; |
+} |
+.test-pass { |
+ background-color:rgb(0,255,0); |
+} |
+.test-image-fail { |
+ background-color:rgb(0,128,255); |
+} |
+.test-text-fail { |
+ background-color:rgb(250,100,100); |
+} |
+.test-image-text-fail { |
+ background-color:rgb(161,128,250); |
+} |
+.test-flaky { |
+ background-color:rgb(255,0,255); |
+} |
+.test-missing { |
+ background-color:rgb(255,255,255); |
+} |
+.test-fail { |
+ background-color:rgb(255,0,0); |
+} |
+ |
+#flagged-tests { |
+ margin: 1px; |
+ padding: 5px; |
+ height: 100px; |
+} |
+ |
+#flagged-test-container h2 { |
+ display: inline-block; |
+ margin: 0 10px 0 0; |
+} |
+</style> |
+<style id="unexpected-pass-style"></style> |
+<style id="flaky-failures-style"></style> |
+<style id="stderr-style"></style> |
+<style id="unexpected-style"></style> |
+ |
+<script> |
+var g_state; |
+function globalState() |
+{ |
+ if (!g_state) { |
+ g_state = { |
+ crashTests: [], |
+ leakTests: [], |
+ flakyPassTests: [], |
+ hasHttpTests: false, |
+ hasImageFailures: false, |
+ hasTextFailures: false, |
+ missingResults: [], |
+ results: {}, |
+ failingTests: [], |
+ testsWithStderr: [], |
+ timeoutTests: [], |
+ unexpectedPassTests: [] |
+ } |
+ } |
+ return g_state; |
+} |
+ |
+function ADD_RESULTS(input) |
+{ |
+ globalState().results = input; |
+} |
+</script> |
+ |
+<script src="archived_results.json"></script> |
+ |
+<script> |
+ |
+function matchesSelector(node, selector) |
+{ |
+ if (node.webkitMatchesSelector) |
+ return node.webkitMatchesSelector(selector); |
+ |
+ if (node.mozMatchesSelector) |
+ return node.mozMatchesSelector(selector); |
+} |
+ |
+function parentOfType(node, selector) |
+{ |
+ while (node = node.parentNode) { |
+ if (matchesSelector(node, selector)) |
+ return node; |
+ } |
+ return null; |
+} |
+ |
+function remove(node) |
+{ |
+ node.parentNode.removeChild(node); |
+} |
+ |
+function forEach(nodeList, handler) |
+{ |
+ Array.prototype.forEach.call(nodeList, handler); |
+} |
+ |
+function resultIframe(src) |
+{ |
+ // FIXME: use audio tags for AUDIO tests? |
+ var layoutTestsIndex = src.indexOf('LayoutTests'); |
+ var name; |
+ if (layoutTestsIndex != -1) { |
+ var hasTrac = src.indexOf('trac.webkit.org') != -1; |
+ var prefix = hasTrac ? 'trac.webkit.org/.../' : ''; |
+ name = prefix + src.substring(layoutTestsIndex + 'LayoutTests/'.length); |
+ } else { |
+ var lastDashIndex = src.lastIndexOf('-pretty'); |
+ if (lastDashIndex == -1) |
+ lastDashIndex = src.lastIndexOf('-'); |
+ name = src.substring(lastDashIndex + 1); |
+ } |
+ |
+ var tagName = (src.lastIndexOf('.png') == -1) ? 'iframe' : 'img'; |
+ |
+ if (tagName != 'img') |
+ src += '?format=txt'; |
+ return '<div class=result-container><div class=label>' + name + '</div><' + tagName + ' src="' + src + '"></' + tagName + '></div>'; |
+} |
+ |
+function togglingImage(prefix) |
+{ |
+ return '<div class=result-container><div class="label imageText"></div><img class=animatedImage data-prefix="' + |
+ prefix + '"></img></div>'; |
+} |
+ |
+function appendHTML(node, html) |
+{ |
+ if (node.insertAdjacentHTML) |
+ node.insertAdjacentHTML('beforeEnd', html); |
+ else |
+ node.innerHTML += html; |
+} |
+ |
+function shouldUseTracLinks() |
+{ |
+ return !globalState().results.layout_tests_dir || !location.toString().indexOf('file://') == 0; |
+} |
+ |
+function testLinkTarget(test) |
+{ |
+ var target; |
+ if (shouldUseTracLinks()) { |
+ var revision = globalState().results.revision; |
+ target = 'http://src.chromium.org/viewvc/blink/trunk/LayoutTests/' + test; |
+ if (revision) |
+ target += '?pathrev=' + revision; |
+ target += '#l1'; |
+ } else |
+ target = globalState().results.layout_tests_dir + '/' + test; |
+ return target; |
+} |
+ |
+function testLink(test) |
+{ |
+ var target = testLinkTarget(test); |
+ return '<a class=test-link href="' + target + '">' + test + '</a>'; |
+} |
+ |
+function resultLink(testPrefix, suffix, contents) |
+{ |
+ return '<a class=result-link href="' + testPrefix + suffix + '" data-prefix="' + testPrefix + '">' + contents + '</a> '; |
+} |
+ |
+function processGlobalStateFor(testObject) |
+{ |
+ var test = testObject.name; |
+ if (testObject.has_stderr) |
+ globalState().testsWithStderr.push(testObject); |
+ |
+ globalState().hasHttpTests = globalState().hasHttpTests || test.indexOf('http/') == 0; |
+ |
+ var actual = testObject.actual; |
+ var expected = testObject.expected || 'PASS'; |
+ |
+ if (actual == 'MISSING') { |
+ // FIXME: make sure that new-run-webkit-tests spits out an -actual.txt file for |
+ // tests with MISSING results. |
+ globalState().missingResults.push(testObject); |
+ return; |
+ } |
+ |
+ var actualTokens = actual.split(' '); |
+ var passedWithImageOnlyFailureInRetry = actualTokens[0] == 'TEXT' && actualTokens[1] == 'IMAGE'; |
+ if (actualTokens[1] && actual.indexOf('PASS') != -1 || (!globalState().results.pixel_tests_enabled && passedWithImageOnlyFailureInRetry)) { |
+ globalState().flakyPassTests.push(testObject); |
+ return; |
+ } |
+ |
+ if (actual == 'PASS' && expected != 'PASS') { |
+ if (expected != 'IMAGE' || (globalState().results.pixel_tests_enabled || testObject.reftest_type)) { |
+ globalState().unexpectedPassTests.push(testObject); |
+ } |
+ return; |
+ } |
+ |
+ if (actual == 'CRASH') { |
+ globalState().crashTests.push(testObject); |
+ return; |
+ } |
+ |
+ if (actual == 'LEAK') { |
+ globalState().leakTests.push(testObject); |
+ return; |
+ } |
+ |
+ if (actual == 'TIMEOUT') { |
+ globalState().timeoutTests.push(testObject); |
+ return; |
+ } |
+ |
+ globalState().failingTests.push(testObject); |
+} |
+ |
+function getResultLink(index) |
+{ |
+ if(index < globalState().results.result_links.length) |
+ return globalState().results.result_links[index]; |
+ else |
+ return ''; |
+} |
+ |
+function processArchivedResults(archivedResults) |
+{ |
+ var result = ''; |
+ var i = 1; |
+ for (var i = 0; i < archivedResults.length; i++) { |
+ switch(archivedResults[i]) { |
+ case "PASS": |
+ result += '<td class=test-pass>'; |
+ break; |
+ case "IMAGE": |
+ result += '<td class=test-image-fail>'; |
+ break; |
+ case "TEXT": |
+ result += '<td class=test-text-fail>'; |
+ break; |
+ case "IMAGE+TEXT": |
+ result += '<td class=test-image-text-fail>'; |
+ break; |
+ case "NOTFOUND": |
+ result += '<td class=test-missing>'; |
+ break; |
+ case "SKIP": |
+ result += '<td class=test-missing>'; |
+ break; |
+ default: |
+ result += '<td class=test-fail>'; |
+ } |
+ result += '<a href="' + getResultLink(i) + '">' + (i+1).toString() + '</a>' + '</td>'; |
+ } |
+ |
+ return result; |
+} |
+ |
+function tableRow(testObject) |
+{ |
+ var row = '<tbody class="' + (testObject.is_unexpected ? '' : 'expected') + '"'; |
+ if (testObject.reftest_type && testObject.reftest_type.indexOf('!=') != -1) |
+ row += ' mismatchreftest=true'; |
+ row += '><tr>'; |
+ |
+ row += '<td>' + testLink(testObject.name) + '</td>'; |
+ |
+ var archivedResults = testObject.archived_results; |
+ row += processArchivedResults(archivedResults); |
+ row += '</tr></tbody>'; |
+ return row; |
+} |
+ |
+function forEachTest(handler, opt_tree, opt_prefix) |
+{ |
+ var tree = opt_tree || globalState().results.tests; |
+ var prefix = opt_prefix || ''; |
+ |
+ for (var key in tree) { |
+ var newPrefix = prefix ? (prefix + '/' + key) : key; |
+ if ('actual' in tree[key]) { |
+ var testObject = tree[key]; |
+ testObject.name = newPrefix; |
+ handler(testObject); |
+ } else |
+ forEachTest(handler, tree[key], newPrefix); |
+ } |
+} |
+ |
+function hasUnexpected(tests) |
+{ |
+ return tests.some(function (test) { return test.is_unexpected; }); |
+} |
+ |
+function updateTestlistCounts() |
+{ |
+ forEach(document.querySelectorAll('.test-list-count'), function(count) { |
+ var container = parentOfType(count, 'div'); |
+ var testContainers; |
+ if (onlyShowUnexpectedFailures()) |
+ testContainers = container.querySelectorAll('tbody:not(.expected)'); |
+ else |
+ testContainers = container.querySelectorAll('tbody'); |
+ |
+ count.textContent = testContainers.length; |
+ |
+ }) |
+} |
+ |
+function testListHeaderHtml(header) |
+{ |
+ return '<h1>' + header + ' (<span class=test-list-count></span>): </h1>'; |
+} |
+ |
+function testList(tests, header, tableId) |
+{ |
+ tests.sort(); |
+ |
+ var html = '<div' + ((!hasUnexpected(tests) && tableId != 'stderr-table') ? ' class=expected' : '') + ' id=' + tableId + '>' + |
+ testListHeaderHtml(header) + '<table>'; |
+ |
+ // FIXME: Include this for all testLists. |
+ if (tableId == 'passes-table') |
+ html += '<thead><th>test</th><th>expected</th></thead>'; |
+ |
+ for (var i = 0; i < tests.length; i++) { |
+ var testObject = tests[i]; |
+ var test = testObject.name; |
+ html += '<tbody class="' + ((testObject.is_unexpected || tableId == 'stderr-table') ? '' : 'expected') + '"><tr><td>' + |
+ testLink(test) + |
+ '</td>'; |
+ |
+ html += processArchivedResults(testObject.archived_results) |
+ html += '</tr></tbody>'; |
+ } |
+ html += '</table></div>'; |
+ return html; |
+} |
+ |
+function toArray(nodeList) |
+{ |
+ return Array.prototype.slice.call(nodeList); |
+} |
+ |
+function trim(string) |
+{ |
+ return string.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); |
+} |
+ |
+// Just a namespace for code management. |
+var TableSorter = {}; |
+ |
+TableSorter._forwardArrow = '<svg style="width:10px;height:10px"><polygon points="0,0 10,0 5,10" style="fill:#ccc"></svg>'; |
+ |
+TableSorter._backwardArrow = '<svg style="width:10px;height:10px"><polygon points="0,10 10,10 5,0" style="fill:#ccc"></svg>'; |
+ |
+TableSorter._sortedContents = function(header, arrow) |
+{ |
+ return arrow + ' ' + trim(header.textContent) + ' ' + arrow; |
+} |
+ |
+TableSorter._updateHeaderClassNames = function(newHeader) |
+{ |
+ var sortHeader = document.querySelector('.sortHeader'); |
+ if (sortHeader) { |
+ if (sortHeader == newHeader) { |
+ var isAlreadyReversed = sortHeader.classList.contains('reversed'); |
+ if (isAlreadyReversed) |
+ sortHeader.classList.remove('reversed'); |
+ else |
+ sortHeader.classList.add('reversed'); |
+ } else { |
+ sortHeader.textContent = sortHeader.textContent; |
+ sortHeader.classList.remove('sortHeader'); |
+ sortHeader.classList.remove('reversed'); |
+ } |
+ } |
+ |
+ newHeader.classList.add('sortHeader'); |
+} |
+ |
+TableSorter._textContent = function(tbodyRow, column) |
+{ |
+ return tbodyRow.querySelectorAll('td')[column].textContent; |
+} |
+ |
+TableSorter._sortRows = function(newHeader, reversed) |
+{ |
+ var testsTable = document.getElementById('results-table'); |
+ var headers = toArray(testsTable.querySelectorAll('th')); |
+ var sortColumn = headers.indexOf(newHeader); |
+ |
+ var rows = toArray(testsTable.querySelectorAll('tbody')); |
+ |
+ rows.sort(function(a, b) { |
+ // Only need to support lexicographic sort for now. |
+ var aText = TableSorter._textContent(a, sortColumn); |
+ var bText = TableSorter._textContent(b, sortColumn); |
+ |
+ // Forward sort equal values by test name. |
+ if (sortColumn && aText == bText) { |
+ var aTestName = TableSorter._textContent(a, 0); |
+ var bTestName = TableSorter._textContent(b, 0); |
+ if (aTestName == bTestName) |
+ return 0; |
+ return aTestName < bTestName ? -1 : 1; |
+ } |
+ |
+ if (reversed) |
+ return aText < bText ? 1 : -1; |
+ else |
+ return aText < bText ? -1 : 1; |
+ }); |
+ |
+ for (var i = 0; i < rows.length; i++) |
+ testsTable.appendChild(rows[i]); |
+} |
+ |
+TableSorter.sortColumn = function(columnNumber) |
+{ |
+ var newHeader = document.getElementById('results-table').querySelectorAll('th')[columnNumber]; |
+ TableSorter._sort(newHeader); |
+} |
+ |
+TableSorter.handleClick = function(e) |
+{ |
+ var newHeader = e.target; |
+ if (newHeader.localName != 'th') |
+ return; |
+ TableSorter._sort(newHeader); |
+} |
+ |
+TableSorter._sort = function(newHeader) |
+{ |
+ TableSorter._updateHeaderClassNames(newHeader); |
+ |
+ var reversed = newHeader.classList.contains('reversed'); |
+ var sortArrow = reversed ? TableSorter._backwardArrow : TableSorter._forwardArrow; |
+ newHeader.innerHTML = TableSorter._sortedContents(newHeader, sortArrow); |
+ |
+ TableSorter._sortRows(newHeader, reversed); |
+} |
+ |
+document.addEventListener('keypress', TestNavigator.handleKeyEvent, false); |
+ |
+function onlyShowUnexpectedFailures() |
+{ |
+ return !document.getElementById('show-expected-failures').checked; |
+} |
+ |
+function handleStderrChange() |
+{ |
+ OptionWriter.save(); |
+ document.getElementById('stderr-style').textContent = document.getElementById('show-stderr').checked ? |
+ '' : '#stderr-table { display: none; }'; |
+} |
+ |
+function handleUnexpectedPassesChange() |
+{ |
+ OptionWriter.save(); |
+ document.getElementById('unexpected-pass-style').textContent = document.getElementById('show-unexpected-passes').checked ? |
+ '' : '#passes-table { display: none; }'; |
+} |
+ |
+function handleFlakyFailuresChange() |
+{ |
+ OptionWriter.save(); |
+ document.getElementById('flaky-failures-style').textContent = document.getElementById('show-flaky-failures').checked ? |
+ '' : '.flaky { display: none; }'; |
+} |
+ |
+function handleUnexpectedResultsChange() |
+{ |
+ OptionWriter.save(); |
+ updateExpectedFailures(); |
+} |
+ |
+function updateExpectedFailures() |
+{ |
+ document.getElementById('unexpected-style').textContent = onlyShowUnexpectedFailures() ? |
+ '.expected { display: none; }' : ''; |
+ |
+ updateTestlistCounts(); |
+ TestNavigator.onlyShowUnexpectedFailuresChanged(); |
+} |
+ |
+var OptionWriter = {}; |
+ |
+OptionWriter._key = 'run-webkit-tests-options'; |
+ |
+OptionWriter.save = function() |
+{ |
+ var options = document.querySelectorAll('label input'); |
+ var data = {}; |
+ for (var i = 0, len = options.length; i < len; i++) { |
+ var option = options[i]; |
+ data[option.id] = option.checked; |
+ } |
+ localStorage.setItem(OptionWriter._key, JSON.stringify(data)); |
+} |
+ |
+OptionWriter.apply = function() |
+{ |
+ var json = localStorage.getItem(OptionWriter._key); |
+ if (!json) { |
+ updateAllOptions(); |
+ return; |
+ } |
+ |
+ var data = JSON.parse(json); |
+ for (var id in data) { |
+ var input = document.getElementById(id); |
+ if (input) |
+ input.checked = data[id]; |
+ } |
+ updateAllOptions(); |
+} |
+ |
+function updateAllOptions() |
+{ |
+ forEach(document.querySelectorAll('input'), function(input) { input.onchange(); }); |
+} |
+ |
+function failingTestsTable(tests, title, id) |
+{ |
+ if (!tests.length) |
+ return ''; |
+ |
+ var numberofUnexpectedFailures = 0; |
+ var tableRowHtml = ''; |
+ for (var i = 0; i < tests.length; i++){ |
+ tableRowHtml += tableRow(tests[i]); |
+ if (tests[i].is_unexpected) |
+ numberofUnexpectedFailures++; |
+ } |
+ |
+ var className = ''; |
+ if (id) |
+ className += id.split('-')[0]; |
+ if (!hasUnexpected(tests)) |
+ className += ' expected'; |
+ |
+ var header = '<div'; |
+ if (className) |
+ header += ' class="' + className + '"'; |
+ |
+ header += '>' + testListHeaderHtml(title) + |
+ '<table id="' + id + '"><thead><tr>' + |
+ '<th>test</th>'; |
+ |
+ header += '</tr></thead>'; |
+ |
+ |
+ return header + tableRowHtml + '</table></div>'; |
+} |
+ |
+function generatePage() |
+{ |
+ forEachTest(processGlobalStateFor); |
+ |
+ var html = '<div><div id=toolbar>' + |
+ '<div id=container>Show: '+ |
+ '<label><input id="show-expected-failures" type=checkbox onchange="handleUnexpectedResultsChange()">expected failures</label>' + |
+ '<label><input id="show-flaky-failures" type=checkbox onchange="handleFlakyFailuresChange()">flaky failures</label>' + |
+ '<label><input id="show-unexpected-passes" type=checkbox onchange="handleUnexpectedPassesChange()">unexpected passes</label>' + |
+ '<label><input id="show-stderr" type=checkbox onchange="handleStderrChange()">stderr</label>' + |
+ '</div></div>'; |
+ |
+ if (globalState().results.interrupted) |
+ html += "<p class='stopped-running-early-message'>Testing exited early.</p>" |
+ |
+ if (globalState().crashTests.length) |
+ html += testList(globalState().crashTests, 'Tests that crashed', 'crash-tests-table'); |
+ |
+ if (globalState().leakTests.length) |
+ html += testList(globalState().leakTests, 'Tests that leaked', 'leak-tests-table'); |
+ |
+ html += failingTestsTable(globalState().failingTests, |
+ 'Tests that failed text/pixel/audio diff', 'results-table'); |
+ |
+ html += failingTestsTable(globalState().missingResults, |
+ 'Tests that had no expected results (probably new)', 'missing-table'); |
+ |
+ if (globalState().timeoutTests.length) |
+ html += testList(globalState().timeoutTests, 'Tests that timed out', 'timeout-tests-table'); |
+ |
+ if (globalState().testsWithStderr.length) |
+ html += testList(globalState().testsWithStderr, 'Tests that had stderr output', 'stderr-table'); |
+ |
+ html += failingTestsTable(globalState().flakyPassTests, |
+ 'Flaky tests (failed the first run and passed on retry)', 'flaky-tests-table'); |
+ |
+ if (globalState().unexpectedPassTests.length) |
+ html += testList(globalState().unexpectedPassTests, 'Tests expected to fail but passed', 'passes-table'); |
+ |
+ html += '</div>'; |
+ |
+ |
+ document.body.innerHTML = html; |
+ |
+ if (document.getElementById('results-table')) { |
+ document.getElementById('results-table').addEventListener('click', TableSorter.handleClick, false); |
+ TableSorter.sortColumn(0); |
+ if (!globalState().hasTextFailures) |
+ document.getElementById('text-results-header').textContent = ''; |
+ if (!globalState().hasImageFailures) { |
+ document.getElementById('image-results-header').textContent = ''; |
+ parentOfType(document.getElementById('toggle-images'), 'label').style.display = 'none'; |
+ } |
+ } |
+ |
+ updateTestlistCounts(); |
+ |
+ OptionWriter.apply(); |
+} |
+</script> |
+<body onload="generatePage()"></body> |