| 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>
|
|
|