mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
1409 lines
41 KiB
HTML
1409 lines
41 KiB
HTML
<!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: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;
|
|
}
|
|
|
|
#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: {},
|
|
shouldToggleImages: true,
|
|
failingTests: [],
|
|
testsWithStderr: [],
|
|
timeoutTests: [],
|
|
unexpectedPassTests: []
|
|
}
|
|
}
|
|
return g_state;
|
|
}
|
|
|
|
function ADD_RESULTS(input)
|
|
{
|
|
globalState().results = input;
|
|
}
|
|
</script>
|
|
|
|
<script src="failing_results.json"></script>
|
|
|
|
<script>
|
|
function stripExtension(test)
|
|
{
|
|
var index = test.lastIndexOf('.');
|
|
return test.substring(0, index);
|
|
}
|
|
|
|
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('tests');
|
|
var name;
|
|
if (layoutTestsIndex != -1) {
|
|
var hasTrac = src.indexOf('trac.webkit.org') != -1;
|
|
var prefix = hasTrac ? 'trac.webkit.org/.../' : '';
|
|
name = prefix + src.substring(layoutTestsIndex + 'tests/'.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 toggleExpectations(element)
|
|
{
|
|
var expandLink = element;
|
|
if (expandLink.className != 'expand-button-text')
|
|
expandLink = expandLink.querySelector('.expand-button-text');
|
|
|
|
if (expandLink.textContent == '+')
|
|
expandExpectations(expandLink);
|
|
else
|
|
collapseExpectations(expandLink);
|
|
}
|
|
|
|
function collapseExpectations(expandLink)
|
|
{
|
|
expandLink.textContent = '+';
|
|
var existingResultsRow = parentOfType(expandLink, 'tbody').querySelector('.results-row');
|
|
if (existingResultsRow)
|
|
updateExpandedState(existingResultsRow, false);
|
|
}
|
|
|
|
function updateExpandedState(row, isExpanded)
|
|
{
|
|
row.setAttribute('data-expanded', isExpanded);
|
|
updateImageTogglingTimer();
|
|
}
|
|
|
|
function appendHTML(node, html)
|
|
{
|
|
node.innerHTML += html;
|
|
}
|
|
|
|
function expandExpectations(expandLink)
|
|
{
|
|
var row = parentOfType(expandLink, 'tr');
|
|
var parentTbody = row.parentNode;
|
|
var existingResultsRow = parentTbody.querySelector('.results-row');
|
|
|
|
var enDash = '\u2013';
|
|
expandLink.textContent = enDash;
|
|
if (existingResultsRow) {
|
|
updateExpandedState(existingResultsRow, true);
|
|
return;
|
|
}
|
|
|
|
var newRow = document.createElement('tr');
|
|
newRow.className = 'results-row';
|
|
var newCell = document.createElement('td');
|
|
newCell.colSpan = row.querySelectorAll('td').length;
|
|
|
|
var resultLinks = row.querySelectorAll('.result-link');
|
|
var hasTogglingImages = false;
|
|
for (var i = 0; i < resultLinks.length; i++) {
|
|
var link = resultLinks[i];
|
|
var result;
|
|
if (link.textContent == 'images') {
|
|
hasTogglingImages = true;
|
|
result = togglingImage(link.getAttribute('data-prefix'));
|
|
} else
|
|
result = resultIframe(link.href);
|
|
|
|
appendHTML(newCell, result);
|
|
}
|
|
|
|
newRow.appendChild(newCell);
|
|
parentTbody.appendChild(newRow);
|
|
|
|
updateExpandedState(newRow, true);
|
|
|
|
updateImageTogglingTimer();
|
|
}
|
|
|
|
function updateImageTogglingTimer()
|
|
{
|
|
var hasVisibleAnimatedImage = document.querySelector('.results-row[data-expanded="true"] .animatedImage');
|
|
if (!hasVisibleAnimatedImage) {
|
|
clearInterval(globalState().togglingImageInterval);
|
|
globalState().togglingImageInterval = null;
|
|
return;
|
|
}
|
|
|
|
if (!globalState().togglingImageInterval) {
|
|
toggleImages();
|
|
globalState().togglingImageInterval = setInterval(toggleImages, 2000);
|
|
}
|
|
}
|
|
|
|
function async(func, args)
|
|
{
|
|
setTimeout(function() { func.apply(null, args); }, 100);
|
|
}
|
|
|
|
function visibleTests(opt_container)
|
|
{
|
|
var container = opt_container || document;
|
|
if (onlyShowUnexpectedFailures())
|
|
return container.querySelectorAll('tbody:not(.expected)');
|
|
else
|
|
return container.querySelectorAll('tbody');
|
|
}
|
|
|
|
function visibleExpandLinks()
|
|
{
|
|
if (onlyShowUnexpectedFailures())
|
|
return document.querySelectorAll('tbody:not(.expected) .expand-button-text');
|
|
else
|
|
return document.querySelectorAll('.expand-button-text');
|
|
}
|
|
|
|
function expandAllExpectations()
|
|
{
|
|
var expandLinks = visibleExpandLinks();
|
|
for (var i = 0, len = expandLinks.length; i < len; i++)
|
|
async(expandExpectations, [expandLinks[i]]);
|
|
}
|
|
|
|
function collapseAllExpectations()
|
|
{
|
|
var expandLinks = visibleExpandLinks();
|
|
for (var i = 0, len = expandLinks.length; i < len; i++)
|
|
async(collapseExpectations, [expandLinks[i]]);
|
|
}
|
|
|
|
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/tests/' + 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><span class=flag onclick="unflag(this)"> \u2691</span>';
|
|
}
|
|
|
|
function unflag(flag)
|
|
{
|
|
var shouldFlag = false;
|
|
TestNavigator.flagTest(parentOfType(flag, 'tbody'), shouldFlag);
|
|
}
|
|
|
|
function testLinkWithExpandButton(test)
|
|
{
|
|
return '<span class=expand-button onclick="toggleExpectations(this)"><span class=expand-button-text>+</span></span>' + testLink(test);
|
|
}
|
|
|
|
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 toggleImages()
|
|
{
|
|
var images = document.querySelectorAll('.animatedImage');
|
|
var imageTexts = document.querySelectorAll('.imageText');
|
|
for (var i = 0, len = images.length; i < len; i++) {
|
|
var image = images[i];
|
|
var text = imageTexts[i];
|
|
if (text.textContent == 'Expected Image') {
|
|
text.textContent = 'Actual Image';
|
|
image.src = image.getAttribute('data-prefix') + '-actual.png';
|
|
} else {
|
|
text.textContent = 'Expected Image';
|
|
image.src = image.getAttribute('data-prefix') + '-expected.png';
|
|
}
|
|
}
|
|
}
|
|
|
|
function textResultLinks(test, prefix)
|
|
{
|
|
var html = resultLink(prefix, '-expected.txt', 'expected') +
|
|
resultLink(prefix, '-actual.txt', 'actual') +
|
|
resultLink(prefix, '-diff.txt', 'diff');
|
|
|
|
if (globalState().results.has_pretty_patch)
|
|
html += resultLink(prefix, '-pretty-diff.html', 'pretty diff');
|
|
|
|
if (globalState().results.has_wdiff)
|
|
html += resultLink(prefix, '-wdiff.html', 'wdiff');
|
|
|
|
return html;
|
|
}
|
|
|
|
function imageResultsCell(testObject, testPrefix, actual) {
|
|
var row = '';
|
|
|
|
if (actual.indexOf('IMAGE') != -1) {
|
|
globalState().hasImageFailures = true;
|
|
|
|
if (testObject.reftest_type && testObject.reftest_type.indexOf('!=') != -1) {
|
|
row += resultLink(testPrefix, '-expected-mismatch.sky', 'ref mismatch html');
|
|
row += resultLink(testPrefix, '-actual.png', 'actual');
|
|
} else {
|
|
if (testObject.reftest_type && testObject.reftest_type.indexOf('==') != -1) {
|
|
row += resultLink(testPrefix, '-expected.sky', 'ref html');
|
|
}
|
|
if (globalState().shouldToggleImages) {
|
|
row += resultLink(testPrefix, '-diffs.html', 'images');
|
|
} else {
|
|
row += resultLink(testPrefix, '-expected.png', 'expected');
|
|
row += resultLink(testPrefix, '-actual.png', 'actual');
|
|
}
|
|
|
|
row += resultLink(testPrefix, '-diff.png', 'diff');
|
|
}
|
|
}
|
|
|
|
if (actual.indexOf('MISSING') != -1 && testObject.is_missing_image)
|
|
row += resultLink(testPrefix, '-actual.png', 'png result');
|
|
|
|
return row;
|
|
}
|
|
|
|
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>' + testLinkWithExpandButton(testObject.name) + '</td>';
|
|
|
|
var testPrefix = stripExtension(testObject.name);
|
|
row += '<td>';
|
|
|
|
var actual = testObject.actual;
|
|
if (actual.indexOf('TEXT') != -1) {
|
|
globalState().hasTextFailures = true;
|
|
if (testObject.is_testharness_test) {
|
|
row += resultLink(testPrefix, '-actual.txt', 'actual');
|
|
} else {
|
|
row += textResultLinks(testObject.name, testPrefix);
|
|
}
|
|
}
|
|
|
|
if (actual.indexOf('AUDIO') != -1) {
|
|
row += resultLink(testPrefix, '-expected.wav', 'expected audio');
|
|
row += resultLink(testPrefix, '-actual.wav', 'actual audio');
|
|
}
|
|
|
|
if (actual.indexOf('MISSING') != -1) {
|
|
if (testObject.is_missing_audio)
|
|
row += resultLink(testPrefix, '-actual.wav', 'audio result');
|
|
if (testObject.is_missing_text)
|
|
row += resultLink(testPrefix, '-actual.txt', 'result');
|
|
}
|
|
|
|
if (actual.indexOf('CRASH') != -1) {
|
|
row += resultLink(testPrefix, '-crash-log.txt', 'crash log');
|
|
row += resultLink(testPrefix, '-sample.txt', 'sample');
|
|
if (testObject.has_stderr)
|
|
row += resultLink(testPrefix, '-stderr.txt', 'stderr');
|
|
}
|
|
|
|
if (testObject.has_repaint_overlay)
|
|
row += resultLink(testPrefix, '-overlay.html?' + encodeURIComponent(testLinkTarget(testObject.name)), 'overlay');
|
|
|
|
var actualTokens = actual.split(/\s+/);
|
|
var cell = imageResultsCell(testObject, testPrefix, actualTokens[0]);
|
|
if (!cell && actualTokens.length > 1)
|
|
cell = imageResultsCell(testObject, 'retries/' + testPrefix, actualTokens[1]);
|
|
|
|
row += '</td><td>' + cell + '</td>' +
|
|
'<td>' + actual + '</td>' +
|
|
'<td>' + (actual.indexOf('MISSING') == -1 ? testObject.expected : '') + '</td>' +
|
|
'</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 flagAll(headerLink)
|
|
{
|
|
var tests = visibleTests(parentOfType(headerLink, 'div'));
|
|
forEach(tests, function(test) {
|
|
var shouldFlag = true;
|
|
TestNavigator.flagTest(test, shouldFlag);
|
|
})
|
|
}
|
|
|
|
function testListHeaderHtml(header)
|
|
{
|
|
return '<h1>' + header + ' (<span class=test-list-count></span>): <a href="#" class=flag-all onclick="flagAll(this)">flag all</a></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>' +
|
|
((tableId == 'passes-table') ? testLink(test) : testLinkWithExpandButton(test)) +
|
|
'</td><td>';
|
|
|
|
if (tableId == 'stderr-table')
|
|
html += resultLink(stripExtension(test), '-stderr.txt', 'stderr');
|
|
else if (tableId == 'passes-table')
|
|
html += testObject.expected;
|
|
else if (tableId == 'crash-tests-table') {
|
|
html += resultLink(stripExtension(test), '-crash-log.txt', 'crash log');
|
|
html += resultLink(stripExtension(test), '-sample.txt', 'sample');
|
|
if (testObject.has_stderr)
|
|
html += resultLink(stripExtension(test), '-stderr.txt', 'stderr');
|
|
} else if (tableId == 'leak-tests-table')
|
|
html += resultLink(stripExtension(test), '-leak-log.txt', 'leak log');
|
|
else if (tableId == 'timeout-tests-table') {
|
|
// FIXME: only include timeout actual/diff results here if we actually spit out results for timeout tests.
|
|
html += textResultLinks(test, stripExtension(test));
|
|
}
|
|
|
|
if (testObject.has_repaint_overlay)
|
|
html += resultLink(stripExtension(test), '-overlay.html?' + encodeURIComponent(testLinkTarget(test)), 'overlay');
|
|
|
|
html += '</td></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);
|
|
}
|
|
|
|
var PixelZoomer = {};
|
|
|
|
PixelZoomer.showOnDelay = true;
|
|
PixelZoomer._zoomFactor = 6;
|
|
|
|
var kResultWidth = 800;
|
|
var kResultHeight = 600;
|
|
|
|
var kZoomedResultWidth = kResultWidth * PixelZoomer._zoomFactor;
|
|
var kZoomedResultHeight = kResultHeight * PixelZoomer._zoomFactor;
|
|
|
|
PixelZoomer._zoomImageContainer = function(url)
|
|
{
|
|
var container = document.createElement('div');
|
|
container.className = 'zoom-image-container';
|
|
|
|
var title = url.match(/\-([^\-]*)\.png/)[1];
|
|
|
|
var label = document.createElement('div');
|
|
label.className = 'label';
|
|
label.appendChild(document.createTextNode(title));
|
|
container.appendChild(label);
|
|
|
|
var imageContainer = document.createElement('div');
|
|
imageContainer.className = 'scaled-image-container';
|
|
|
|
var image = new Image();
|
|
image.src = url;
|
|
image.style.display = 'none';
|
|
|
|
var canvas = document.createElement('canvas');
|
|
|
|
imageContainer.appendChild(image);
|
|
imageContainer.appendChild(canvas);
|
|
container.appendChild(imageContainer);
|
|
|
|
return container;
|
|
}
|
|
|
|
PixelZoomer._createContainer = function(e)
|
|
{
|
|
var tbody = parentOfType(e.target, 'tbody');
|
|
var row = tbody.querySelector('tr');
|
|
var imageDiffLinks = row.querySelectorAll('a[href$=".png"]');
|
|
|
|
var container = document.createElement('div');
|
|
container.className = 'pixel-zoom-container';
|
|
|
|
var html = '';
|
|
|
|
var togglingImageLink = row.querySelector('a[href$="-diffs.html"]');
|
|
if (togglingImageLink) {
|
|
var prefix = togglingImageLink.getAttribute('data-prefix');
|
|
container.appendChild(PixelZoomer._zoomImageContainer(prefix + '-expected.png'));
|
|
container.appendChild(PixelZoomer._zoomImageContainer(prefix + '-actual.png'));
|
|
}
|
|
|
|
for (var i = 0; i < imageDiffLinks.length; i++)
|
|
container.appendChild(PixelZoomer._zoomImageContainer(imageDiffLinks[i].href));
|
|
|
|
document.body.appendChild(container);
|
|
PixelZoomer._drawAll();
|
|
}
|
|
|
|
PixelZoomer._draw = function(imageContainer)
|
|
{
|
|
var image = imageContainer.querySelector('img');
|
|
var canvas = imageContainer.querySelector('canvas');
|
|
|
|
if (!image.complete) {
|
|
image.onload = function() {
|
|
PixelZoomer._draw(imageContainer);
|
|
};
|
|
return;
|
|
}
|
|
|
|
canvas.width = imageContainer.clientWidth;
|
|
canvas.height = imageContainer.clientHeight;
|
|
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.mozImageSmoothingEnabled = false;
|
|
ctx.imageSmoothingEnabled = false;
|
|
ctx.translate(imageContainer.clientWidth / 2, imageContainer.clientHeight / 2);
|
|
ctx.translate(-PixelZoomer._percentX * kZoomedResultWidth, -PixelZoomer._percentY * kZoomedResultHeight);
|
|
ctx.strokeRect(-1.5, -1.5, kZoomedResultWidth + 2, kZoomedResultHeight + 2);
|
|
ctx.scale(PixelZoomer._zoomFactor, PixelZoomer._zoomFactor);
|
|
ctx.drawImage(image, 0, 0);
|
|
}
|
|
|
|
PixelZoomer._drawAll = function()
|
|
{
|
|
forEach(document.querySelectorAll('.pixel-zoom-container .scaled-image-container'), PixelZoomer._draw);
|
|
}
|
|
|
|
PixelZoomer.handleMouseOut = function(e)
|
|
{
|
|
if (e.relatedTarget && e.relatedTarget.tagName != 'IFRAME')
|
|
return;
|
|
|
|
// If e.relatedTarget is null, we've moused out of the document.
|
|
var container = document.querySelector('.pixel-zoom-container');
|
|
if (container)
|
|
remove(container);
|
|
}
|
|
|
|
PixelZoomer.handleMouseMove = function(e) {
|
|
if (PixelZoomer._mouseMoveTimeout)
|
|
clearTimeout(PixelZoomer._mouseMoveTimeout);
|
|
|
|
if (parentOfType(e.target, '.pixel-zoom-container'))
|
|
return;
|
|
|
|
var container = document.querySelector('.pixel-zoom-container');
|
|
|
|
var resultContainer = (e.target.className == 'result-container') ?
|
|
e.target : parentOfType(e.target, '.result-container');
|
|
if (!resultContainer || !resultContainer.querySelector('img')) {
|
|
if (container)
|
|
remove(container);
|
|
return;
|
|
}
|
|
|
|
var targetLocation = e.target.getBoundingClientRect();
|
|
PixelZoomer._percentX = (e.clientX - targetLocation.left) / targetLocation.width;
|
|
PixelZoomer._percentY = (e.clientY - targetLocation.top) / targetLocation.height;
|
|
|
|
if (!container) {
|
|
if (PixelZoomer.showOnDelay) {
|
|
PixelZoomer._mouseMoveTimeout = setTimeout(function() {
|
|
PixelZoomer._createContainer(e);
|
|
}, 400);
|
|
return;
|
|
}
|
|
|
|
PixelZoomer._createContainer(e);
|
|
return;
|
|
}
|
|
|
|
PixelZoomer._drawAll();
|
|
}
|
|
|
|
document.addEventListener('mousemove', PixelZoomer.handleMouseMove, false);
|
|
document.addEventListener('mouseout', PixelZoomer.handleMouseOut, false);
|
|
|
|
var TestNavigator = {};
|
|
|
|
TestNavigator.reset = function() {
|
|
TestNavigator.currentTestIndex = -1;
|
|
TestNavigator.flaggedTests = {};
|
|
TestNavigator._createFlaggedTestContainer();
|
|
}
|
|
|
|
TestNavigator.handleKeyEvent = function(event)
|
|
{
|
|
if (event.metaKey || event.shiftKey || event.ctrlKey)
|
|
return;
|
|
|
|
switch (String.fromCharCode(event.charCode)) {
|
|
case 'i':
|
|
TestNavigator._scrollToFirstTest();
|
|
break;
|
|
case 'j':
|
|
TestNavigator._scrollToNextTest();
|
|
break;
|
|
case 'k':
|
|
TestNavigator._scrollToPreviousTest();
|
|
break;
|
|
case 'l':
|
|
TestNavigator._scrollToLastTest();
|
|
break;
|
|
case 'e':
|
|
TestNavigator._expandCurrentTest();
|
|
break;
|
|
case 'c':
|
|
TestNavigator._collapseCurrentTest();
|
|
break;
|
|
case 't':
|
|
TestNavigator._toggleCurrentTest();
|
|
break;
|
|
case 'f':
|
|
TestNavigator._toggleCurrentTestFlagged();
|
|
break;
|
|
}
|
|
}
|
|
|
|
TestNavigator._scrollToFirstTest = function()
|
|
{
|
|
if (TestNavigator._setCurrentTest(0))
|
|
TestNavigator._scrollToCurrentTest();
|
|
}
|
|
|
|
TestNavigator._scrollToLastTest = function()
|
|
{
|
|
var links = visibleTests();
|
|
if (TestNavigator._setCurrentTest(links.length - 1))
|
|
TestNavigator._scrollToCurrentTest();
|
|
}
|
|
|
|
TestNavigator._scrollToNextTest = function()
|
|
{
|
|
if (TestNavigator.currentTestIndex == -1)
|
|
TestNavigator._scrollToFirstTest();
|
|
else if (TestNavigator._setCurrentTest(TestNavigator.currentTestIndex + 1))
|
|
TestNavigator._scrollToCurrentTest();
|
|
}
|
|
|
|
TestNavigator._scrollToPreviousTest = function()
|
|
{
|
|
if (TestNavigator.currentTestIndex == -1)
|
|
TestNavigator._scrollToLastTest();
|
|
else if (TestNavigator._setCurrentTest(TestNavigator.currentTestIndex - 1))
|
|
TestNavigator._scrollToCurrentTest();
|
|
}
|
|
|
|
TestNavigator._currentTestLink = function()
|
|
{
|
|
var links = visibleTests();
|
|
return links[TestNavigator.currentTestIndex];
|
|
}
|
|
|
|
TestNavigator._currentTestExpandLink = function()
|
|
{
|
|
return TestNavigator._currentTestLink().querySelector('.expand-button-text');
|
|
}
|
|
|
|
TestNavigator._expandCurrentTest = function()
|
|
{
|
|
expandExpectations(TestNavigator._currentTestExpandLink());
|
|
}
|
|
|
|
TestNavigator._collapseCurrentTest = function()
|
|
{
|
|
collapseExpectations(TestNavigator._currentTestExpandLink());
|
|
}
|
|
|
|
TestNavigator._toggleCurrentTest = function()
|
|
{
|
|
toggleExpectations(TestNavigator._currentTestExpandLink());
|
|
}
|
|
|
|
TestNavigator._toggleCurrentTestFlagged = function()
|
|
{
|
|
var testLink = TestNavigator._currentTestLink();
|
|
TestNavigator.flagTest(testLink, !testLink.classList.contains('flagged'));
|
|
}
|
|
|
|
// FIXME: Test navigator shouldn't know anything about flagging. It should probably call out to TestFlagger or something.
|
|
TestNavigator.flagTest = function(testTbody, shouldFlag)
|
|
{
|
|
var testName = testTbody.querySelector('.test-link').innerText;
|
|
|
|
if (shouldFlag) {
|
|
testTbody.classList.add('flagged');
|
|
TestNavigator.flaggedTests[testName] = 1;
|
|
} else {
|
|
testTbody.classList.remove('flagged');
|
|
delete TestNavigator.flaggedTests[testName];
|
|
}
|
|
|
|
TestNavigator.updateFlaggedTests();
|
|
}
|
|
|
|
TestNavigator._createFlaggedTestContainer = function()
|
|
{
|
|
var flaggedTestContainer = document.createElement('div');
|
|
flaggedTestContainer.id = 'flagged-test-container';
|
|
flaggedTestContainer.innerHTML = '<h2>Flagged Tests</h2>' +
|
|
'<label title="Use newlines instead of spaces to separate flagged tests">' +
|
|
'<input id="use-newlines" type=checkbox checked onchange="handleToggleUseNewlines()">Use newlines</input>' +
|
|
'</label>' +
|
|
'<pre id="flagged-tests" contentEditable></pre>';
|
|
document.body.appendChild(flaggedTestContainer);
|
|
}
|
|
|
|
TestNavigator.updateFlaggedTests = function()
|
|
{
|
|
var flaggedTestTextbox = document.getElementById('flagged-tests');
|
|
var flaggedTests = Object.keys(this.flaggedTests);
|
|
flaggedTests.sort();
|
|
var separator = document.getElementById('use-newlines').checked ? '\n' : ' ';
|
|
flaggedTestTextbox.innerHTML = flaggedTests.join(separator);
|
|
document.getElementById('flagged-test-container').style.display = flaggedTests.length ? '' : 'none';
|
|
}
|
|
|
|
TestNavigator._setCurrentTest = function(testIndex)
|
|
{
|
|
var links = visibleTests();
|
|
if (testIndex < 0 || testIndex >= links.length)
|
|
return false;
|
|
|
|
var currentTest = links[TestNavigator.currentTestIndex];
|
|
if (currentTest)
|
|
currentTest.classList.remove('current');
|
|
|
|
TestNavigator.currentTestIndex = testIndex;
|
|
|
|
currentTest = links[TestNavigator.currentTestIndex];
|
|
currentTest.classList.add('current');
|
|
|
|
return true;
|
|
}
|
|
|
|
TestNavigator._scrollToCurrentTest = function()
|
|
{
|
|
var targetLink = TestNavigator._currentTestLink();
|
|
if (!targetLink)
|
|
return;
|
|
|
|
var rowRect = targetLink.getBoundingClientRect();
|
|
var container = document.querySelector('.content-container');
|
|
// rowRect is in client coords (i.e. relative to viewport), so we just want to add its top to the current scroll position.
|
|
container.scrollTop += rowRect.top - 20;
|
|
}
|
|
|
|
TestNavigator.onlyShowUnexpectedFailuresChanged = function()
|
|
{
|
|
var currentTest = document.querySelector('.current');
|
|
if (!currentTest)
|
|
return;
|
|
|
|
// If our currentTest became hidden, reset the currentTestIndex.
|
|
if (onlyShowUnexpectedFailures() && currentTest.classList.contains('expected'))
|
|
TestNavigator._scrollToFirstTest();
|
|
else {
|
|
// Recompute TestNavigator.currentTestIndex
|
|
var links = visibleTests();
|
|
TestNavigator.currentTestIndex = links.indexOf(currentTest);
|
|
window.console.log('TestNavigator.currentTestIndex is ', TestNavigator.currentTestIndex)
|
|
}
|
|
}
|
|
|
|
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 handleToggleUseNewlines()
|
|
{
|
|
OptionWriter.save();
|
|
TestNavigator.updateFlaggedTests();
|
|
}
|
|
|
|
function handleToggleImagesChange()
|
|
{
|
|
OptionWriter.save();
|
|
updateTogglingImages();
|
|
}
|
|
|
|
function updateTogglingImages()
|
|
{
|
|
var shouldToggle = document.getElementById('toggle-images').checked;
|
|
globalState().shouldToggleImages = shouldToggle;
|
|
|
|
if (shouldToggle) {
|
|
forEach(document.querySelectorAll('table:not(#missing-table) tbody:not([mismatchreftest]) a[href$=".png"]'), convertToTogglingHandler(function(prefix) {
|
|
return resultLink(prefix, '-diffs.html', 'images');
|
|
}));
|
|
forEach(document.querySelectorAll('table:not(#missing-table) tbody:not([mismatchreftest]) img[src$=".png"]'), convertToTogglingHandler(togglingImage));
|
|
} else {
|
|
forEach(document.querySelectorAll('a[href$="-diffs.html"]'), convertToNonTogglingHandler(resultLink));
|
|
forEach(document.querySelectorAll('.animatedImage'), convertToNonTogglingHandler(function (absolutePrefix, suffix) {
|
|
return resultIframe(absolutePrefix + suffix);
|
|
}));
|
|
}
|
|
|
|
updateImageTogglingTimer();
|
|
}
|
|
|
|
function getResultContainer(node)
|
|
{
|
|
return (node.tagName == 'IMG') ? parentOfType(node, '.result-container') : node;
|
|
}
|
|
|
|
function convertToTogglingHandler(togglingImageFunction)
|
|
{
|
|
return function(node) {
|
|
var url = (node.tagName == 'IMG') ? node.src : node.href;
|
|
if (url.match('-expected.png$'))
|
|
remove(getResultContainer(node));
|
|
else if (url.match('-actual.png$')) {
|
|
var name = parentOfType(node, 'tbody').querySelector('.test-link').textContent;
|
|
getResultContainer(node).outerHTML = togglingImageFunction(stripExtension(name));
|
|
}
|
|
}
|
|
}
|
|
|
|
function convertToNonTogglingHandler(resultFunction)
|
|
{
|
|
return function(node) {
|
|
var prefix = node.getAttribute('data-prefix');
|
|
getResultContainer(node).outerHTML = resultFunction(prefix, '-expected.png', 'expected') + resultFunction(prefix, '-actual.png', 'actual');
|
|
}
|
|
}
|
|
|
|
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>' +
|
|
'<th id="text-results-header">results</th>' +
|
|
'<th id="image-results-header">image results</th>' +
|
|
'<th>actual</th>' +
|
|
'<th>expected</th>';
|
|
|
|
if (id == 'flaky-tests-table')
|
|
header += '<th>failures</th>';
|
|
|
|
header += '</tr></thead>';
|
|
|
|
|
|
return header + tableRowHtml + '</table></div>';
|
|
}
|
|
|
|
function generatePage()
|
|
{
|
|
forEachTest(processGlobalStateFor);
|
|
|
|
var html = '<div class=content-container><div id=toolbar>' +
|
|
'<div class="note">Use the i, j, k and l keys to navigate, e, c to expand and collapse, and f to flag</div>' +
|
|
'<a href="dashboard.html" >Archived results </a>' +
|
|
'<a href="javascript:void()" onclick="expandAllExpectations()">expand all</a> ' +
|
|
'<a href="javascript:void()" onclick="collapseAllExpectations()">collapse all</a> ' +
|
|
'<label><input id="toggle-images" type=checkbox checked onchange="handleToggleImagesChange()">Toggle images</label>' +
|
|
'<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');
|
|
|
|
if (globalState().hasHttpTests) {
|
|
html += '<p>httpd access log: <a href="access_log.txt">access_log.txt</a></p>' +
|
|
'<p>httpd error log: <a href="error_log.txt">error_log.txt</a></p>';
|
|
}
|
|
|
|
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();
|
|
|
|
TestNavigator.reset();
|
|
OptionWriter.apply();
|
|
}
|
|
</script>
|
|
<!-- HACK: when json_results_test.js is included, loading this page runs the tests.
|
|
It is not copied to the layout-test-results output directory. -->
|
|
<script src="resources/results-test.js"></script>
|
|
<body onload="generatePage()"></body>
|