Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!DOCTYPE HTML> | 1 <!DOCTYPE HTML> |
| 2 <html> | 2 <html> |
| 3 | 3 |
| 4 <head> | 4 <head> |
| 5 <title>Webkit Layout Test History</title> | 5 <title>Webkit Layout Test History</title> |
| 6 <script> | 6 <script> |
| 7 var pageLoadStartTime = Date.now(); | 7 var pageLoadStartTime = Date.now(); |
| 8 </script> | 8 </script> |
| 9 <style> | 9 <style> |
| 10 body { | 10 body { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 text-align: center; | 81 text-align: center; |
| 82 } | 82 } |
| 83 #legend { | 83 #legend { |
| 84 position: fixed; | 84 position: fixed; |
| 85 top: 5px; | 85 top: 5px; |
| 86 right: 5px; | 86 right: 5px; |
| 87 width: 130px; | 87 width: 130px; |
| 88 border: 2px solid grey; | 88 border: 2px solid grey; |
| 89 background-color: white; | 89 background-color: white; |
| 90 } | 90 } |
| 91 #legend * { | 91 #legend-contents * { |
| 92 margin: 3px; | 92 margin: 3px; |
| 93 padding: 0 2px; | 93 padding: 0 2px; |
| 94 } | 94 } |
| 95 body > div > :not(#legend) { | 95 body > div > :not(#legend) { |
| 96 margin-right: 145px; | 96 margin-right: 145px; |
| 97 } | 97 } |
| 98 #builders * { | 98 #builders * { |
| 99 margin: 0 5px; | 99 margin: 0 5px; |
| 100 display: inline-block; | 100 display: inline-block; |
| 101 white-space: nowrap; | 101 white-space: nowrap; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 124 } | 124 } |
| 125 .F { | 125 .F { |
| 126 background-color: #e98080; | 126 background-color: #e98080; |
| 127 } | 127 } |
| 128 .O { | 128 .O { |
| 129 background-color: #69f; | 129 background-color: #69f; |
| 130 } | 130 } |
| 131 .merge { | 131 .merge { |
| 132 background-color: green; | 132 background-color: green; |
| 133 } | 133 } |
| 134 :not(#legend) > .merge { | 134 :not(#legend-contents) > .merge { |
| 135 width: 1px; | 135 width: 1px; |
| 136 } | 136 } |
| 137 .separator { | 137 .separator { |
| 138 border: 1px solid lightgray; | 138 border: 1px solid lightgray; |
| 139 height: 0px; | 139 height: 0px; |
| 140 } | 140 } |
| 141 .different-platform { | 141 .different-platform { |
| 142 color: gray; | 142 color: gray; |
| 143 font-size: 10px; | 143 font-size: 10px; |
| 144 } | 144 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 162 position: fixed; | 162 position: fixed; |
| 163 top: 0; | 163 top: 0; |
| 164 left: 0; | 164 left: 0; |
| 165 background-color: yellow; | 165 background-color: yellow; |
| 166 padding: 5px; | 166 padding: 5px; |
| 167 text-align: center; | 167 text-align: center; |
| 168 font-weight: bold; | 168 font-weight: bold; |
| 169 } | 169 } |
| 170 #popup { | 170 #popup { |
| 171 background-color: white; | 171 background-color: white; |
| 172 overflow: hidden; | |
| 173 width: 250px; | |
| 174 z-index: 1; | 172 z-index: 1; |
| 175 position: absolute; | 173 position: absolute; |
| 176 border: 3px solid grey; | 174 border: 3px solid grey; |
| 177 padding: 3px; | 175 padding: 3px; |
| 178 -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5); | 176 -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5); |
| 179 -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5); | 177 -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5); |
| 180 -webkit-border-radius: 5px; | 178 -webkit-border-radius: 5px; |
| 181 -moz-border-radius: 5px; | 179 -moz-border-radius: 5px; |
| 182 } | 180 } |
| 183 #popup > * { | 181 #popup > * { |
|
arv (Not doing code reviews)
2009/09/18 02:35:24
remove empty rule?
| |
| 184 width: 100%; | |
| 185 } | 182 } |
| 186 #popup > ul { | 183 #popup > ul { |
| 187 margin: 0; | 184 margin: 0; |
| 188 padding-left: 20px; | 185 padding-left: 20px; |
| 189 } | 186 } |
| 190 </style> | 187 </style> |
| 191 | 188 |
| 192 <script> | 189 <script> |
| 193 /** | 190 /** |
| 194 * @fileoverview Creates a dashboard for multiple runs of a given set of tests | 191 * @fileoverview Creates a dashboard for multiple runs of a given set of tests |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 'flakiness (numbers are runtimes in seconds)']; | 234 'flakiness (numbers are runtimes in seconds)']; |
| 238 var perBuilderPlatformAndBuildType = {}; | 235 var perBuilderPlatformAndBuildType = {}; |
| 239 var perBuilderFailures = {}; | 236 var perBuilderFailures = {}; |
| 240 // Map of builder to arrays of tests that are listed in the expectations file | 237 // Map of builder to arrays of tests that are listed in the expectations file |
| 241 // but have for that builder. | 238 // but have for that builder. |
| 242 var perBuilderWithExpectationsButNoFailures = {}; | 239 var perBuilderWithExpectationsButNoFailures = {}; |
| 243 // Map of builder to arrays of paths that are skipped. This shows the raw | 240 // Map of builder to arrays of paths that are skipped. This shows the raw |
| 244 // path used in test_expectations.txt rather than the test path since we | 241 // path used in test_expectations.txt rather than the test path since we |
| 245 // don't actually have any data here for skipped tests. | 242 // don't actually have any data here for skipped tests. |
| 246 var perBuilderSkippedPaths = {}; | 243 var perBuilderSkippedPaths = {}; |
| 244 // Maps test path to an array of {builder, testResults} objects. | |
| 245 var testToResultsMap = {}; | |
| 247 | 246 |
| 248 // Generic utility functions. | 247 // Generic utility functions. |
| 249 function $(id) { | 248 function $(id) { |
| 250 return document.getElementById(id); | 249 return document.getElementById(id); |
| 251 } | 250 } |
| 252 | 251 |
| 253 function stringContains(a, b) { | 252 function stringContains(a, b) { |
| 254 return a.indexOf(b) != -1; | 253 return a.indexOf(b) != -1; |
| 255 } | 254 } |
| 256 | 255 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 'Webkit Mac10.5 (dbg)(3)': 'webkit-dbg-mac5-3' | 332 'Webkit Mac10.5 (dbg)(3)': 'webkit-dbg-mac5-3' |
| 334 }; | 333 }; |
| 335 var builderBase = 'http://build.chromium.org/buildbot/'; | 334 var builderBase = 'http://build.chromium.org/buildbot/'; |
| 336 } | 335 } |
| 337 | 336 |
| 338 var defaultStateValues = { | 337 var defaultStateValues = { |
| 339 sortOrder: BACKWARD, | 338 sortOrder: BACKWARD, |
| 340 sortColumn: 'flakiness', | 339 sortColumn: 'flakiness', |
| 341 showWontFix: false, | 340 showWontFix: false, |
| 342 showCorrectExpectations: false, | 341 showCorrectExpectations: false, |
| 342 showLegend: true, | |
| 343 showFlaky: true, | 343 showFlaky: true, |
| 344 showSkipped: false, | 344 showSkipped: false, |
| 345 maxResults: 200, | 345 maxResults: 200, |
| 346 testType: 'layout_test_results' | 346 testType: 'layout_test_results' |
| 347 }; | 347 }; |
| 348 | 348 |
| 349 function fillDefaultStateValues() { | 349 function fillDefaultStateValues() { |
| 350 for (var state in defaultStateValues) { | 350 for (var state in defaultStateValues) { |
| 351 if (!(state in currentState)) | 351 if (!(state in currentState)) |
| 352 currentState[state] = defaultStateValues[state]; | 352 currentState[state] = defaultStateValues[state]; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 function() { | 411 function() { |
| 412 return value.match(/^\d+$/) | 412 return value.match(/^\d+$/) |
| 413 }); | 413 }); |
| 414 | 414 |
| 415 return true; | 415 return true; |
| 416 | 416 |
| 417 case 'debug': | 417 case 'debug': |
| 418 case 'showWontFix': | 418 case 'showWontFix': |
| 419 case 'showCorrectExpectations': | 419 case 'showCorrectExpectations': |
| 420 case 'showFlaky': | 420 case 'showFlaky': |
| 421 case 'showLegend': | |
| 421 currentState[key] = value == 'true'; | 422 currentState[key] = value == 'true'; |
| 422 | 423 |
| 423 return true; | 424 return true; |
| 424 | 425 |
| 425 default: | 426 default: |
| 426 return false; | 427 return false; |
| 427 } | 428 } |
| 428 } | 429 } |
| 429 | 430 |
| 430 // Keep the location around for detecting changes to hash arguments | 431 // Keep the location around for detecting changes to hash arguments |
| 431 // manually typed into the URL bar. | 432 // manually typed into the URL bar. |
| 432 var oldLocation; | 433 var oldLocation; |
| 433 | 434 |
| 434 function parseAllParameters() { | 435 function parseAllParameters() { |
| 435 oldLocation = window.location.href; | 436 oldLocation = window.location.href; |
| 436 parseParameters(window.location.hash.substring(1), | 437 parseParameters(window.location.hash.substring(1), |
| 437 handleValidHashParameter); | 438 handleValidHashParameter); |
| 438 fillDefaultStateValues(); | 439 fillDefaultStateValues(); |
| 439 } | 440 } |
| 440 | 441 |
| 441 parseAllParameters(); | 442 parseAllParameters(); |
| 442 | 443 |
| 443 // Append JSON script elements. | 444 // Append JSON script elements. |
| 444 var resultsByBuilder = {}; | 445 var resultsByBuilder = {}; |
| 445 // Maps test path to an array of {builder, testResults} objects. | |
| 446 var testToResultsMap = {}; | |
| 447 var expectationsByTest = {}; | 446 var expectationsByTest = {}; |
| 448 function ADD_RESULTS(builds) { | 447 function ADD_RESULTS(builds) { |
| 449 for (var builderName in builds) { | 448 for (var builderName in builds) { |
| 450 if (builderName != 'version') | 449 if (builderName != 'version') |
| 451 resultsByBuilder[builderName] = builds[builderName]; | 450 resultsByBuilder[builderName] = builds[builderName]; |
| 452 } | 451 } |
| 453 | 452 |
| 454 generatePage(); | 453 generatePage(); |
| 455 } | 454 } |
| 456 | 455 |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 786 } | 785 } |
| 787 | 786 |
| 788 var rawTest = resultsByBuilder[builderName].tests[test]; | 787 var rawTest = resultsByBuilder[builderName].tests[test]; |
| 789 resultsForTest.rawTimes = rawTest.times; | 788 resultsForTest.rawTimes = rawTest.times; |
| 790 var rawResults = rawTest.results; | 789 var rawResults = rawTest.results; |
| 791 resultsForTest.rawResults = rawResults; | 790 resultsForTest.rawResults = rawResults; |
| 792 resultsForTest.flips = rawResults.length - 1; | 791 resultsForTest.flips = rawResults.length - 1; |
| 793 | 792 |
| 794 var unexpectedExpectations = []; | 793 var unexpectedExpectations = []; |
| 795 var resultsMap = {} | 794 var resultsMap = {} |
| 796 for (var i = 0; i < rawResults.length; i++) { | 795 var numResultsSeen = 0; |
| 796 for (var i = 0; | |
| 797 i < rawResults.length && numResultsSeen < currentState.maxResults; | |
| 798 i++) { | |
| 799 numResultsSeen += rawResults[i][0]; | |
| 797 var expectation = getExpectationsFileStringForResult(rawResults[i][1]); | 800 var expectation = getExpectationsFileStringForResult(rawResults[i][1]); |
| 798 resultsMap[expectation] = true; | 801 resultsMap[expectation] = true; |
| 799 } | 802 } |
| 800 | 803 |
| 801 var expectationsArray = resultsForTest.expectations ? | 804 var expectationsArray = resultsForTest.expectations ? |
| 802 resultsForTest.expectations.split(' ') : []; | 805 resultsForTest.expectations.split(' ') : []; |
| 803 var extraExpectations = expectationsArray.filter( | 806 var extraExpectations = expectationsArray.filter( |
| 804 function(element) { | 807 function(element) { |
| 805 return element && !resultsMap[element] && | 808 return element && !resultsMap[element] && |
| 806 !stringContains(element, 'BUG'); | 809 !stringContains(element, 'BUG'); |
| 807 }); | 810 }); |
| 808 | 811 |
| 809 var missingExpectations = []; | 812 var missingExpectations = []; |
| 810 for (var result in resultsMap) { | 813 for (var result in resultsMap) { |
| 811 var hasExpectation = false; | 814 var hasExpectation = false; |
| 812 for (var i = 0; i < expectationsArray.length; i++) { | 815 for (var i = 0; i < expectationsArray.length; i++) { |
| 813 if (result == expectationsArray[i]) | 816 if (result == expectationsArray[i]) |
| 814 hasExpectation = true; | 817 hasExpectation = true; |
| 815 } | 818 } |
| 816 if (!hasExpectation) | 819 if (!hasExpectation) |
| 817 missingExpectations.push(result); | 820 missingExpectations.push(result); |
| 818 } | 821 } |
| 819 | 822 |
| 820 var times = resultsByBuilder[builderName].tests[test].times; | 823 var times = resultsByBuilder[builderName].tests[test].times; |
| 821 for (var i = 0; i < times.length; i++) { | 824 var numResultsSeen = 0; |
| 825 for (var i = 0; | |
| 826 i < times.length && numResultsSeen < currentState.maxResults; | |
| 827 i++) { | |
| 828 numResultsSeen += times[i][0]; | |
| 822 resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime, | 829 resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime, |
| 823 times[i][1]); | 830 times[i][1]); |
| 824 } | 831 } |
| 825 | 832 |
| 826 if (resultsForTest.slowestTime && !resultsMap['TIMEOUT'] && | 833 if (resultsForTest.slowestTime && !resultsMap['TIMEOUT'] && |
| 827 (!resultsForTest.expectations || | 834 (!resultsForTest.expectations || |
| 828 !stringContains(resultsForTest.expectations, 'TIMEOUT')) && | 835 !stringContains(resultsForTest.expectations, 'TIMEOUT')) && |
| 829 (!resultsForTest.modifiers || | 836 (!resultsForTest.modifiers || |
| 830 !stringContains(resultsForTest.modifiers, 'SLOW'))) { | 837 !stringContains(resultsForTest.modifiers, 'SLOW'))) { |
| 831 missingExpectations.push('SLOW'); | 838 missingExpectations.push('SLOW'); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 */ | 877 */ |
| 871 function getHtmlForBugs(bugs) { | 878 function getHtmlForBugs(bugs) { |
| 872 bugs = bugs.replace(/BUG(\d{4})(\ |$)/g, externalBugReplaceValue); | 879 bugs = bugs.replace(/BUG(\d{4})(\ |$)/g, externalBugReplaceValue); |
| 873 bugs = bugs.replace(/BUG(\d{5})(\ |$)/g, externalBugReplaceValue); | 880 bugs = bugs.replace(/BUG(\d{5})(\ |$)/g, externalBugReplaceValue); |
| 874 bugs = bugs.replace(/BUG(\d{6})(\ |$)/g, internalBugReplaceValue); | 881 bugs = bugs.replace(/BUG(\d{6})(\ |$)/g, internalBugReplaceValue); |
| 875 bugs = bugs.replace(/BUG(\d{7})(\ |$)/g, internalBugReplaceValue); | 882 bugs = bugs.replace(/BUG(\d{7})(\ |$)/g, internalBugReplaceValue); |
| 876 return bugs; | 883 return bugs; |
| 877 } | 884 } |
| 878 | 885 |
| 879 function getLinkHTMLToOpenWindow(url, text) { | 886 function getLinkHTMLToOpenWindow(url, text) { |
| 880 return '<li class=link onclick="window.open(\'' + url + '\')">' + text + | 887 return '<div class=link onclick="window.open(\'' + url + '\')">' + text + |
| 881 '</li>'; | 888 '</div>'; |
| 889 } | |
| 890 | |
| 891 function createBlameListHTML(revisions, index, urlBase, separator, repo) { | |
| 892 var thisRevision = revisions[index]; | |
| 893 if (!thisRevision) | |
| 894 return ''; | |
| 895 | |
| 896 var previousRevision = revisions[index + 1]; | |
| 897 if (previousRevision && previousRevision != thisRevision) { | |
| 898 previousRevision++; | |
| 899 return getLinkHTMLToOpenWindow( | |
| 900 urlBase + thisRevision + separator + previousRevision, | |
| 901 repo + ' blamelist r' + previousRevision + ':r' + thisRevision); | |
| 902 } else { | |
| 903 return 'At ' + repo + ' revision: ' + thisRevision; | |
| 904 } | |
| 882 } | 905 } |
| 883 | 906 |
| 884 function showPopupForBuild(e, builder, index) { | 907 function showPopupForBuild(e, builder, index) { |
| 885 var html = ''; | 908 var html = ''; |
| 886 | 909 |
| 887 var time = resultsByBuilder[builder].secondsSinceEpoch[index]; | 910 var time = resultsByBuilder[builder].secondsSinceEpoch[index]; |
| 888 if (time) { | 911 if (time) { |
| 889 var date = new Date(time * 1000); | 912 var date = new Date(time * 1000); |
| 890 html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString(); | 913 html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString(); |
| 891 } | 914 } |
| 892 | 915 |
| 893 html += '<ul>'; | 916 html += '<ul><li>' + |
| 917 createBlameListHTML(resultsByBuilder[builder].webkitRevision, index, | |
| 918 'http://trac.webkit.org/log/?rev=', '&stop_rev=', 'WebKit') + | |
| 919 '</li><li>' + | |
| 920 createBlameListHTML(resultsByBuilder[builder].chromeRevision, index, | |
| 921 'http://build.chromium.org/buildbot/perf/dashboard/ui/' + | |
| 922 'changelog.html?url=/trunk/src&mode=html&range=', ':', 'Chrome') + | |
| 923 '</li>'; | |
| 894 | 924 |
| 895 var webkitRevision = resultsByBuilder[builder].webkitRevision; | 925 var chromeRevision = resultsByBuilder[builder].chromeRevision[index]; |
| 896 var thisWebkitRevision = webkitRevision[index]; | 926 if (chromeRevision) { |
| 897 if (thisWebkitRevision) { | 927 html += '<li><a href="' + TEST_RESULTS_BASE_PATH + builders[builder] + |
| 898 var previousWebkitRevision = webkitRevision[index + 1] || | 928 '/' + chromeRevision + '/layout-test-results.zip' + |
| 899 thisWebkitRevision; | 929 '">layout-test-results.zip</a></li>'; |
| 900 html += getLinkHTMLToOpenWindow('http://trac.webkit.org/log/?rev=' + | |
| 901 thisWebkitRevision + '&stop_rev=' + previousWebkitRevision, | |
| 902 'WebKit blamelist r' + previousWebkitRevision + ':r' + | |
| 903 thisWebkitRevision); | |
| 904 } | |
| 905 | |
| 906 var chromeRevision = resultsByBuilder[builder].chromeRevision; | |
| 907 var thisChromeRevision = chromeRevision[index]; | |
| 908 if (thisChromeRevision) { | |
| 909 var previousChromeRevision = chromeRevision[index + 1] || | |
| 910 thisChromeRevision; | |
| 911 html += getLinkHTMLToOpenWindow( | |
| 912 'http://build.chromium.org/buildbot/perf/dashboard/ui/' + | |
| 913 'changelog.html?url=/trunk/src&mode=html&range=' + | |
| 914 previousChromeRevision + ':' + thisChromeRevision, | |
| 915 'Chrome blamelist r' + previousChromeRevision + ':r' + | |
| 916 thisChromeRevision) + | |
| 917 getLinkHTMLToOpenWindow(TEST_RESULTS_BASE_PATH + builders[builder] + | |
| 918 '/' + thisChromeRevision + '/layout-test-results.zip', | |
| 919 'layout-test-results.zip'); | |
| 920 } | 930 } |
| 921 | 931 |
| 922 var buildNumbers = resultsByBuilder[builder].buildNumbers; | 932 var buildNumbers = resultsByBuilder[builder].buildNumbers; |
| 923 html += getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' + | 933 html += '<li>' + |
| 924 buildNumbers[index], 'Build log and blamelist') + '</ul>'; | 934 getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' + |
| 935 buildNumbers[index], 'Build log and blamelist') + '</li></ul>'; | |
| 925 | 936 |
| 926 showPopup(e, html); | 937 showPopup(e, html); |
| 927 } | 938 } |
| 928 | 939 |
| 940 function showPopupForTest(e, test) { | |
| 941 showPopup(e, getHTMLForIndividulTestOnAllBuilders(test)); | |
| 942 } | |
| 943 | |
| 929 function getHtmlForTestResults(test, builder) { | 944 function getHtmlForTestResults(test, builder) { |
| 930 var html = ''; | 945 var html = ''; |
| 931 var results = test.rawResults.concat(); | 946 var results = test.rawResults.concat(); |
| 932 var times = test.rawTimes.concat(); | 947 var times = test.rawTimes.concat(); |
| 933 var buildNumbers = resultsByBuilder[builder].buildNumbers; | 948 var buildNumbers = resultsByBuilder[builder].buildNumbers; |
| 934 | 949 |
| 935 var indexToReplaceCurrentResult = -1; | 950 var indexToReplaceCurrentResult = -1; |
| 936 var indexToReplaceCurrentTime = -1; | 951 var indexToReplaceCurrentTime = -1; |
| 937 var currentResultArray, currentTimeArray, currentResult, innerHTML; | 952 var currentResultArray, currentTimeArray, currentResult, innerHTML; |
| 938 var maxIndex = Math.min(buildNumbers.length, currentState.maxResults); | 953 var maxIndex = Math.min(buildNumbers.length, currentState.maxResults); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1017 * Returns whether this tests results match the heuristic for new tests that | 1032 * Returns whether this tests results match the heuristic for new tests that |
| 1018 * have been fixed. Specifically, a new test that fails a couple | 1033 * have been fixed. Specifically, a new test that fails a couple |
| 1019 * times and then passes from then on would have results like PPPPFFFFNNNNN. | 1034 * times and then passes from then on would have results like PPPPFFFFNNNNN. |
| 1020 * Where that middle part can be a series of F's, S's or I's for the | 1035 * Where that middle part can be a series of F's, S's or I's for the |
| 1021 * different types of failures. | 1036 * different types of failures. |
| 1022 */ | 1037 */ |
| 1023 function isFixedTest(testResult) { | 1038 function isFixedTest(testResult) { |
| 1024 if (testResult.isFixedTest === undefined) { | 1039 if (testResult.isFixedTest === undefined) { |
| 1025 var results = testResult.rawResults; | 1040 var results = testResult.rawResults; |
| 1026 var isFixedTest = results[0][1] == 'P'; | 1041 var isFixedTest = results[0][1] == 'P'; |
| 1027 if (isFixedTest && results.length > 1) { | 1042 var numResults = results[0][0]; |
| 1028 var secondResult = results[1][1]; | 1043 if (numResults < currentState.maxResults && |
| 1029 isFixedTest = secondResult == 'S' || secondResult == 'F' || | 1044 isFixedTest && results.length > 1) { |
| 1030 secondResult == 'I'; | 1045 // We don't care what the value of the second set of results is, just |
| 1046 // how many results there are. | |
| 1047 numResults += results[1][0]; | |
| 1031 } | 1048 } |
| 1032 if (isFixedTest && results.length > 2) { | 1049 if (numResults < currentState.maxResults && |
| 1050 isFixedTest && results.length > 2) { | |
| 1033 isFixedTest = results.length == 3 && results[2][1] == 'N'; | 1051 isFixedTest = results.length == 3 && results[2][1] == 'N'; |
| 1034 } | 1052 } |
| 1035 testResult.isFixedTest = isFixedTest; | 1053 testResult.isFixedTest = isFixedTest; |
| 1036 } | 1054 } |
| 1037 return testResult.isFixedTest; | 1055 return testResult.isFixedTest; |
| 1038 } | 1056 } |
| 1039 | 1057 |
| 1040 /** | 1058 /** |
| 1041 * Returns whether we should exclude test results from the test table. | 1059 * Returns whether we should exclude test results from the test table. |
| 1042 * Note that we never want to exclude tests when we're in the individual | 1060 * Note that we never want to exclude tests when we're in the individual |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1064 if (shouldHideTest(test)) { | 1082 if (shouldHideTest(test)) { |
| 1065 // The innerHTML call is considerably faster if we exclude the rows for | 1083 // The innerHTML call is considerably faster if we exclude the rows for |
| 1066 // items we're not showing than if we hide them using display:none. | 1084 // items we're not showing than if we hide them using display:none. |
| 1067 return ''; | 1085 return ''; |
| 1068 } | 1086 } |
| 1069 | 1087 |
| 1070 // If opt_isCrossBuilderView is true, we're just viewing a single test | 1088 // If opt_isCrossBuilderView is true, we're just viewing a single test |
| 1071 // with results for many builders, so the first column is builder names | 1089 // with results for many builders, so the first column is builder names |
| 1072 // instead of test paths. | 1090 // instead of test paths. |
| 1073 var testCellHTML = opt_isCrossBuilderView ? builder : | 1091 var testCellHTML = opt_isCrossBuilderView ? builder : |
| 1074 '<span class="link" onclick="setState(\'tests\', \'' + test.test + | 1092 '<span class="link" onclick="showPopupForTest(event, \'' + test.test + |
| 1075 '\');return false;">' + test.test + '</span>'; | 1093 '\');return false;">' + test.test + '</span>'; |
| 1076 | 1094 |
| 1077 return '<tr class="' + | 1095 return '<tr class="' + |
| 1078 (test.meetsExpectations ? '' : 'wrong-expectations') + | 1096 (test.meetsExpectations ? '' : 'wrong-expectations') + |
| 1079 // TODO(ojan): If a test is a chrome/ or a pending/ test, point to | 1097 // TODO(ojan): If a test is a chrome/ or a pending/ test, point to |
| 1080 // src.chromium.org instead of trac.webkit.org. | 1098 // src.chromium.org instead of trac.webkit.org. |
| 1081 '"><td class=test-link>' + testCellHTML + | 1099 '"><td class=test-link>' + testCellHTML + |
| 1082 '</td><td class=options-container>' + test.bugsHTML + | 1100 '</td><td class=options-container>' + test.bugsHTML + |
| 1083 '</td><td class=options-container>' + test.modifiersHTML + | 1101 '</td><td class=options-container>' + test.modifiersHTML + |
| 1084 '</td><td class=options-container>' + test.expectationsHTML + | 1102 '</td><td class=options-container>' + test.expectationsHTML + |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1200 } | 1218 } |
| 1201 | 1219 |
| 1202 tableHeaders.shift(); | 1220 tableHeaders.shift(); |
| 1203 if (currentState.tests) { | 1221 if (currentState.tests) { |
| 1204 tableHeaders.unshift('builder'); | 1222 tableHeaders.unshift('builder'); |
| 1205 generatePageForIndividualTests(currentState.tests.split(',')); | 1223 generatePageForIndividualTests(currentState.tests.split(',')); |
| 1206 } else { | 1224 } else { |
| 1207 tableHeaders.unshift('test'); | 1225 tableHeaders.unshift('test'); |
| 1208 generatePageForBuilder(currentState.builder); | 1226 generatePageForBuilder(currentState.builder); |
| 1209 } | 1227 } |
| 1228 | |
| 1229 $('max-results-input').value = currentState.maxResults; | |
| 1230 updateLegendDisplay(); | |
| 1231 } | |
| 1232 | |
| 1233 function getHTMLForIndividulTestOnAllBuilders(test) { | |
| 1234 for (var builder in builders) | |
| 1235 processTestRunsForBuilder(builder); | |
| 1236 | |
| 1237 var testResults = testToResultsMap[test]; | |
| 1238 if (testResults && testResults.length) { | |
| 1239 var tracURL = TEST_URL_BASE_PATH + test | |
| 1240 var html = getLinkHTMLToOpenWindow(tracURL, tracURL) + | |
| 1241 '<div><b>If a builder is not listed, that means the builder does ' + | |
| 1242 '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/
| |
| 1243 | |
| 1244 for (var j = 0; j < testResults.length; j++) { | |
| 1245 html += getHTMLForSingleTestRow(testResults[j].results, | |
| 1246 testResults[j].builder, true); | |
| 1247 } | |
| 1248 return getHTMLForTestTable(html); | |
| 1249 } else { | |
| 1250 return '<div class="not-found">Test not found. Either it does not ' + | |
| 1251 'exist or it passes on all platforms.</div>'; | |
| 1252 } | |
| 1210 } | 1253 } |
| 1211 | 1254 |
| 1212 function generatePageForIndividualTests(tests) { | 1255 function generatePageForIndividualTests(tests) { |
| 1213 // TODO: Add link to trac from individual test page | 1256 var html = getHTMLForNavBar(); |
| 1214 // TODO: Make links on builder pages to tests be to the individual test page | |
| 1215 for (var builder in builders) | |
| 1216 processTestRunsForBuilder(builder); | |
| 1217 | |
| 1218 var html = getHTMLForNavBar() + | |
| 1219 '<b>IF A BUILDER IS NOT LISTED THAT MEANS THE ' + | |
| 1220 'BUILDER DOES NOT RUN THAT TEST OR ALL RUNS OF THE TEST PASSED.</b>'; | |
| 1221 | |
| 1222 for (var i = 0; i < tests.length; i++) { | 1257 for (var i = 0; i < tests.length; i++) { |
| 1223 html += '<h2>' + tests[i] + '</h2>'; | 1258 html += '<h2>' + tests[i] + '</h2>' + |
| 1224 | 1259 getHTMLForIndividulTestOnAllBuilders(tests[i]); |
| 1225 var testResults = testToResultsMap[tests[i]]; | |
| 1226 if (testResults && testResults.length) { | |
| 1227 var tableRowsHTML = ''; | |
| 1228 for (var j = 0; j < testResults.length; j++) { | |
| 1229 tableRowsHTML += getHTMLForSingleTestRow(testResults[j].results, | |
| 1230 testResults[j].builder, true); | |
| 1231 } | |
| 1232 html += getHTMLForTestTable(tableRowsHTML); | |
| 1233 } else { | |
| 1234 html +='<div class="not-found">Test not found. Either it does not ' + | |
| 1235 'exist or it passes on all platforms.</div>'; | |
| 1236 } | |
| 1237 } | 1260 } |
| 1238 setFullPageHTML(html); | 1261 setFullPageHTML(html); |
| 1239 | 1262 |
| 1240 $('tests-input').value = currentState.tests; | 1263 $('tests-input').value = currentState.tests; |
| 1241 } | 1264 } |
| 1242 | 1265 |
| 1243 function getHTMLForNavBar(opt_builderName) { | 1266 function getHTMLForNavBar(opt_builderName) { |
| 1244 var html = '<div id=builders>'; | 1267 var html = '<div id=builders>'; |
| 1245 for (var builder in builders) { | 1268 for (var builder in builders) { |
| 1246 var className = builder == opt_builderName ? 'current-builder' : 'link'; | 1269 var className = builder == opt_builderName ? 'current-builder' : 'link'; |
| 1247 html += '<span class=' + className + | 1270 html += '<span class=' + className + |
| 1248 ' onclick=\'setState("builder", "' + builder + '")\'>' + | 1271 ' onclick=\'setState("builder", "' + builder + '")\'>' + |
| 1249 builder + '</span>'; | 1272 builder + '</span>'; |
| 1250 } | 1273 } |
| 1251 html += '</div>' + | 1274 html += '</div>' + |
| 1252 '<form id=tests-form ' + | 1275 '<form id=tests-form ' + |
| 1253 'onsubmit="setState(\'tests\', tests.value);return false;">' + | 1276 'onsubmit="setState(\'tests\', tests.value);return false;">' + |
| 1254 '<div>Show tests on all platforms (slow): </div><input name=tests ' + | 1277 '<div>Show tests on all platforms (slow): </div><input name=tests ' + |
| 1255 'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' + | 1278 'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' + |
| 1256 'id=tests-input></form><div id="loading-ui">LOADING...</div>' + | 1279 'id=tests-input></form>' + |
| 1257 '<div id=legend>'; | 1280 '<form id=max-results-form ' + |
| 1281 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' + | |
| 1282 '><span>Number of results to show (max=500): </span>' + | |
| 1283 '<input name=maxResults id=max-results-input></form>' + | |
| 1284 '<div id="loading-ui">LOADING...</div><div id=legend>' + | |
| 1285 '<div id=legend-toggle>' + getLinkHTMLToToggleLegendDisplay() + | |
| 1286 '</div><div id=legend-contents>'; | |
| 1258 | 1287 |
| 1259 for (var expectation in EXPECTATIONS_MAP) { | 1288 for (var expectation in EXPECTATIONS_MAP) { |
| 1260 html += '<div class=' + expectation + '>' + | 1289 html += '<div class=' + expectation + '>' + |
| 1261 EXPECTATIONS_MAP[expectation] + '</div>'; | 1290 EXPECTATIONS_MAP[expectation] + '</div>'; |
| 1262 } | 1291 } |
| 1263 return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' + | 1292 return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' + |
| 1264 '<div class=merge>WEBKIT MERGE</div></div>'; | 1293 '<div class=merge>WEBKIT MERGE</div></div></div>'; |
| 1265 } | 1294 } |
| 1266 | 1295 |
| 1267 function getLinkHTMLToToggleState(key, linkText) { | 1296 function getLinkHTMLToToggleState(key, linkText) { |
| 1268 var isTrue = currentState[key]; | 1297 var isTrue = currentState[key]; |
| 1269 return '<span class=link onclick="setState(\'' + key + '\', ' + !isTrue + | 1298 return '<span class=link onclick="setState(\'' + key + '\', ' + !isTrue + |
| 1270 ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span>'; | 1299 ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span>'; |
| 1271 } | 1300 } |
| 1272 | 1301 |
| 1273 function generatePageForBuilder(builderName) { | 1302 function generatePageForBuilder(builderName) { |
| 1274 processTestRunsForBuilder(builderName); | 1303 processTestRunsForBuilder(builderName); |
| 1275 | 1304 |
| 1276 var tableRowsHTML = ''; | 1305 var tableRowsHTML = ''; |
| 1277 var results = perBuilderFailures[builderName]; | 1306 var results = perBuilderFailures[builderName]; |
| 1278 sortTests(results, currentState.sortColumn, currentState.sortOrder); | 1307 sortTests(results, currentState.sortColumn, currentState.sortOrder); |
| 1279 for (var i = 0; i < results.length; i++) { | 1308 for (var i = 0; i < results.length; i++) { |
| 1280 tableRowsHTML += getHTMLForSingleTestRow(results[i], builderName); | 1309 tableRowsHTML += getHTMLForSingleTestRow(results[i], builderName); |
| 1281 } | 1310 } |
| 1282 | 1311 |
| 1283 var testsHTML = tableRowsHTML ? getHTMLForTestTable(tableRowsHTML) : | 1312 var testsHTML = tableRowsHTML ? getHTMLForTestTable(tableRowsHTML) : |
| 1284 '<div>No tests. Try showing tests with correct expectations.</div>'; | 1313 '<div>No tests. Try showing tests with correct expectations.</div>'; |
| 1285 | 1314 |
| 1286 var html = getHTMLForNavBar(builderName) + | 1315 var html = getHTMLForNavBar(builderName) + |
| 1287 getHTMLForTestsWithExpectationsButNoFailures(builderName) + | 1316 getHTMLForTestsWithExpectationsButNoFailures(builderName) + |
| 1288 '<h2>Failing tests</h2><div>' + | 1317 '<h2>Failing tests</h2><div>' + |
| 1289 getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') + ' | ' + | 1318 getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') + ' | ' + |
| 1290 getLinkHTMLToToggleState('showCorrectExpectations', | 1319 getLinkHTMLToToggleState('showCorrectExpectations', |
| 1291 'tests with correct expectations') + ' | ' + | 1320 'tests with correct expectations') + ' | ' + |
| 1292 getLinkHTMLToToggleState('showFlaky', 'flaky tests') + ' | ' + | 1321 getLinkHTMLToToggleState('showFlaky', 'flaky tests') + ' | ' + |
| 1293 '<form id=max-results-form ' + | 1322 '<b>All columns are sortable. | ' + |
| 1294 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' + | |
| 1295 '><span>Number of results to show: </span>' + | |
| 1296 '<input name=maxResults id=max-results-input></form> | ' + | |
| 1297 '<b>All columns are sortable. | Skipped tests are not listed. | ' + | |
| 1298 'Flakiness reader order is newer --> older runs.</b></div>' + | 1323 'Flakiness reader order is newer --> older runs.</b></div>' + |
| 1299 testsHTML; | 1324 testsHTML; |
| 1300 | 1325 |
| 1301 setFullPageHTML(html); | 1326 setFullPageHTML(html); |
| 1302 | 1327 |
| 1303 var ths = document.getElementsByTagName('th'); | 1328 var ths = document.getElementsByTagName('th'); |
| 1304 for (var i = 0; i < ths.length; i++) { | 1329 for (var i = 0; i < ths.length; i++) { |
| 1305 ths[i].addEventListener('click', changeSort, false); | 1330 ths[i].addEventListener('click', changeSort, false); |
| 1306 ths[i].className = "sortable"; | 1331 ths[i].className = "sortable"; |
| 1307 } | 1332 } |
| 1333 } | |
| 1308 | 1334 |
| 1309 $('max-results-input').value = currentState.maxResults; | 1335 function getLinkHTMLToToggleLegendDisplay() { |
| 1336 return getLinkHTMLToToggleState('showLegend', 'Legend'); | |
| 1337 } | |
| 1338 | |
| 1339 function updateLegendDisplay() { | |
| 1340 $('legend-contents').style.display = currentState.showLegend ? '' : 'none'; | |
| 1341 } | |
| 1342 | |
| 1343 /** | |
| 1344 * Clears the processed test state for perBuilderFailures. | |
| 1345 * TODO(ojan): This really should probably clear all the state we've | |
| 1346 * generated, but that's kind of a pain given the many global objects state is | |
| 1347 * stored in. There should probably be one global generatedState | |
| 1348 * object that all the generated state lives off of. | |
| 1349 */ | |
| 1350 function clearProcessedTestState() { | |
| 1351 for (var builder in builders) { | |
| 1352 delete perBuilderFailures[builder]; | |
| 1353 delete perBuilderPlatformAndBuildType[builder]; | |
| 1354 delete perBuilderWithExpectationsButNoFailures[builder]; | |
| 1355 delete perBuilderSkippedPaths[builder]; | |
| 1356 } | |
| 1357 | |
| 1358 for (var key in testToResultsMap) { | |
| 1359 delete testToResultsMap[key] | |
| 1360 } | |
| 1310 } | 1361 } |
| 1311 | 1362 |
| 1312 /** | 1363 /** |
| 1313 * Sets the page state and regenerates the page. Takes varargs of key, value | 1364 * Sets the page state and regenerates the page. Takes varargs of key, value |
| 1314 * pairs. | 1365 * pairs. |
| 1315 */ | 1366 */ |
| 1316 function setState(key, value) { | 1367 function setState(key, value) { |
| 1317 for (var i = 0; i < arguments.length; i = i + 2) { | 1368 for (var i = 0; i < arguments.length; i = i + 2) { |
| 1318 var key = arguments[i]; | 1369 var key = arguments[i]; |
| 1319 if (key != 'tests') { | 1370 if (key != 'tests' && key != 'maxResults') { |
| 1320 delete currentState.tests; | 1371 delete currentState.tests; |
| 1321 } | 1372 } |
| 1322 | 1373 |
| 1374 if (key == 'maxResults') { | |
| 1375 // Processing the test results JSON makes assumptions about the number | |
| 1376 // of results to show. This makes changing the number of maxResults slow | |
| 1377 // but is considerably easier than refactoring all the other code. | |
| 1378 clearProcessedTestState(); | |
| 1379 } | |
| 1380 | |
| 1323 currentState[key] = arguments[i + 1]; | 1381 currentState[key] = arguments[i + 1]; |
| 1324 } | 1382 } |
| 1325 window.location.replace(getPermaLinkURL()); | 1383 window.location.replace(getPermaLinkURL()); |
| 1326 handleLocationChange(); | 1384 if (key == 'showLegend') { |
| 1385 saveStoredWindowLocation(); | |
| 1386 updateLegendDisplay(); | |
| 1387 $('legend-toggle').innerHTML = getLinkHTMLToToggleLegendDisplay(); | |
| 1388 } else { | |
| 1389 handleLocationChange(); | |
| 1390 } | |
| 1391 } | |
| 1392 | |
| 1393 function saveStoredWindowLocation() { | |
| 1394 oldLocation = window.location.href; | |
| 1327 } | 1395 } |
| 1328 | 1396 |
| 1329 function handleLocationChange() { | 1397 function handleLocationChange() { |
| 1330 $('loading-ui').style.display = 'block'; | 1398 $('loading-ui').style.display = 'block'; |
| 1331 setTimeout(function() { | 1399 setTimeout(function() { |
| 1332 oldLocation = window.location.href; | 1400 saveStoredWindowLocation(); |
| 1333 generatePage(); | 1401 generatePage(); |
| 1334 }, 0); | 1402 }, 0); |
| 1335 } | 1403 } |
| 1336 | 1404 |
| 1337 function getPermaLinkURL() { | 1405 function getPermaLinkURL() { |
| 1338 return window.location.pathname + '#' + joinParameters(currentState); | 1406 return window.location.pathname + '#' + joinParameters(currentState); |
| 1339 } | 1407 } |
| 1340 | 1408 |
| 1341 function joinParameters(stateObject) { | 1409 function joinParameters(stateObject) { |
| 1342 var state = []; | 1410 var state = []; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1363 document.body.appendChild(popup); | 1431 document.body.appendChild(popup); |
| 1364 } | 1432 } |
| 1365 | 1433 |
| 1366 // Set html first so that we can get accurate size metrics on the popup. | 1434 // Set html first so that we can get accurate size metrics on the popup. |
| 1367 popup.innerHTML = html; | 1435 popup.innerHTML = html; |
| 1368 | 1436 |
| 1369 var targetRect = e.target.getBoundingClientRect(); | 1437 var targetRect = e.target.getBoundingClientRect(); |
| 1370 | 1438 |
| 1371 var x = Math.min(targetRect.left - 10, | 1439 var x = Math.min(targetRect.left - 10, |
| 1372 document.documentElement.clientWidth - popup.offsetWidth); | 1440 document.documentElement.clientWidth - popup.offsetWidth); |
| 1441 x = Math.max(0, x); | |
| 1373 popup.style.left = x + document.body.scrollLeft + 'px'; | 1442 popup.style.left = x + document.body.scrollLeft + 'px'; |
| 1374 | 1443 |
| 1375 var y = targetRect.top + targetRect.height; | 1444 var y = targetRect.top + targetRect.height; |
| 1376 if (y + popup.offsetHeight > document.documentElement.clientHeight) { | 1445 if (y + popup.offsetHeight > document.documentElement.clientHeight) { |
| 1377 y = targetRect.top - popup.offsetHeight; | 1446 y = targetRect.top - popup.offsetHeight; |
| 1378 } | 1447 } |
| 1448 y = Math.max(0, y); | |
| 1379 popup.style.top = y + document.body.scrollTop + 'px'; | 1449 popup.style.top = y + document.body.scrollTop + 'px'; |
| 1380 } | 1450 } |
| 1381 | 1451 |
| 1382 document.onmousedown = function(e) { | 1452 document.onmousedown = function(e) { |
| 1383 // Clear the open popup, unless the click was inside the popup. | 1453 // Clear the open popup, unless the click was inside the popup. |
| 1384 var popup = $('popup'); | 1454 var popup = $('popup'); |
| 1385 if (popup && e.target != popup && | 1455 if (popup && e.target != popup && |
| 1386 !(popup.compareDocumentPosition(e.target) & 16)) { | 1456 !(popup.compareDocumentPosition(e.target) & 16)) { |
| 1387 hidePopup(); | 1457 hidePopup(); |
| 1388 } | 1458 } |
| 1389 }; | 1459 }; |
| 1390 | 1460 |
| 1391 window.onload = function() { | 1461 window.onload = function() { |
| 1392 // This doesn't seem totally accurate as there is a race between | 1462 // This doesn't seem totally accurate as there is a race between |
| 1393 // onload firing and the last script tag being executed. | 1463 // onload firing and the last script tag being executed. |
| 1394 logTime('Time to load JS', pageLoadStartTime); | 1464 logTime('Time to load JS', pageLoadStartTime); |
| 1395 setInterval(function() { | 1465 setInterval(function() { |
| 1396 if (oldLocation != window.location.href) { | 1466 if (oldLocation != window.location.href) { |
| 1397 parseAllParameters(); | 1467 parseAllParameters(); |
| 1398 handleLocationChange(); | 1468 handleLocationChange(); |
| 1399 } | 1469 } |
| 1400 }, 100); | 1470 }, 100); |
| 1401 } | 1471 } |
| 1402 </script> | 1472 </script> |
| 1403 </head> | 1473 </head> |
| 1404 | 1474 |
| 1405 <body></body> | 1475 <body></body> |
| 1406 </html> | 1476 </html> |
| OLD | NEW |