Commit c3df552e authored by Quinten Yearsley's avatar Quinten Yearsley Committed by Commit Bot

Remove legacy web test results viewer

I just realized I had asked back in May whether anyone still uses
legacy-results.html, and nobody replied, so I think it's now safe
to remove this.

Context:
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/9NFDSTEzcd4

Bug: 748628
Change-Id: I21e7d7451f3fa2e421daeb08e50a446e1e0a3253
Reviewed-on: https://chromium-review.googlesource.com/c/1355480
Commit-Queue: Quinten Yearsley <qyearsley@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612458}
parent e70dc7a2
...@@ -193,7 +193,6 @@ class Manager(object): ...@@ -193,7 +193,6 @@ class Manager(object):
self._upload_json_files() self._upload_json_files()
self._copy_results_html_file(self._results_directory, 'results.html') self._copy_results_html_file(self._results_directory, 'results.html')
self._copy_results_html_file(self._results_directory, 'legacy-results.html')
if initial_results.keyboard_interrupted: if initial_results.keyboard_interrupted:
exit_code = exit_codes.INTERRUPTED_EXIT_STATUS exit_code = exit_codes.INTERRUPTED_EXIT_STATUS
else: else:
......
<!DOCTYPE html>
<html>
<head>
<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;
border: 1px solid gray;
cursor: default;
display: inline-block;
line-height: 1em;
margin: 0 3px 0 0;
position: relative;
text-align: center;
-webkit-user-select: none;
width: 1em;
}
.current {
color: red;
}
.current .expand-button {
border-color: red;
}
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;
}
#results-table > tbody:hover {
background-color: #DDD;
}
</style>
<style id="unexpected-pass-style"></style>
<style id="flaky-failures-style"></style>
<style id="stderr-style"></style>
<style id="unexpected-style"></style>
<script>
'use strict';
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;
}
// This function is used in the JSONP wrapper for failing_results.json;
// when failing_results.json is loaded, the global state will be populated
// with test results.
function ADD_RESULTS(input) {
globalState().results = input;
}
</script>
<script src="failing_results.json"></script>
<script>
'use strict';
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);
}
// Returns HTML for an img or iframe element showing expected or actual results.
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 toggleExpectations(element) {
var expandLink = element;
if (expandLink.className != 'expand-button-text') {
expandLink = expandLink.querySelector('.expand-button-text');
}
if (expandLink.textContent == '+') {
expandExpectations(expandLink, true);
} 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) {
if (node.insertAdjacentHTML) {
node.insertAdjacentHTML('beforeEnd', html);
} else {
node.innerHTML += html;
}
}
function expandExpectations(expandLink, selectRow) {
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);
if (selectRow) {
TestNavigator._setCurrentTest(parentTbody);
}
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');
for (var i = 0; i < resultLinks.length; i++) {
var link = resultLinks[i];
var result;
if (link.textContent == 'images') {
result = togglingImage(link.getAttribute('data-prefix'));
} else {
result = resultIframe(link.href);
}
appendHTML(newCell, result);
}
newRow.appendChild(newCell);
parentTbody.appendChild(newRow);
updateExpandedState(newRow, true);
if (selectRow) {
TestNavigator._setCurrentTest(parentTbody);
}
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 virtualMatch = /virtual\/[^\/]+\/(.*)/.exec(test);
var devirtualTest = virtualMatch ? virtualMatch[1] : test;
var target;
if (shouldUseTracLinks()) {
var revision = globalState().results.chromium_revision;
if (revision) {
target = 'https://crrev.com/' + revision;
} else {
target = 'https://chromium.googlesource.com/chromium/src/+/master';
}
target += '/third_party/WebKit/LayoutTests/' + devirtualTest;
} else {
target = globalState().results.layout_tests_dir + '/' + devirtualTest;
}
return target;
}
function testLink(test) {
var target = testLinkTarget(test);
var flagChar = '\u2691';
return '<a class=test-link href="' + target + '">' + test +
'</a><span class=flag onclick="unflag(this)"> ' + flagChar + '</span>';
}
function unflag(flag) {
var shouldFlag = false;
TestNavigator.flagTest(parentOfType(flag, 'tbody'), shouldFlag);
TestNavigator.updateFlaggedTestTextBox();
}
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);
// FIXME: Handle tests with actual == PASS and expected == PASS.
}
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') +
resultLink(prefix, '-pretty-diff.html', 'pretty diff');
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.html', 'ref mismatch html');
row += resultLink(testPrefix, '-actual.png', 'actual');
} else {
if (testObject.reftest_type && testObject.reftest_type.indexOf('==') != -1) {
row += resultLink(testPrefix, '-expected.html', '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') + '"';
row += ' data-testname="' + testObject.name + '"';
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) {
TestNavigator.flagTest(test, true);
});
TestNavigator.updateFlaggedTestTextBox();
}
function unflagAll(headerLink) {
var tests = visibleTests(parentOfType(headerLink, 'div'));
forEach(tests, function(test) {
TestNavigator.flagTest(test, false);
});
TestNavigator.updateFlaggedTestTextBox();
}
function testListHeaderHtml(header) {
return '<h1>' + header +
' (<span class=test-list-count></span>): [<a href="#" class=flag-all ' +
'onclick="flagAll(this)">flag all</a>] [<a href="#" class=flag-all ' +
'onclick="unflagAll(this)">unflag 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') +
'" data-testname="' + test + '"><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 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.currentTest = null;
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() {
var links = visibleTests();
if (links.length == 0) {
return;
}
if (TestNavigator._setCurrentTest(links[0])) {
TestNavigator._scrollToCurrentTest();
}
};
TestNavigator._scrollToLastTest = function() {
var links = visibleTests();
if (links.length == 0) {
return;
}
if (TestNavigator._setCurrentTest(links[links.length - 1])) {
TestNavigator._scrollToCurrentTest();
}
};
TestNavigator._scrollToNextTest = function() {
if (!TestNavigator.currentTest) {
TestNavigator._scrollToFirstTest();
return;
}
var onlyUnexpected = onlyShowUnexpectedFailures();
for (var tbody = TestNavigator.currentTest.nextElementSibling; tbody; tbody = tbody.nextElementSibling) {
if (tbody.tagName.toLowerCase() != 'tbody') {
continue;
}
if (onlyUnexpected && tbody.classList.contains('expected')) {
continue;
}
if (TestNavigator._setCurrentTest(tbody)) {
TestNavigator._scrollToCurrentTest();
}
break;
}
};
TestNavigator._scrollToPreviousTest = function() {
if (!TestNavigator.currentTest) {
TestNavigator._scrollToLastTest();
return;
}
var onlyUnexpected = onlyShowUnexpectedFailures();
for (var tbody = TestNavigator.currentTest.previousElementSibling; tbody; tbody = tbody.previousElementSibling) {
if (tbody.tagName.toLowerCase() != 'tbody') {
continue;
}
if (onlyUnexpected && tbody.classList.contains('expected')) {
continue;
}
if (TestNavigator._setCurrentTest(tbody)) {
TestNavigator._scrollToCurrentTest();
}
break;
}
};
TestNavigator._currentTestExpandLink = function() {
return TestNavigator.currentTest.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.currentTest;
TestNavigator.flagTest(testLink, !testLink.classList.contains('flagged'));
TestNavigator.updateFlaggedTestTextBox();
};
// FIXME: Test navigator shouldn't know anything about flagging.
// Flagging-related functionality could be extracted to a separate object.
TestNavigator.flagTest = function(testTbody, shouldFlag) {
var testName = testTbody.getAttribute('data-testname');
if (shouldFlag) {
testTbody.classList.add('flagged');
TestNavigator.flaggedTests[testName] = 1;
} else {
testTbody.classList.remove('flagged');
delete TestNavigator.flaggedTests[testName];
}
};
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.updateFlaggedTestTextBox = 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(tbody) {
if (TestNavigator.currentTest) {
TestNavigator.currentTest.classList.remove('current');
}
TestNavigator.currentTest = tbody;
tbody.classList.add('current');
return true;
};
TestNavigator._scrollToCurrentTest = function() {
var targetLink = TestNavigator.currentTest;
if (!targetLink) {
return;
}
var rowRect = targetLink.getBoundingClientRect();
var container = document.querySelector('.content-container');
// rowRect is in client coordinates (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();
}
};
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.updateFlaggedTestTextBox();
}
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');
};
}
// Returns HTML for a table listing failing tests from the test run.
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>';
}
// Initializes the results page.
// This includes adding HTML for the toolbar and the tables with test results,
// and setting the state of TestNavigator and OptionWriter.
// This function requires that globalState().results is already populated.
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&nbsp;</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>' +
' <a href="results.html">results.html</a>' +
'<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/legacy-results-test.js"></script>
</head>
<body onload="generatePage()"></body>
</html>
// To run these tests, load results.html in a browser.
// You should see a series of PASS lines.
if (window.testRunner) {
testRunner.dumpAsText();
}
var testStyles = document.createElement('style');
testStyles.innerText = ".test-pass { color: green; } .test-fail { color: red; }";
document.querySelector('head').appendChild(testStyles);
var g_testIndex = 0;
var g_log = ["You should see a series of PASS lines."];
// Make async actually be sync for the sake of simpler testing.
function async(func, args) {
func.apply(null, args);
}
function mockResults() {
return {
tests: {},
"skipped": 0,
"num_regressions": 0,
"version": 0,
"num_passes": 0,
"fixable": 0,
"num_flaky": 0,
"layout_tests_dir": "/WEBKITROOT",
"chromium_revision": 12345,
"pixel_tests_enabled": true
};
}
function isFailureExpected(expected, actual) {
var isExpected = true;
if (actual != 'SKIP') {
var expectedArray = expected.split(' ');
var actualArray = actual.split(' ');
for (var i = 0; i < actualArray.length; i++) {
var actualValue = actualArray[i];
if (expectedArray.indexOf(actualValue) == -1 &&
(expectedArray.indexOf('FAIL') == -1 ||
(actualValue != 'TEXT' && actualValue != 'IMAGE+TEXT' && actualValue != 'AUDIO')))
isExpected = false;
}
}
return isExpected;
}
function mockExpectation(expected, actual) {
return {
expected: expected,
time_ms: 1,
actual: actual,
has_stderr: false,
is_unexpected: !isFailureExpected(expected, actual)
};
}
function currentTestName() {
var testName = 'TEST ' + g_testIndex;
if (g_testName) {
testName += ' (' + g_testName + ')';
}
return testName;
}
function logPass(msg) {
g_log.push('<span class="test-pass">' + msg + '</span>: ' + currentTestName());
}
function logFail(msg) {
g_log.push('<span class="test-fail">' + msg + '</span>: ' + currentTestName());
}
function assertTrue(bool) {
if (bool) {
logPass('PASS');
} else {
logFail('FAIL');
}
}
function runTest(results, assertions, opt_testName, opt_localStorageValue) {
document.body.innerHTML = '';
g_testIndex++;
g_state = undefined;
g_testName = opt_testName || '';
localStorage.setItem(OptionWriter._key, opt_localStorageValue || '');
try {
ADD_RESULTS(results);
originalGeneratePage();
} catch (e) {
logFail("FAIL: uncaught exception " + e.toString());
}
try {
assertions();
} catch (e) {
logFail("FAIL: uncaught exception executing assertions " + e.toString());
}
}
function runDefaultSingleRowTest(test, expected, actual, isExpected, textResults, imageResults, opt_testName) {
var results = mockResults();
results.tests[test] = mockExpectation(expected, actual);
runSingleRowTest(results, isExpected, textResults, imageResults, opt_testName);
}
function runSingleRowTest(results, isExpected, textResults, imageResults, opt_testName) {
for (var key in results.tests)
var test = key;
var expected = results.tests[test].expected;
var actual = results.tests[test].actual;
runTest(results, function() {
if (isExpected) {
assertTrue(document.querySelector('tbody').className == 'expected');
} else {
assertTrue(document.querySelector('tbody').className.indexOf('expected') == -1);
}
assertTrue(document.querySelector('tbody td:nth-child(1)').textContent == '+' + test + ' \u2691');
assertTrue(document.querySelector('tbody td:nth-child(2)').textContent == textResults);
assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == imageResults);
assertTrue(document.querySelector('tbody td:nth-child(4)').textContent == actual);
assertTrue(document.querySelector('tbody td:nth-child(5)').textContent == expected);
}, opt_testName || 'single row test');
}
function runTests() {
var results = mockResults();
var subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
runTest(results, function() {
assertTrue(document.getElementById('image-results-header').textContent == '');
assertTrue(document.getElementById('text-results-header').textContent != '');
}, 'text results header');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'MISSING');
subtree['bar.html'].is_missing_text = true;
subtree['bar.html'].is_missing_audio = true;
subtree['bar.html'].is_missing_image = true;
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(document.querySelector('#missing-table .test-link').textContent == 'foo/bar.html');
assertTrue(document.getElementsByClassName('result-link')[0].textContent == 'audio result');
assertTrue(document.getElementsByClassName('result-link')[1].textContent == 'result');
assertTrue(document.getElementsByClassName('result-link')[2].textContent == 'png result');
}, 'actual result links');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
subtree['bar.html'].has_stderr = true;
runTest(results, function() {
assertTrue(document.getElementById('results-table'));
assertTrue(document.querySelector('#stderr-table .result-link').textContent == 'stderr');
}, 'stderr link');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
subtree['bar1.html'] = mockExpectation('CRASH', 'PASS');
subtree['bar2.html'] = mockExpectation('IMAGE', 'PASS');
subtree['crash.html'] = mockExpectation('IMAGE', 'CRASH');
subtree['timeout.html'] = mockExpectation('IMAGE', 'TIMEOUT');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
var testLinks = document.querySelectorAll('#passes-table .test-link');
assertTrue(testLinks[0].textContent == 'foo/bar.html');
assertTrue(testLinks[1].textContent == 'foo/bar1.html');
assertTrue(testLinks[2].textContent == 'foo/bar2.html');
assertTrue(!document.querySelector('#passes-table .expand-button'));
var expectationTypes = document.querySelectorAll('#passes-table td:last-of-type');
assertTrue(expectationTypes[0].textContent == 'TEXT');
assertTrue(expectationTypes[1].textContent == 'CRASH');
assertTrue(expectationTypes[2].textContent == 'IMAGE');
assertTrue(document.getElementById('crash-tests-table'));
assertTrue(document.getElementById('crash-tests-table').textContent.indexOf('crash log') != -1);
assertTrue(document.getElementById('timeout-tests-table'));
assertTrue(document.getElementById('timeout-tests-table').textContent.indexOf('expected actual diff') != -1);
}, 'crash and timeout tests tables');
function isExpanded(expandLink)
{
var enDash = '\u2013';
return expandLink.textContent == enDash;
}
function isCollapsed(expandLink)
{
return expandLink.textContent == '+';
}
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
subtree['bar-missing.html'] = mockExpectation('TEXT', 'MISSING');
subtree['bar-missing.html'].is_missing_text = true;
subtree['bar-stderr.html'] = mockExpectation('PASS', 'TEXT');
subtree['bar-stderr.html'].has_stderr = true;
subtree['bar-unexpected-pass.html'] = mockExpectation('TEXT', 'PASS');
runTest(results, function() {
assertTrue(document.querySelectorAll('tbody tr').length == 5);
expandAllExpectations();
assertTrue(document.querySelectorAll('tbody tr').length == 8);
var expandLinks = document.querySelectorAll('.expand-button-text');
for (var i = 0; i < expandLinks.length; i++) {
assertTrue(isExpanded(expandLinks[i]));
}
collapseAllExpectations();
// Collapsed expectations stay in the dom, but are display:none.
assertTrue(document.querySelectorAll('tbody tr').length == 8);
expandLinks = document.querySelectorAll('.expand-button-text');
for (var i = 0; i < expandLinks.length; i++) {
assertTrue(isCollapsed(expandLinks[i]));
}
expandExpectations(expandLinks[1]);
assertTrue(isCollapsed(expandLinks[0]));
assertTrue(isExpanded(expandLinks[1]));
collapseExpectations(expandLinks[1]);
assertTrue(expandLinks[1].textContent == '+');
}, 'collapsing expectation rows');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
subtree['bar-expected-fail.html'] = mockExpectation('TEXT', 'TEXT');
runTest(results, function() {
assertTrue(document.querySelectorAll('.expected').length == 1);
assertTrue(document.querySelector('.expected .test-link').textContent == 'foo/bar-expected-fail.html');
assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] == 'none');
expandAllExpectations();
assertTrue(visibleExpandLinks().length == 1);
assertTrue(document.querySelectorAll('.results-row').length == 1);
assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] == 'none');
document.getElementById('show-expected-failures').checked = true;
document.getElementById('show-expected-failures').onchange();
assertTrue(visibleExpandLinks().length == 2);
assertTrue(document.querySelectorAll('.results-row').length == 1);
assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] != 'none');
expandAllExpectations();
assertTrue(document.querySelectorAll('.results-row').length == 2);
assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] != 'none');
}, 'expanding expectation rows');
results = mockResults();
results.tests['only-expected-fail.html'] = mockExpectation('TEXT', 'TEXT');
runTest(results, function() {
assertTrue(window.getComputedStyle(document.getElementById('results-table').parentNode, null)['display'] == 'none');
}, 'only one expected fail result');
runDefaultSingleRowTest('bar-skip.html', 'TEXT', 'SKIP', true, '', '');
runDefaultSingleRowTest('bar-flaky-fail.html', 'PASS FAIL', 'TEXT', true, 'expected actual diff pretty diff ', '');
runDefaultSingleRowTest('bar-flaky-fail-unexpected.html', 'PASS TEXT', 'IMAGE', false, '', 'images diff ');
runDefaultSingleRowTest('bar-audio.html', 'TEXT', 'AUDIO', false, 'expected audio actual audio ', '');
runDefaultSingleRowTest('bar-image.html', 'TEXT', 'IMAGE', false, '', 'images diff ');
runDefaultSingleRowTest('bar-image-plus-text.html', 'TEXT', 'IMAGE+TEXT', false, 'expected actual diff pretty diff ', 'images diff ');
// Test the mapping for FAIL onto only ['IMAGE+TEXT', 'AUDIO', 'TEXT', 'IMAGE'].
runDefaultSingleRowTest('bar-image.html', 'FAIL', 'IMAGE+TEXT', true, 'expected actual diff pretty diff ', 'images diff ');
runDefaultSingleRowTest('bar-image.html', 'FAIL', 'AUDIO', true, 'expected audio actual audio ', '');
runDefaultSingleRowTest('bar-image.html', 'FAIL', 'TEXT', true, 'expected actual diff pretty diff ', '');
runDefaultSingleRowTest('bar-image.html', 'FAIL', 'IMAGE', false, '', 'images diff ');
results = mockResults();
results.tests['bar-reftest.html'] = mockExpectation('PASS', 'IMAGE');
results.tests['bar-reftest.html'].reftest_type = ['=='];
runSingleRowTest(results, false, '', 'ref html images diff ', 'match reftest single row test');
results = mockResults();
results.tests['bar-reftest-mismatch.html'] = mockExpectation('PASS', 'IMAGE');
results.tests['bar-reftest-mismatch.html'].reftest_type = ['!='];
runSingleRowTest(results, false, '', 'ref mismatch html actual ', 'mismatch reftest single row test');
results = mockResults();
results.tests['bar-reftest.html'] = mockExpectation('IMAGE', 'PASS');
results.tests['bar-reftest.html'].reftest_type = ['=='];
results.pixel_tests_enabled = false;
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(1)').textContent == 'bar-reftest.html \u2691');
}, 'match reftest');
results = mockResults();
results.tests['bar-reftest-mismatch.html'] = mockExpectation('IMAGE', 'PASS');
results.tests['bar-reftest-mismatch.html'].reftest_type = ['!='];
results.pixel_tests_enabled = false;
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(1)').textContent == 'bar-reftest-mismatch.html \u2691');
}, 'mismatch reftest');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar-flaky-pass.html'] = mockExpectation('PASS TEXT', 'PASS');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(document.getElementById('passes-table'));
assertTrue(document.body.textContent.indexOf('foo/bar-flaky-pass.html') != -1);
}, 'expected flaky and passed');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar-flaky-fail.html'] = mockExpectation('PASS TEXT', 'IMAGE PASS');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(document.getElementById('flaky-tests-table'));
assertTrue(document.body.textContent.indexOf('bar-flaky-fail.html') != -1);
}, 'expected flaky and image mismatch');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar-flaky-expected.html'] = mockExpectation('PASS FAIL', 'PASS TEXT');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(document.getElementById('flaky-tests-table'));
assertTrue(document.body.textContent.indexOf('bar-flaky-expected.html') != -1);
assertTrue(document.querySelector('tbody').className == 'expected');
}, 'expected flaky and text mismatch');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar-really-long-path-that-should-probably-wrap-because-otherwise-the-table-will-be-too-wide.html'] = mockExpectation('PASS', 'TEXT');
runTest(results, function() {
document.body.style.width = '800px';
var links = document.querySelectorAll('tbody a');
assertTrue(links[0].getClientRects().length == 2);
assertTrue(links[1].getClientRects().length == 1);
document.body.style.width = '';
}, 'long test name');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'TEXT');
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('pretty diff') != -1);
}, 'pretty diff link');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
subtree['bar-1.html'] = mockExpectation('TEXT', 'CRASH');
subtree['bar-5.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
subtree['bar-3.html'] = mockExpectation('PASS', 'TEXT');
subtree['bar-2.html'] = mockExpectation('PASS', 'IMAGE');
runTest(results, function() {
// FIXME: This just ensures we don't get a JS error.
// Verify that the sort is correct and that inline expanded expectations
// move along with the test they're attached to.
TableSorter.sortColumn(0);
TableSorter.sortColumn(0);
TableSorter.sortColumn(1);
TableSorter.sortColumn(1);
TableSorter.sortColumn(2);
TableSorter.sortColumn(2);
TableSorter.sortColumn(3);
TableSorter.sortColumn(3);
TableSorter.sortColumn(4);
TableSorter.sortColumn(4);
TableSorter.sortColumn(0);
logPass('PASS');
}, 'TableSorter.sortColumn does not raise a JS error');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar-5.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
runTest(results, function() {
expandAllExpectations();
var png = document.querySelector('[src*="bar-5-expected.png"]');
var x = png.offsetLeft + 1;
var y = png.offsetTop + 1;
var mockEvent = {
target: png,
clientX: x,
clientY: y
};
PixelZoomer.showOnDelay = false;
PixelZoomer.handleMouseMove(mockEvent);
assertTrue(!!document.querySelector('.pixel-zoom-container'));
assertTrue(document.querySelectorAll('.zoom-image-container').length == 3);
}, 'zoom image on hover');
results = mockResults();
subtree = results.tests['fullscreen'] = {};
subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
runTest(results, function() {
// Use a regexp to match windows and unix-style paths.
var expectedRegExp = new RegExp('^file.*' + results.layout_tests_dir + '/fullscreen/full-screen-api.html$');
assertTrue(expectedRegExp.exec(document.querySelector('tbody td:first-child a').href));
}, 'local test link');
var oldShouldUseTracLinks = shouldUseTracLinks;
shouldUseTracLinks = function() { return true; };
results = mockResults();
subtree = results.tests['fullscreen'] = {};
subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
runTest(results, function() {
var expectedHref = 'https://crrev.com/' + results.chromium_revision + '/third_party/WebKit/LayoutTests/fullscreen/full-screen-api.html';
assertTrue(document.querySelector('tbody td:first-child a').href == expectedHref);
}, 'chromium revision link');
results = mockResults();
subtree = results.tests['fullscreen'] = {};
subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
results.chromium_revision = '';
runTest(results, function() {
var expectedHref = 'https://chromium.googlesource.com/chromium/src/+/master/third_party/WebKit/LayoutTests/fullscreen/full-screen-api.html';
assertTrue(document.querySelector('tbody td:first-child a').href == expectedHref);
}, 'googlesource test link');
shouldUseTracLinks = oldShouldUseTracLinks;
results = mockResults();
results.tests['bar.html'] = mockExpectation('PASS', 'IMAGE');
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'images diff ');
document.getElementById('toggle-images').checked = false;
// FIXME: We shouldn't need to call updateTogglingImages. Setting checked above should call it.
updateTogglingImages();
// FIXME: We get extra spaces in the DOM every time we enable/disable image toggling.
assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'expected actual diff ');
document.getElementById('toggle-images').checked = true;
updateTogglingImages();
assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == ' images diff ');
}, 'toggle images option');
results = mockResults();
results.tests['reading-options-from-localstorage.html'] = mockExpectation('IMAGE+TEXT', 'IMAGE+TEXT');
runTest(results, function() {
assertTrue(window.getComputedStyle(document.querySelector('tbody'), null)['display'] != 'none');
assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'expected actual diff ');
}, 'reading options from localstorage', '{"toggle-images":false,"show-expected-failures":true}');
function enclosingNodeWithTagNameHasClassName(node, tagName, className) {
while (node && (!node.tagName || node.localName != tagName)) {
node = node.parentNode;
}
if (!node) {
return false;
}
return node.className == className;
}
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['expected-to-pass-but-crashed.html'] = mockExpectation('PASS', 'CRASH');
subtree['expected-to-pass-or-crash-and-crashed.html'] = mockExpectation('PASS CRASH', 'CRASH');
subtree['expected-to-pass-but-timeouted.html'] = mockExpectation('PASS', 'CRASH');
subtree['expected-to-pass-or-timeout-and-timeouted.html'] = mockExpectation('PASS TIMEOUT', 'TIMEOUT');
subtree['expected-fail-but-passed.html'] = mockExpectation('FAIL', 'PASS');
subtree['expected-pass-or-fail-and-passed.html'] = mockExpectation('PASS FAIL', 'PASS');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
var testLinks = document.querySelectorAll('.test-link');
assertTrue(testLinks[0].innerText == 'foo/expected-to-pass-but-crashed.html');
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[0], 'tbody', 'expected'));
assertTrue(testLinks[1].innerText == 'foo/expected-to-pass-or-crash-and-crashed.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'tbody', 'expected'));
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[0], 'table', 'expected'));
assertTrue(testLinks[2].innerText == 'foo/expected-to-pass-but-timeouted.html');
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[2], 'tbody', 'expected'));
assertTrue(testLinks[3].innerText == 'foo/expected-to-pass-or-timeout-and-timeouted.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[3], 'tbody', 'expected'));
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[2], 'table', 'expected'));
assertTrue(testLinks[4].innerText == 'foo/expected-fail-but-passed.html');
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[4], 'tbody', 'expected'));
assertTrue(testLinks[5].innerText == 'foo/expected-pass-or-fail-and-passed.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[5], 'tbody', 'expected'));
assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[4], 'table', 'expected'));
}, 'class names 1');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['expected-to-pass-or-crash-and-crashed.html'] = mockExpectation('PASS CRASH', 'CRASH');
subtree['expected-to-pass-or-timeout-and-timeouted.html'] = mockExpectation('PASS TIMEOUT', 'TIMEOUT');
subtree['expected-pass-or-fail-and-passed.html'] = mockExpectation('PASS FAIL', 'PASS');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
var testLinks = document.querySelectorAll('.test-link');
assertTrue(testLinks[0].innerText == 'foo/expected-to-pass-or-crash-and-crashed.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[0], 'tbody', 'expected'));
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[0], 'div', 'expected'));
assertTrue(testLinks[1].innerText == 'foo/expected-to-pass-or-timeout-and-timeouted.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'tbody', 'expected'));
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'div', 'expected'));
assertTrue(testLinks[2].innerText == 'foo/expected-pass-or-fail-and-passed.html');
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[2], 'tbody', 'expected'));
assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[2], 'div', 'expected'));
}, 'class names 2');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
subtree['crash.html'] = mockExpectation('IMAGE', 'CRASH');
subtree['flaky-fail.html'] = mockExpectation('PASS TEXT', 'IMAGE PASS');
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
var resultText = document.body.textContent;
assertTrue(resultText.indexOf('crash.html') != -1);
assertTrue(resultText.indexOf('flaky-fail.html') != -1);
assertTrue(resultText.indexOf('crash.html') < resultText.indexOf('flaky-fail.html'));
}, 'crash and flaky fail test order');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['expected-missing.html'] = mockExpectation('MISSING', 'MISSING');
subtree['expected-missing.html'].is_missing_text = true;
subtree['expected-missing.html'].is_missing_image = true;
subtree['unexpected-missing.html'] = mockExpectation('PASS', 'MISSING');
subtree['unexpected-missing.html'].is_missing_text = true;
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(visibleExpandLinks().length == 1);
assertTrue(document.querySelector('#missing-table tbody.expected .test-link').textContent == 'foo/expected-missing.html');
assertTrue(document.querySelector('#missing-table tbody.expected').getElementsByClassName('result-link')[0].textContent == 'result');
assertTrue(document.querySelector('#missing-table tbody.expected').getElementsByClassName('result-link')[1].textContent == 'png result');
assertTrue(document.querySelector('#missing-table tbody:not(.expected) .test-link').textContent == 'foo/unexpected-missing.html');
assertTrue(document.querySelector('#missing-table tbody:not(.expected) .result-link').textContent == 'result');
document.getElementById('show-expected-failures').checked = true;
document.getElementById('show-expected-failures').onchange();
expandAllExpectations();
assertTrue(visibleExpandLinks().length == 2);
}, 'missing results table');
results = mockResults();
subtree = results.tests['foo'] = {}
subtree['bar.html'] = mockExpectation('TEXT', 'FAIL');
subtree['bar1.html'] = mockExpectation('TEXT', 'FAIL');
subtree['bar2.html'] = mockExpectation('TEXT', 'FAIL');
runTest(results, function() {
if (window.eventSender) {
eventSender.keyDown('k'); // previous
var testRows = document.querySelectorAll('#results-table tbody');
assertTrue(!testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(testRows[2].classList.contains('current'));
}
}, 'keyboard shortcuts: prev');
runTest(results, function() {
if (window.eventSender) {
eventSender.keyDown('j'); // next
var testRows = document.querySelectorAll('#results-table tbody');
assertTrue(testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
}
}, 'keyboard shortcuts: next');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'FAIL');
subtree['bar1.html'] = mockExpectation('TEXT', 'FAIL');
subtree['bar2.html'] = mockExpectation('TEXT', 'FAIL');
subtree['bar3.html'] = mockExpectation('TEXT', 'PASS');
subtree['bar4.html'] = mockExpectation('IMAGE', 'PASS');
runTest(results, function() {
assertTrue(document.getElementById('results-table'));
assertTrue(visibleExpandLinks().length == 3);
if (window.eventSender) {
eventSender.keyDown('i', ["metaKey"]);
eventSender.keyDown('i', ["shiftKey"]);
eventSender.keyDown('i', ["ctrlKey"]);
var testRows = document.querySelectorAll('tbody');
assertTrue(!testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('i'); // first
assertTrue(testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('j', ["metaKey"]);
eventSender.keyDown('j', ["shiftKey"]);
eventSender.keyDown('j', ["ctrlKey"]);
assertTrue(testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('j'); // next
assertTrue(!testRows[0].classList.contains('current'));
assertTrue(testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('k', ["metaKey"]);
eventSender.keyDown('k', ["shiftKey"]);
eventSender.keyDown('k', ["ctrlKey"]);
assertTrue(!testRows[0].classList.contains('current'));
assertTrue(testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('k'); // previous
assertTrue(testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('l', ["metaKey"]);
eventSender.keyDown('l', ["shiftKey"]);
eventSender.keyDown('l', ["ctrlKey"]);
assertTrue(testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(!testRows[2].classList.contains('current'));
eventSender.keyDown('l'); // last
assertTrue(!testRows[0].classList.contains('current'));
assertTrue(!testRows[1].classList.contains('current'));
assertTrue(testRows[4].classList.contains('current'));
var flaggedTestsTextbox = document.getElementById('flagged-tests');
eventSender.keyDown('f'); // flag
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar4.html');
eventSender.keyDown('f'); // unflag
eventSender.keyDown('i'); // first
eventSender.keyDown('e', ["metaKey"]);
eventSender.keyDown('e', ["shiftKey"]);
eventSender.keyDown('e', ["ctrlKey"]);
var expandLinks = document.querySelectorAll('.expand-button-text');
assertTrue(!isExpanded(expandLinks[0]));
eventSender.keyDown('e'); // expand
assertTrue(isExpanded(expandLinks[0]));
eventSender.keyDown('c', ["metaKey"]);
eventSender.keyDown('c', ["shiftKey"]);
eventSender.keyDown('c', ["ctrlKey"]);
assertTrue(isExpanded(expandLinks[0]));
eventSender.keyDown('c'); // collapse
assertTrue(isCollapsed(expandLinks[0]));
eventSender.keyDown('f', ["metaKey"]);
eventSender.keyDown('f', ["shiftKey"]);
eventSender.keyDown('f', ["ctrlKey"]);
assertTrue(flaggedTestsTextbox.innerText == '');
eventSender.keyDown('f'); // flag
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html');
eventSender.keyDown('j'); // next
eventSender.keyDown('f'); // flag
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html\nfoo/bar1.html');
document.getElementById('use-newlines').checked = false;
TestNavigator.updateFlaggedTestTextBox();
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html foo/bar1.html');
eventSender.keyDown('f'); // unflag
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html');
eventSender.keyDown('k'); // previous
eventSender.keyDown('f'); // flag
assertTrue(flaggedTestsTextbox.innerText == '');
}
}, 'keyboard shortcuts');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
subtree['bar-1.html'] = mockExpectation('TEXT', 'CRASH');
subtree['bar-2.html'] = mockExpectation('PASS', 'IMAGE');
subtree['bar-3.html'] = mockExpectation('PASS', 'TEXT');
subtree['bar-4.html'] = mockExpectation('TEXT', 'TEXT');
subtree['bar-5.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
subtree['bar-stderr-expected.html'] = mockExpectation('IMAGE', 'IMAGE');
subtree['bar-stderr-expected.html'].has_stderr = true;
subtree['bar-expected-timeout.html'] = mockExpectation('TIMEOUT', 'TIMEOUT');
subtree['bar-expected-crash.html'] = mockExpectation('CRASH', 'CRASH');
subtree['bar-missing.html'] = mockExpectation('TEXT', 'MISSING');
subtree['bar-missing.html'].is_missing_text = true;
runTest(results, function() {
var titles = document.getElementsByTagName('h1');
assertTrue(titles[0].textContent == 'Tests that crashed (1): [flag all] [unflag all]');
assertTrue(titles[1].textContent == 'Tests that failed text/pixel/audio diff (3): [flag all] [unflag all]');
assertTrue(titles[2].textContent == 'Tests that had no expected results (probably new) (1): [flag all] [unflag all]');
assertTrue(titles[3].textContent == 'Tests that timed out (0): [flag all] [unflag all]');
assertTrue(titles[4].textContent == 'Tests that had stderr output (1): [flag all] [unflag all]');
assertTrue(titles[5].textContent == 'Tests expected to fail but passed (1): [flag all] [unflag all]');
document.getElementById('show-expected-failures').checked = true;
document.getElementById('show-expected-failures').onchange();
assertTrue(titles[0].textContent == 'Tests that crashed (2): [flag all] [unflag all]');
assertTrue(titles[1].textContent == 'Tests that failed text/pixel/audio diff (5): [flag all] [unflag all]');
assertTrue(titles[2].textContent == 'Tests that had no expected results (probably new) (1): [flag all] [unflag all]');
assertTrue(titles[3].textContent == 'Tests that timed out (1): [flag all] [unflag all]');
assertTrue(titles[4].textContent == 'Tests that had stderr output (1): [flag all] [unflag all]');
assertTrue(titles[5].textContent == 'Tests expected to fail but passed (1): [flag all] [unflag all]');
}, 'table titles 1');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('', 'PASS TEXT');
subtree['bar-1.html'] = mockExpectation('', 'TEXT IMAGE');
subtree['bar-2.html'] = mockExpectation('IMAGE TEXT', 'TEXT IMAGE');
subtree['bar-3.html'] = mockExpectation('PASS TEXT', 'TEXT PASS');
runTest(results, function() {
var titles = document.getElementsByTagName('h1');
assertTrue(titles[0].textContent == 'Tests that failed text/pixel/audio diff (1): [flag all] [unflag all]');
assertTrue(titles[1].textContent == 'Flaky tests (failed the first run and passed on retry) (1): [flag all] [unflag all]');
assertTrue(document.querySelectorAll('#results-table tbody').length == 2);
assertTrue(document.querySelectorAll('#flaky-tests-table tbody').length == 2);
}, 'table titles 2');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'IMAGE');
subtree['bar1.html'] = mockExpectation('TEXT', 'TEXT');
subtree['bar2.html'] = mockExpectation('TEXT', 'TEXT');
runTest(results, function() {
flagAll(document.querySelector('.flag-all'));
var flaggedTestsTextbox = document.getElementById('flagged-tests');
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html');
document.getElementById('show-expected-failures').checked = true;
document.getElementById('show-expected-failures').onchange();
flagAll(document.querySelector('.flag-all'));
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html\nfoo/bar1.html\nfoo/bar2.html');
unflag(document.querySelector('.flag'));
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar1.html\nfoo/bar2.html');
}, 'flagging tests');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'IMAGE');
subtree['bar1.html'] = mockExpectation('TEXT', 'IMAGE');
runTest(results, function() {
flagAll(document.querySelector('.flag-all'));
var flaggedTestsTextbox = document.getElementById('flagged-tests');
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html\nfoo/bar1.html');
}, 'flagged tests with newlines', '{"use-newlines":true}');
results = mockResults();
subtree = results.tests['foo'] = {};
subtree['bar.html'] = mockExpectation('TEXT', 'IMAGE');
subtree['bar1.html'] = mockExpectation('TEXT', 'IMAGE');
runTest(results, function() {
flagAll(document.querySelector('.flag-all'));
var flaggedTestsTextbox = document.getElementById('flagged-tests');
assertTrue(flaggedTestsTextbox.innerText == 'foo/bar.html foo/bar1.html');
}, 'flagged tests with spaces', '{"use-newlines":false}');
results = mockResults();
results.tests['foo/bar-image.html'] = mockExpectation('PASS', 'TEXT IMAGE+TEXT');
results.pixel_tests_enabled = false;
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(3) a').getAttribute('href') == 'retries/foo/bar-image-diffs.html');
}, 'image diff links with IMAGE+TEXT result');
results = mockResults();
results.tests['foo/bar-image.html'] = mockExpectation('PASS', 'TEXT IMAGE');
results.pixel_tests_enabled = false;
runTest(results, function() {
assertTrue(!document.getElementById('results-table'));
assertTrue(document.querySelector('#flaky-tests-table td:nth-child(3) a').getAttribute('href') == 'retries/foo/bar-image-diffs.html');
}, 'image diff links flaky TEXT IMAGE result');
results = mockResults();
results.tests['foo'] = mockExpectation('PASS', 'TEXT');
results.tests['foo'].has_repaint_overlay = true;
runTest(results, function() {
assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('overlay') != -1);
}, 'repaint overlay');
document.body.innerHTML = '<pre>' + g_log.join('\n') + '</pre>';
}
var originalGeneratePage = generatePage;
generatePage = runTests;
...@@ -191,7 +191,6 @@ p, h2, h3, h4 { ...@@ -191,7 +191,6 @@ p, h2, h3, h4 {
<div id="right-toolbar"> <div id="right-toolbar">
<a id="help_button" href="javascript:GUI.toggleVisibility('help')">help</a> <a id="help_button" href="javascript:GUI.toggleVisibility('help')">help</a>
<div style="">go back to <a href="legacy-results.html">legacy-results.html</a></div>
</div> </div>
<div id="help" class="hidden hide-on-esc"> <div id="help" class="hidden hide-on-esc">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment