Chromium Code Reviews

Unified Diff: webkit/tools/layout_tests/flakiness_dashboard.html

Issue 215019: Dashboard UI changes.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/tools/layout_tests/flakiness_dashboard.html
===================================================================
--- webkit/tools/layout_tests/flakiness_dashboard.html (revision 26455)
+++ webkit/tools/layout_tests/flakiness_dashboard.html (working copy)
@@ -88,7 +88,7 @@
border: 2px solid grey;
background-color: white;
}
- #legend * {
+ #legend-contents * {
margin: 3px;
padding: 0 2px;
}
@@ -131,7 +131,7 @@
.merge {
background-color: green;
}
- :not(#legend) > .merge {
+ :not(#legend-contents) > .merge {
width: 1px;
}
.separator {
@@ -169,8 +169,6 @@
}
#popup {
background-color: white;
- overflow: hidden;
- width: 250px;
z-index: 1;
position: absolute;
border: 3px solid grey;
@@ -181,7 +179,6 @@
-moz-border-radius: 5px;
}
#popup > * {
arv (Not doing code reviews) 2009/09/18 02:35:24 remove empty rule?
- width: 100%;
}
#popup > ul {
margin: 0;
@@ -244,6 +241,8 @@
// path used in test_expectations.txt rather than the test path since we
// don't actually have any data here for skipped tests.
var perBuilderSkippedPaths = {};
+ // Maps test path to an array of {builder, testResults} objects.
+ var testToResultsMap = {};
// Generic utility functions.
function $(id) {
@@ -340,6 +339,7 @@
sortColumn: 'flakiness',
showWontFix: false,
showCorrectExpectations: false,
+ showLegend: true,
showFlaky: true,
showSkipped: false,
maxResults: 200,
@@ -418,6 +418,7 @@
case 'showWontFix':
case 'showCorrectExpectations':
case 'showFlaky':
+ case 'showLegend':
currentState[key] = value == 'true';
return true;
@@ -442,8 +443,6 @@
// Append JSON script elements.
var resultsByBuilder = {};
- // Maps test path to an array of {builder, testResults} objects.
- var testToResultsMap = {};
var expectationsByTest = {};
function ADD_RESULTS(builds) {
for (var builderName in builds) {
@@ -793,7 +792,11 @@
var unexpectedExpectations = [];
var resultsMap = {}
- for (var i = 0; i < rawResults.length; i++) {
+ var numResultsSeen = 0;
+ for (var i = 0;
+ i < rawResults.length && numResultsSeen < currentState.maxResults;
+ i++) {
+ numResultsSeen += rawResults[i][0];
var expectation = getExpectationsFileStringForResult(rawResults[i][1]);
resultsMap[expectation] = true;
}
@@ -818,7 +821,11 @@
}
var times = resultsByBuilder[builderName].tests[test].times;
- for (var i = 0; i < times.length; i++) {
+ var numResultsSeen = 0;
+ for (var i = 0;
+ i < times.length && numResultsSeen < currentState.maxResults;
+ i++) {
+ numResultsSeen += times[i][0];
resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime,
times[i][1]);
}
@@ -877,10 +884,26 @@
}
function getLinkHTMLToOpenWindow(url, text) {
- return '<li class=link onclick="window.open(\'' + url + '\')">' + text +
- '</li>';
+ return '<div class=link onclick="window.open(\'' + url + '\')">' + text +
+ '</div>';
}
+ function createBlameListHTML(revisions, index, urlBase, separator, repo) {
+ var thisRevision = revisions[index];
+ if (!thisRevision)
+ return '';
+
+ var previousRevision = revisions[index + 1];
+ if (previousRevision && previousRevision != thisRevision) {
+ previousRevision++;
+ return getLinkHTMLToOpenWindow(
+ urlBase + thisRevision + separator + previousRevision,
+ repo + ' blamelist r' + previousRevision + ':r' + thisRevision);
+ } else {
+ return 'At ' + repo + ' revision: ' + thisRevision;
+ }
+ }
+
function showPopupForBuild(e, builder, index) {
var html = '';
@@ -890,42 +913,34 @@
html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
- html += '<ul>';
+ html += '<ul><li>' +
+ createBlameListHTML(resultsByBuilder[builder].webkitRevision, index,
+ 'http://trac.webkit.org/log/?rev=', '&stop_rev=', 'WebKit') +
+ '</li><li>' +
+ createBlameListHTML(resultsByBuilder[builder].chromeRevision, index,
+ 'http://build.chromium.org/buildbot/perf/dashboard/ui/' +
+ 'changelog.html?url=/trunk/src&mode=html&range=', ':', 'Chrome') +
+ '</li>';
- var webkitRevision = resultsByBuilder[builder].webkitRevision;
- var thisWebkitRevision = webkitRevision[index];
- if (thisWebkitRevision) {
- var previousWebkitRevision = webkitRevision[index + 1] ||
- thisWebkitRevision;
- html += getLinkHTMLToOpenWindow('http://trac.webkit.org/log/?rev=' +
- thisWebkitRevision + '&stop_rev=' + previousWebkitRevision,
- 'WebKit blamelist r' + previousWebkitRevision + ':r' +
- thisWebkitRevision);
+ var chromeRevision = resultsByBuilder[builder].chromeRevision[index];
+ if (chromeRevision) {
+ html += '<li><a href="' + TEST_RESULTS_BASE_PATH + builders[builder] +
+ '/' + chromeRevision + '/layout-test-results.zip' +
+ '">layout-test-results.zip</a></li>';
}
- var chromeRevision = resultsByBuilder[builder].chromeRevision;
- var thisChromeRevision = chromeRevision[index];
- if (thisChromeRevision) {
- var previousChromeRevision = chromeRevision[index + 1] ||
- thisChromeRevision;
- html += getLinkHTMLToOpenWindow(
- 'http://build.chromium.org/buildbot/perf/dashboard/ui/' +
- 'changelog.html?url=/trunk/src&mode=html&range=' +
- previousChromeRevision + ':' + thisChromeRevision,
- 'Chrome blamelist r' + previousChromeRevision + ':r' +
- thisChromeRevision) +
- getLinkHTMLToOpenWindow(TEST_RESULTS_BASE_PATH + builders[builder] +
- '/' + thisChromeRevision + '/layout-test-results.zip',
- 'layout-test-results.zip');
- }
-
var buildNumbers = resultsByBuilder[builder].buildNumbers;
- html += getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' +
- buildNumbers[index], 'Build log and blamelist') + '</ul>';
+ html += '<li>' +
+ getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' +
+ buildNumbers[index], 'Build log and blamelist') + '</li></ul>';
showPopup(e, html);
}
+ function showPopupForTest(e, test) {
+ showPopup(e, getHTMLForIndividulTestOnAllBuilders(test));
+ }
+
function getHtmlForTestResults(test, builder) {
var html = '';
var results = test.rawResults.concat();
@@ -1024,12 +1039,15 @@
if (testResult.isFixedTest === undefined) {
var results = testResult.rawResults;
var isFixedTest = results[0][1] == 'P';
- if (isFixedTest && results.length > 1) {
- var secondResult = results[1][1];
- isFixedTest = secondResult == 'S' || secondResult == 'F' ||
- secondResult == 'I';
+ var numResults = results[0][0];
+ if (numResults < currentState.maxResults &&
+ isFixedTest && results.length > 1) {
+ // We don't care what the value of the second set of results is, just
+ // how many results there are.
+ numResults += results[1][0];
}
- if (isFixedTest && results.length > 2) {
+ if (numResults < currentState.maxResults &&
+ isFixedTest && results.length > 2) {
isFixedTest = results.length == 3 && results[2][1] == 'N';
}
testResult.isFixedTest = isFixedTest;
@@ -1071,7 +1089,7 @@
// with results for many builders, so the first column is builder names
// instead of test paths.
var testCellHTML = opt_isCrossBuilderView ? builder :
- '<span class="link" onclick="setState(\'tests\', \'' + test.test +
+ '<span class="link" onclick="showPopupForTest(event, \'' + test.test +
'\');return false;">' + test.test + '</span>';
return '<tr class="' +
@@ -1207,34 +1225,39 @@
tableHeaders.unshift('test');
generatePageForBuilder(currentState.builder);
}
+
+ $('max-results-input').value = currentState.maxResults;
+ updateLegendDisplay();
}
- function generatePageForIndividualTests(tests) {
- // TODO: Add link to trac from individual test page
- // TODO: Make links on builder pages to tests be to the individual test page
+ function getHTMLForIndividulTestOnAllBuilders(test) {
for (var builder in builders)
processTestRunsForBuilder(builder);
- var html = getHTMLForNavBar() +
- '<b>IF A BUILDER IS NOT LISTED THAT MEANS THE ' +
- 'BUILDER DOES NOT RUN THAT TEST OR ALL RUNS OF THE TEST PASSED.</b>';
+ var testResults = testToResultsMap[test];
+ if (testResults && testResults.length) {
+ var tracURL = TEST_URL_BASE_PATH + test
+ var html = getLinkHTMLToOpenWindow(tracURL, tracURL) +
+ '<div><b>If a builder is not listed, that means the builder does ' +
+ 'run that tst or all runs of the test passed.</b></div>';
arv (Not doing code reviews) 2009/09/18 02:35:24 s/tst/test/
- for (var i = 0; i < tests.length; i++) {
- html += '<h2>' + tests[i] + '</h2>';
-
- var testResults = testToResultsMap[tests[i]];
- if (testResults && testResults.length) {
- var tableRowsHTML = '';
- for (var j = 0; j < testResults.length; j++) {
- tableRowsHTML += getHTMLForSingleTestRow(testResults[j].results,
- testResults[j].builder, true);
- }
- html += getHTMLForTestTable(tableRowsHTML);
- } else {
- html +='<div class="not-found">Test not found. Either it does not ' +
- 'exist or it passes on all platforms.</div>';
+ for (var j = 0; j < testResults.length; j++) {
+ html += getHTMLForSingleTestRow(testResults[j].results,
+ testResults[j].builder, true);
}
+ return getHTMLForTestTable(html);
+ } else {
+ return '<div class="not-found">Test not found. Either it does not ' +
+ 'exist or it passes on all platforms.</div>';
}
+ }
+
+ function generatePageForIndividualTests(tests) {
+ var html = getHTMLForNavBar();
+ for (var i = 0; i < tests.length; i++) {
+ html += '<h2>' + tests[i] + '</h2>' +
+ getHTMLForIndividulTestOnAllBuilders(tests[i]);
+ }
setFullPageHTML(html);
$('tests-input').value = currentState.tests;
@@ -1253,15 +1276,21 @@
'onsubmit="setState(\'tests\', tests.value);return false;">' +
'<div>Show tests on all platforms (slow): </div><input name=tests ' +
'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' +
- 'id=tests-input></form><div id="loading-ui">LOADING...</div>' +
- '<div id=legend>';
+ 'id=tests-input></form>' +
+ '<form id=max-results-form ' +
+ 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' +
+ '><span>Number of results to show (max=500): </span>' +
+ '<input name=maxResults id=max-results-input></form>' +
+ '<div id="loading-ui">LOADING...</div><div id=legend>' +
+ '<div id=legend-toggle>' + getLinkHTMLToToggleLegendDisplay() +
+ '</div><div id=legend-contents>';
for (var expectation in EXPECTATIONS_MAP) {
html += '<div class=' + expectation + '>' +
EXPECTATIONS_MAP[expectation] + '</div>';
}
return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' +
- '<div class=merge>WEBKIT MERGE</div></div>';
+ '<div class=merge>WEBKIT MERGE</div></div></div>';
}
function getLinkHTMLToToggleState(key, linkText) {
@@ -1290,11 +1319,7 @@
getLinkHTMLToToggleState('showCorrectExpectations',
'tests with correct expectations') + ' | ' +
getLinkHTMLToToggleState('showFlaky', 'flaky tests') + ' | ' +
- '<form id=max-results-form ' +
- 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' +
- '><span>Number of results to show: </span>' +
- '<input name=maxResults id=max-results-input></form> | ' +
- '<b>All columns are sortable. | Skipped tests are not listed. | ' +
+ '<b>All columns are sortable. | ' +
'Flakiness reader order is newer --> older runs.</b></div>' +
testsHTML;
@@ -1305,31 +1330,74 @@
ths[i].addEventListener('click', changeSort, false);
ths[i].className = "sortable";
}
+ }
- $('max-results-input').value = currentState.maxResults;
+ function getLinkHTMLToToggleLegendDisplay() {
+ return getLinkHTMLToToggleState('showLegend', 'Legend');
}
+ function updateLegendDisplay() {
+ $('legend-contents').style.display = currentState.showLegend ? '' : 'none';
+ }
+
/**
+ * Clears the processed test state for perBuilderFailures.
+ * TODO(ojan): This really should probably clear all the state we've
+ * generated, but that's kind of a pain given the many global objects state is
+ * stored in. There should probably be one global generatedState
+ * object that all the generated state lives off of.
+ */
+ function clearProcessedTestState() {
+ for (var builder in builders) {
+ delete perBuilderFailures[builder];
+ delete perBuilderPlatformAndBuildType[builder];
+ delete perBuilderWithExpectationsButNoFailures[builder];
+ delete perBuilderSkippedPaths[builder];
+ }
+
+ for (var key in testToResultsMap) {
+ delete testToResultsMap[key]
+ }
+ }
+
+ /**
* Sets the page state and regenerates the page. Takes varargs of key, value
* pairs.
*/
function setState(key, value) {
for (var i = 0; i < arguments.length; i = i + 2) {
var key = arguments[i];
- if (key != 'tests') {
+ if (key != 'tests' && key != 'maxResults') {
delete currentState.tests;
}
+ if (key == 'maxResults') {
+ // Processing the test results JSON makes assumptions about the number
+ // of results to show. This makes changing the number of maxResults slow
+ // but is considerably easier than refactoring all the other code.
+ clearProcessedTestState();
+ }
+
currentState[key] = arguments[i + 1];
}
window.location.replace(getPermaLinkURL());
- handleLocationChange();
+ if (key == 'showLegend') {
+ saveStoredWindowLocation();
+ updateLegendDisplay();
+ $('legend-toggle').innerHTML = getLinkHTMLToToggleLegendDisplay();
+ } else {
+ handleLocationChange();
+ }
}
+ function saveStoredWindowLocation() {
+ oldLocation = window.location.href;
+ }
+
function handleLocationChange() {
$('loading-ui').style.display = 'block';
setTimeout(function() {
- oldLocation = window.location.href;
+ saveStoredWindowLocation();
generatePage();
}, 0);
}
@@ -1370,12 +1438,14 @@
var x = Math.min(targetRect.left - 10,
document.documentElement.clientWidth - popup.offsetWidth);
+ x = Math.max(0, x);
popup.style.left = x + document.body.scrollLeft + 'px';
var y = targetRect.top + targetRect.height;
if (y + popup.offsetHeight > document.documentElement.clientHeight) {
y = targetRect.top - popup.offsetHeight;
}
+ y = Math.max(0, y);
popup.style.top = y + document.body.scrollTop + 'px';
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine