| 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 { |
| 11 font-family: arial; | 11 font-family: arial; |
| 12 font-size: 13px; | 12 font-size: 13px; |
| 13 } | 13 } |
| 14 h2 { | 14 h2 { |
| 15 font-size: 16px; | 15 font-size: 16px; |
| 16 margin-bottom: .25em; | 16 margin-bottom: .25em; |
| 17 } | 17 } |
| 18 h3 { |
| 19 font-size: 13px; |
| 20 margin: 0; |
| 21 } |
| 18 #max-results-form { | 22 #max-results-form { |
| 19 display: inline; | 23 display: inline; |
| 20 } | 24 } |
| 21 #max-results-input { | 25 #max-results-input { |
| 22 width: 30px; | 26 width: 30px; |
| 23 } | 27 } |
| 24 #tests-form { | 28 #tests-form { |
| 25 display: -webkit-box; | 29 display: -webkit-box; |
| 26 } | 30 } |
| 27 #tests-form > * { | 31 #tests-form > * { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 121 } |
| 118 .S { | 122 .S { |
| 119 background-color: #c6c; | 123 background-color: #c6c; |
| 120 } | 124 } |
| 121 .F { | 125 .F { |
| 122 background-color: #e98080; | 126 background-color: #e98080; |
| 123 } | 127 } |
| 124 .O { | 128 .O { |
| 125 background-color: #69f; | 129 background-color: #69f; |
| 126 } | 130 } |
| 131 .merge { |
| 132 background-color: green; |
| 133 } |
| 134 :not(#legend) > .merge { |
| 135 width: 1px; |
| 136 } |
| 127 .separator { | 137 .separator { |
| 128 border: 1px solid lightgray; | 138 border: 1px solid lightgray; |
| 129 height: 0px; | 139 height: 0px; |
| 130 } | 140 } |
| 131 .different-platform { | 141 .different-platform { |
| 132 color: gray; | 142 color: gray; |
| 133 font-size: 10px; | 143 font-size: 10px; |
| 134 } | 144 } |
| 135 .current-builder { | 145 .current-builder { |
| 136 font-weight: bold; | 146 font-weight: bold; |
| 137 } | 147 } |
| 138 #passing-tests { | 148 #passing-tests { |
| 139 -webkit-column-count: 2; | 149 -webkit-column-count: 3; |
| 140 -webkit-column-gap: 25px; | 150 -webkit-column-gap: 25px; |
| 141 -webkit-column-rule: 1px dashed black; | 151 -webkit-column-rule: 1px dashed black; |
| 142 -moz-column-count: 2; | 152 -moz-column-count: 3; |
| 143 -moz-column-gap: 25px; | 153 -moz-column-gap: 25px; |
| 144 -moz-column-rule: 1px dashed black; | 154 -moz-column-rule: 1px dashed black; |
| 145 } | 155 } |
| 146 .not-found { | 156 .not-found { |
| 147 color: red; | 157 color: red; |
| 148 font-size: large; | 158 font-size: large; |
| 149 } | 159 } |
| 150 #loading-ui { | 160 #loading-ui { |
| 151 display: none; | 161 display: none; |
| 152 position: fixed; | 162 position: fixed; |
| 153 top: 0; | 163 top: 0; |
| 154 left: 0; | 164 left: 0; |
| 155 background-color: yellow; | 165 background-color: yellow; |
| 156 padding: 5px; | 166 padding: 5px; |
| 157 text-align: center; | 167 text-align: center; |
| 158 font-weight: bold; | 168 font-weight: bold; |
| 159 } | 169 } |
| 170 #popup { |
| 171 background-color: white; |
| 172 overflow: hidden; |
| 173 width: 250px; |
| 174 z-index: 1; |
| 175 position: absolute; |
| 176 border: 3px solid grey; |
| 177 padding: 3px; |
| 178 -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); |
| 180 -webkit-border-radius: 5px; |
| 181 -moz-border-radius: 5px; |
| 182 } |
| 183 #popup > * { |
| 184 width: 100%; |
| 185 } |
| 186 #popup > ul { |
| 187 margin: 0; |
| 188 padding-left: 20px; |
| 189 } |
| 160 </style> | 190 </style> |
| 161 | 191 |
| 162 <script> | 192 <script> |
| 163 /** | 193 /** |
| 164 * @fileoverview Creates a dashboard for multiple runs of a given set of tests | 194 * @fileoverview Creates a dashboard for multiple runs of a given set of tests |
| 165 * on the buildbots. Pulls in JSONP-ish files with the results for running | 195 * on the buildbots. Pulls in JSONP-ish files with the results for running |
| 166 * tests on a given builder (i.e. ADD_RESULTS(json_here)) and the expectations | 196 * tests on a given builder (i.e. ADD_RESULTS(json_here)) and the expectations |
| 167 * for all tests on all builders (i.e. ADD_EXPECTATIONS(json_here)). | 197 * for all tests on all builders (i.e. ADD_EXPECTATIONS(json_here)). |
| 168 * | 198 * |
| 169 * This shows flakiness of the tests as well as runtimes for slow tests. | 199 * This shows flakiness of the tests as well as runtimes for slow tests. |
| 170 * | 200 * |
| 171 * Also, each column in the dashboard is sortable. | 201 * Also, each column in the dashboard is sortable. |
| 172 * | 202 * |
| 173 * Currently, only webkit tests are supported, but adding other test types | 203 * Currently, only webkit tests are supported, but adding other test types |
| 174 * should just require the following steps: | 204 * should just require the following steps: |
| 175 * -generate results.json and expectations.json for these tests | 205 * -generate results.json and expectations.json for these tests |
| 176 * -copy them to the appropriate location | 206 * -copy them to the appropriate location |
| 177 * -add the builder name to the list of builders below. | 207 * -add the builder name to the list of builders below. |
| 178 */ | 208 */ |
| 179 | 209 |
| 180 // CONSTANTS | 210 // CONSTANTS |
| 181 var FORWARD = 'forward'; | 211 var FORWARD = 'forward'; |
| 182 var BACKWARD = 'backward'; | 212 var BACKWARD = 'backward'; |
| 183 var TEST_URL_BASE_PATH = | 213 var TEST_URL_BASE_PATH = |
| 184 'http://trac.webkit.org/projects/webkit/browser/trunk/'; | 214 'http://trac.webkit.org/projects/webkit/browser/trunk/'; |
| 185 var BUILDERS_BASE_PATH = | 215 var BUILDERS_BASE_PATH = |
| 186 'http://build.chromium.org/buildbot/waterfall/builders/'; | 216 'http://build.chromium.org/buildbot/waterfall/builders/'; |
| 187 var EXPECTATIONS_MAP = { | 217 var TEST_RESULTS_BASE_PATH = |
| 188 'T': 'TIMEOUT', | 218 'http://build.chromium.org/buildbot/layout_test_results/'; |
| 189 'C': 'CRASH', | 219 var EXPECTATIONS_MAP = { |
| 190 'P': 'PASS', | 220 'T': 'TIMEOUT', |
| 191 'F': 'TEXT FAIL', | 221 'C': 'CRASH', |
| 192 'S': 'SIMPLIFIED', | 222 'P': 'PASS', |
| 193 'I': 'IMAGE', | 223 'F': 'TEXT FAIL', |
| 194 'O': 'OTHER', | 224 'S': 'SIMPLIFIED', |
| 195 'N': 'NO DATA' | 225 'I': 'IMAGE', |
| 196 }; | 226 'O': 'OTHER', |
| 197 var PLATFORMS = {'MAC': 'MAC', 'LINUX': 'LINUX', 'WIN': 'WIN'}; | 227 'N': 'NO DATA' |
| 198 var BUILD_TYPES = {'DEBUG': 'DBG', 'RELEASE': 'RELEASE'}; | 228 }; |
| 229 var PLATFORMS = {'MAC': 'MAC', 'LINUX': 'LINUX', 'WIN': 'WIN'}; |
| 230 var BUILD_TYPES = {'DEBUG': 'DBG', 'RELEASE': 'RELEASE'}; |
| 199 | 231 |
| 200 // GLOBALS | 232 // GLOBALS |
| 201 // The DUMMYVALUE gets shifted off the array in the first call to | 233 // The DUMMYVALUE gets shifted off the array in the first call to |
| 202 // generatePage. | 234 // generatePage. |
| 203 var tableHeaders = ['DUMMYVALUE', 'bugs', 'modifiers', 'expectations', | 235 var tableHeaders = ['DUMMYVALUE', 'bugs', 'modifiers', 'expectations', |
| 204 'missing', 'extra', 'slowest run', | 236 'missing', 'extra', 'slowest run', |
| 205 'flakiness (numbers are runtimes in seconds)']; | 237 'flakiness (numbers are runtimes in seconds)']; |
| 206 var perBuilderPlatformAndBuildType = {}; | 238 var perBuilderPlatformAndBuildType = {}; |
| 207 var perBuilderFailures = {}; | 239 var perBuilderFailures = {}; |
| 208 // Map of builder to arrays of tests that are listed in the expectations file | 240 // Map of builder to arrays of tests that are listed in the expectations file |
| 209 // but have for that builder. | 241 // but have for that builder. |
| 210 var perBuilderWithExpectationsButNoFailures = {}; | 242 var perBuilderWithExpectationsButNoFailures = {}; |
| 211 | 243 // 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 |
| 245 // don't actually have any data here for skipped tests. |
| 246 var perBuilderSkippedPaths = {}; |
| 212 | 247 |
| 213 // Generic utility functions. | 248 // Generic utility functions. |
| 214 function $(id) { | 249 function $(id) { |
| 215 return document.getElementById(id); | 250 return document.getElementById(id); |
| 216 } | 251 } |
| 217 | 252 |
| 218 function stringContains(a, b) { | 253 function stringContains(a, b) { |
| 219 return a.indexOf(b) != -1; | 254 return a.indexOf(b) != -1; |
| 220 } | 255 } |
| 221 | 256 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 }; | 334 }; |
| 300 var builderBase = 'http://build.chromium.org/buildbot/'; | 335 var builderBase = 'http://build.chromium.org/buildbot/'; |
| 301 } | 336 } |
| 302 | 337 |
| 303 var defaultStateValues = { | 338 var defaultStateValues = { |
| 304 sortOrder: BACKWARD, | 339 sortOrder: BACKWARD, |
| 305 sortColumn: 'flakiness', | 340 sortColumn: 'flakiness', |
| 306 showWontFix: false, | 341 showWontFix: false, |
| 307 showCorrectExpectations: false, | 342 showCorrectExpectations: false, |
| 308 showFlaky: true, | 343 showFlaky: true, |
| 344 showSkipped: false, |
| 309 maxResults: 200, | 345 maxResults: 200, |
| 310 testType: 'layout_test_results' | 346 testType: 'layout_test_results' |
| 311 }; | 347 }; |
| 312 | 348 |
| 313 for (var builder in builders) { | |
| 314 defaultStateValues.builder = builder; | |
| 315 break; | |
| 316 } | |
| 317 | |
| 318 function fillDefaultStateValues() { | 349 function fillDefaultStateValues() { |
| 319 // tests has no states with default values. | |
| 320 if (currentState.tests) | |
| 321 return; | |
| 322 | |
| 323 for (var state in defaultStateValues) { | 350 for (var state in defaultStateValues) { |
| 324 if (!(state in currentState)) | 351 if (!(state in currentState)) |
| 325 currentState[state] = defaultStateValues[state]; | 352 currentState[state] = defaultStateValues[state]; |
| 326 } | 353 } |
| 354 |
| 355 if (!currentState.tests && !('builder' in currentState)) { |
| 356 for (var builder in builders) { |
| 357 currentState.builder = builder; |
| 358 break; |
| 359 } |
| 360 } |
| 327 } | 361 } |
| 328 | 362 |
| 329 function handleValidHashParameter(key, value) { | 363 function handleValidHashParameter(key, value) { |
| 330 switch(key) { | 364 switch(key) { |
| 331 case 'testType': | 365 case 'testType': |
| 332 validateParameter(currentState, key, value, | 366 validateParameter(currentState, key, value, |
| 333 function() { | 367 function() { |
| 334 return isValidName(value); | 368 return isValidName(value); |
| 335 }); | 369 }); |
| 336 | 370 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 } | 629 } |
| 596 | 630 |
| 597 return allTestsByPlatformAndBuildType[platform][buildType]; | 631 return allTestsByPlatformAndBuildType[platform][buildType]; |
| 598 } | 632 } |
| 599 | 633 |
| 600 /** | 634 /** |
| 601 * Adds the given test and path to the appropriate objects depending on | 635 * Adds the given test and path to the appropriate objects depending on |
| 602 * whether the modifiers match the builders platform and buildType. | 636 * whether the modifiers match the builders platform and buildType. |
| 603 */ | 637 */ |
| 604 function addTestAndExpectations(test, prefixPath, builder, expectationsMap, | 638 function addTestAndExpectations(test, prefixPath, builder, expectationsMap, |
| 605 expectations, testPrefixes) { | 639 expectations, testPrefixes, skippedPaths) { |
| 606 var modifiersForBuilder = | 640 var modifiersForBuilder = |
| 607 getModifierThatHasPlatformAndBuildType(builder, expectations); | 641 getModifierThatHasPlatformAndBuildType(builder, expectations); |
| 608 if (modifiersForBuilder) { | 642 |
| 609 if (getAllTestsWithSamePlatformAndBuildType(builder)[test]) { | 643 if (!modifiersForBuilder) |
| 610 expectationsMap[test] = expectations; | 644 return false; |
| 611 testPrefixes[test] = prefixPath; | 645 |
| 612 } else if (!stringContains(modifiersForBuilder.modifiers, 'SKIP') && | 646 if (getAllTestsWithSamePlatformAndBuildType(builder)[test]) { |
| 613 !modifiersForBuilder.expectations.match(/^\s*PASS\s*$/)) { | 647 expectationsMap[test] = expectations; |
| 648 testPrefixes[test] = prefixPath; |
| 649 } else if (!stringContains(modifiersForBuilder.modifiers, 'WONTFIX')) { |
| 650 |
| 651 if (stringContains(modifiersForBuilder.modifiers, 'SKIP')) { |
| 652 skippedPaths[prefixPath] = true; |
| 653 } else if (!modifiersForBuilder.expectations.match(/^\s*PASS\s*$/)) { |
| 614 // Don't include skip tests here as they'll look the same as a test | 654 // Don't include skip tests here as they'll look the same as a test |
| 615 // that passes on all builders. | 655 // that passes on all builders. |
| 616 // Also don't include tests that are only expected to pass, e.g. | 656 // Also don't include tests that are only expected to pass, e.g. |
| 617 // SLOW : foo/bar/baz.html = PASS | 657 // SLOW : foo/bar/baz.html = PASS |
| 618 // TODO(ojan): Should we also exclude WONTFIX tests here? | 658 // TODO(ojan): Should we also exclude WONTFIX tests here? |
| 619 perBuilderWithExpectationsButNoFailures[builder].push(test); | 659 perBuilderWithExpectationsButNoFailures[builder].push(test); |
| 620 } | 660 } |
| 621 return true; | |
| 622 } | 661 } |
| 623 return false; | 662 |
| 663 return true; |
| 624 } | 664 } |
| 625 | 665 |
| 626 /** | 666 /** |
| 627 * Naive check that path points to a directory. | 667 * Naive check that path points to a directory. |
| 628 */ | 668 */ |
| 629 function isDirectory(path) { | 669 function isDirectory(path) { |
| 630 return !stringContains(path, '.') | 670 return !stringContains(path, '.') |
| 631 } | 671 } |
| 632 | 672 |
| 633 function addHTMLToIndividualOptionsArray(array, html, isCurrentPlatform) { | 673 function addHTMLToIndividualOptionsArray(array, html, isCurrentPlatform) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 658 var allTests = getAllTests(); | 698 var allTests = getAllTests(); |
| 659 | 699 |
| 660 var expectationsMap = {}; | 700 var expectationsMap = {}; |
| 661 for (var test in allTests) { | 701 for (var test in allTests) { |
| 662 if (expectationsByTest[test]) | 702 if (expectationsByTest[test]) |
| 663 expectationsMap[test] = expectationsByTest[test]; | 703 expectationsMap[test] = expectationsByTest[test]; |
| 664 } | 704 } |
| 665 | 705 |
| 666 var testPrefixes = {}; | 706 var testPrefixes = {}; |
| 667 perBuilderWithExpectationsButNoFailures[builderName] = []; | 707 perBuilderWithExpectationsButNoFailures[builderName] = []; |
| 708 var skippedPaths = {}; |
| 668 for (var path in expectationsByTest) { | 709 for (var path in expectationsByTest) { |
| 669 var expectations = expectationsByTest[path]; | 710 var expectations = expectationsByTest[path]; |
| 670 if (!isDirectory(path) && | 711 if (!isDirectory(path) && |
| 671 addTestAndExpectations(path, path, builderName, expectationsMap, | 712 addTestAndExpectations(path, path, builderName, expectationsMap, |
| 672 expectations, testPrefixes)) { | 713 expectations, testPrefixes, skippedPaths)) { |
| 673 continue; | 714 continue; |
| 674 } | 715 } |
| 675 // Test path doesn't match a specific test, see if it prefix matches | 716 // Test path doesn't match a specific test, see if it prefix matches |
| 676 // any test. | 717 // any test. |
| 677 for (var test in allTests) { | 718 for (var test in allTests) { |
| 678 if (stringContains(test, path) && | 719 if (stringContains(test, path) && |
| 679 (!testPrefixes[test] || | 720 (!testPrefixes[test] || |
| 680 !stringContains(testPrefixes[test], path))) { | 721 !stringContains(testPrefixes[test], path))) { |
| 681 addTestAndExpectations(test, path, builderName, expectationsMap, | 722 addTestAndExpectations(test, path, builderName, expectationsMap, |
| 682 expectations, testPrefixes); | 723 expectations, testPrefixes, skippedPaths); |
| 683 } | 724 } |
| 684 } | 725 } |
| 685 } | 726 } |
| 727 |
| 728 perBuilderSkippedPaths[builderName] = []; |
| 729 for (var path in skippedPaths) { |
| 730 perBuilderSkippedPaths[builderName].push(path); |
| 731 } |
| 732 perBuilderSkippedPaths[builderName].sort(); |
| 686 perBuilderWithExpectationsButNoFailures[builderName].sort(); | 733 perBuilderWithExpectationsButNoFailures[builderName].sort(); |
| 687 | 734 |
| 688 var allTestsForThisBuilder = resultsByBuilder[builderName].tests; | 735 var allTestsForThisBuilder = resultsByBuilder[builderName].tests; |
| 689 for (var test in allTestsForThisBuilder) { | 736 for (var test in allTestsForThisBuilder) { |
| 690 var resultsForTest = createResultsObjectForTest(test); | 737 var resultsForTest = createResultsObjectForTest(test); |
| 691 | 738 |
| 692 if (expectationsMap[test] && expectationsMap[test].length) { | 739 if (expectationsMap[test] && expectationsMap[test].length) { |
| 693 var expectationsArray = expectationsMap[test]; | 740 var expectationsArray = expectationsMap[test]; |
| 694 var htmlArrays = {}; | 741 var htmlArrays = {}; |
| 695 htmlArrays.expectations = []; | 742 htmlArrays.expectations = []; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 if (!hasExpectation) | 816 if (!hasExpectation) |
| 770 missingExpectations.push(result); | 817 missingExpectations.push(result); |
| 771 } | 818 } |
| 772 | 819 |
| 773 var times = resultsByBuilder[builderName].tests[test].times; | 820 var times = resultsByBuilder[builderName].tests[test].times; |
| 774 for (var i = 0; i < times.length; i++) { | 821 for (var i = 0; i < times.length; i++) { |
| 775 resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime, | 822 resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime, |
| 776 times[i][1]); | 823 times[i][1]); |
| 777 } | 824 } |
| 778 | 825 |
| 779 if (resultsForTest.slowestTime && | 826 if (resultsForTest.slowestTime && !resultsMap['TIMEOUT'] && |
| 780 (!resultsForTest.expectations || | 827 (!resultsForTest.expectations || |
| 781 !stringContains(resultsForTest.expectations, 'TIMEOUT')) && | 828 !stringContains(resultsForTest.expectations, 'TIMEOUT')) && |
| 782 (!resultsForTest.modifiers || | 829 (!resultsForTest.modifiers || |
| 783 !stringContains(resultsForTest.modifiers, 'SLOW'))) { | 830 !stringContains(resultsForTest.modifiers, 'SLOW'))) { |
| 784 missingExpectations.push('SLOW'); | 831 missingExpectations.push('SLOW'); |
| 785 } | 832 } |
| 786 | 833 |
| 787 resultsForTest.meetsExpectations = | 834 resultsForTest.meetsExpectations = |
| 788 !missingExpectations.length && !extraExpectations.length; | 835 !missingExpectations.length && !extraExpectations.length; |
| 789 resultsForTest.missing = missingExpectations.sort().join(' '); | 836 resultsForTest.missing = missingExpectations.sort().join(' '); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 * are internal google bugs. | 869 * are internal google bugs. |
| 823 */ | 870 */ |
| 824 function getHtmlForBugs(bugs) { | 871 function getHtmlForBugs(bugs) { |
| 825 bugs = bugs.replace(/BUG(\d{4})(\ |$)/g, externalBugReplaceValue); | 872 bugs = bugs.replace(/BUG(\d{4})(\ |$)/g, externalBugReplaceValue); |
| 826 bugs = bugs.replace(/BUG(\d{5})(\ |$)/g, externalBugReplaceValue); | 873 bugs = bugs.replace(/BUG(\d{5})(\ |$)/g, externalBugReplaceValue); |
| 827 bugs = bugs.replace(/BUG(\d{6})(\ |$)/g, internalBugReplaceValue); | 874 bugs = bugs.replace(/BUG(\d{6})(\ |$)/g, internalBugReplaceValue); |
| 828 bugs = bugs.replace(/BUG(\d{7})(\ |$)/g, internalBugReplaceValue); | 875 bugs = bugs.replace(/BUG(\d{7})(\ |$)/g, internalBugReplaceValue); |
| 829 return bugs; | 876 return bugs; |
| 830 } | 877 } |
| 831 | 878 |
| 832 function loadBuilderPageForBuildNumber(builderName, buildNumber) { | 879 function getLinkHTMLToOpenWindow(url, text) { |
| 833 window.open(BUILDERS_BASE_PATH + builderName + '/builds/' + buildNumber); | 880 return '<li class=link onclick="window.open(\'' + url + '\')">' + text + |
| 881 '</li>'; |
| 882 } |
| 883 |
| 884 function showPopupForBuild(e, builder, index) { |
| 885 var html = ''; |
| 886 |
| 887 var time = resultsByBuilder[builder].secondsSinceEpoch[index]; |
| 888 if (time) { |
| 889 var date = new Date(time * 1000); |
| 890 html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString(); |
| 891 } |
| 892 |
| 893 html += '<ul>'; |
| 894 |
| 895 var webkitRevision = resultsByBuilder[builder].webkitRevision; |
| 896 var thisWebkitRevision = webkitRevision[index]; |
| 897 if (thisWebkitRevision) { |
| 898 var previousWebkitRevision = webkitRevision[index + 1] || |
| 899 thisWebkitRevision; |
| 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 } |
| 921 |
| 922 var buildNumbers = resultsByBuilder[builder].buildNumbers; |
| 923 html += getLinkHTMLToOpenWindow(BUILDERS_BASE_PATH + builder + '/builds/' + |
| 924 buildNumbers[index], 'Build log and blamelist') + '</ul>'; |
| 925 |
| 926 showPopup(e, html); |
| 834 } | 927 } |
| 835 | 928 |
| 836 function getHtmlForTestResults(test, builder) { | 929 function getHtmlForTestResults(test, builder) { |
| 837 var html = ''; | 930 var html = ''; |
| 838 var results = test.rawResults.concat(); | 931 var results = test.rawResults.concat(); |
| 839 var times = test.rawTimes.concat(); | 932 var times = test.rawTimes.concat(); |
| 840 var buildNumbers = resultsByBuilder[builder].buildNumbers; | 933 var buildNumbers = resultsByBuilder[builder].buildNumbers; |
| 841 | 934 |
| 842 var indexToReplaceCurrentResult = -1; | 935 var indexToReplaceCurrentResult = -1; |
| 843 var indexToReplaceCurrentTime = -1; | 936 var indexToReplaceCurrentTime = -1; |
| 844 var currentResultArray, currentTimeArray, currentResult, innerHTML; | 937 var currentResultArray, currentTimeArray, currentResult, innerHTML; |
| 845 for (var i = 0; | 938 var maxIndex = Math.min(buildNumbers.length, currentState.maxResults); |
| 846 i < buildNumbers.length && i < currentState.maxResults; | 939 for (var i = 0; i < maxIndex; i++) { |
| 847 i++) { | |
| 848 if (i > indexToReplaceCurrentResult) { | 940 if (i > indexToReplaceCurrentResult) { |
| 849 currentResultArray = results.shift(); | 941 currentResultArray = results.shift(); |
| 850 if (currentResultArray) { | 942 if (currentResultArray) { |
| 851 currentResult = currentResultArray[1]; | 943 currentResult = currentResultArray[1]; |
| 852 indexToReplaceCurrentResult += currentResultArray[0]; | 944 indexToReplaceCurrentResult += currentResultArray[0]; |
| 853 } else { | 945 } else { |
| 854 currentResult = 'N'; | 946 currentResult = 'N'; |
| 855 indexToReplaceCurrentResult += buildNumbers.length; | 947 indexToReplaceCurrentResult += buildNumbers.length; |
| 856 } | 948 } |
| 857 } | 949 } |
| 858 | 950 |
| 859 if (i > indexToReplaceCurrentTime) { | 951 if (i > indexToReplaceCurrentTime) { |
| 860 currentTimeArray = times.shift(); | 952 currentTimeArray = times.shift(); |
| 861 var currentTime = 0; | 953 var currentTime = 0; |
| 862 if (currentResultArray) { | 954 if (currentResultArray) { |
| 863 currentTime = currentTimeArray[1]; | 955 currentTime = currentTimeArray[1]; |
| 864 indexToReplaceCurrentTime += currentTimeArray[0]; | 956 indexToReplaceCurrentTime += currentTimeArray[0]; |
| 865 } else { | 957 } else { |
| 866 indexToReplaceCurrentTime += buildNumbers.length; | 958 indexToReplaceCurrentTime += buildNumbers.length; |
| 867 } | 959 } |
| 868 innerHTML = currentTime || ' '; | 960 innerHTML = currentTime || ' '; |
| 869 } | 961 } |
| 870 | 962 |
| 871 var buildNumber = buildNumbers[i]; | 963 html += '<td title="Click results for handy links." class="results ' + |
| 872 html += '<td title="Build:' + buildNumber + '" class="results ' + | 964 currentResult + '" onclick=\'showPopupForBuild(event, "' + builder + |
| 873 currentResult + '" onclick=\'loadBuilderPageForBuildNumber("' + | 965 '",' + i + ')\'>' + innerHTML + '</td>'; |
| 874 builder + '","' + buildNumber + '")\'>' + innerHTML + '</td>'; | 966 |
| 967 var webkitRevision = resultsByBuilder[builder].webkitRevision; |
| 968 var isWebkitMerge = webkitRevision[i + 1] && |
| 969 webkitRevision[i] != webkitRevision[i + 1]; |
| 970 if (isWebkitMerge) |
| 971 html += '<td class=merge></td>'; |
| 875 } | 972 } |
| 876 return html; | 973 return html; |
| 877 } | 974 } |
| 878 | 975 |
| 879 function getHTMLForTestsWithExpectationsButNoFailures(builder) { | 976 function getHTMLForTestsWithExpectationsButNoFailures(builder) { |
| 880 var tests = perBuilderWithExpectationsButNoFailures[builder]; | 977 var tests = perBuilderWithExpectationsButNoFailures[builder]; |
| 881 if (!tests.length) | 978 var skippedPaths = perBuilderSkippedPaths[builder]; |
| 882 return ''; | |
| 883 | 979 |
| 884 var buildInfo = getPlatFormAndBuildType(builder); | 980 var html = ''; |
| 885 return '<h2>Have expectations for ' + buildInfo.platform + '-' + | 981 if (tests.length || skippedPaths.length) { |
| 886 buildInfo.buildType + ' but have not failed in last ' + | 982 var buildInfo = getPlatFormAndBuildType(builder); |
| 983 html += '<h2>Expectations for ' + buildInfo.platform + '-' + |
| 984 buildInfo.buildType + ':</h2>'; |
| 985 } |
| 986 |
| 987 if (tests.length) { |
| 988 html += '<h3>Have not failed in last ' + |
| 887 resultsByBuilder[builderName].buildNumbers.length + | 989 resultsByBuilder[builderName].buildNumbers.length + |
| 888 ' runs.</h2><div id="passing-tests"><div>' + | 990 ' runs.</h3><div id="passing-tests"><div>' + |
| 889 tests.join('</div><div>') + '</div></div>'; | 991 tests.join('</div><div>') + '</div></div>'; |
| 992 } |
| 993 |
| 994 if (skippedPaths.length) { |
| 995 html += '<h3>' + |
| 996 getLinkHTMLToToggleState('showSkipped', |
| 997 'Skipped tests in text_expectations.txt') + |
| 998 '</h3>'; |
| 999 |
| 1000 if (currentState.showSkipped) { |
| 1001 html += '<div id="passing-tests"><div>' + |
| 1002 skippedPaths.join('</div><div>') + '</div></div>'; |
| 1003 } |
| 1004 } |
| 1005 return html; |
| 890 } | 1006 } |
| 891 | 1007 |
| 892 /** | 1008 /** |
| 893 * Returns true if a test should be considered flaky. Uses heuristics to | 1009 * Returns true if a test should be considered flaky. Uses heuristics to |
| 894 * avoid common non-flaky cases. | 1010 * avoid common non-flaky cases. |
| 895 */ | 1011 */ |
| 896 function isTestFlaky(testResult) { | 1012 function isTestFlaky(testResult) { |
| 897 return testResult.flips > 1 && !isFixedTest(testResult); | 1013 return testResult.flips > 1 && !isFixedTest(testResult); |
| 898 } | 1014 } |
| 899 | 1015 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 '<div>Show tests on all platforms (slow): </div><input name=tests ' + | 1254 '<div>Show tests on all platforms (slow): </div><input name=tests ' + |
| 1139 'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' + | 1255 'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' + |
| 1140 'id=tests-input></form><div id="loading-ui">LOADING...</div>' + | 1256 'id=tests-input></form><div id="loading-ui">LOADING...</div>' + |
| 1141 '<div id=legend>'; | 1257 '<div id=legend>'; |
| 1142 | 1258 |
| 1143 for (var expectation in EXPECTATIONS_MAP) { | 1259 for (var expectation in EXPECTATIONS_MAP) { |
| 1144 html += '<div class=' + expectation + '>' + | 1260 html += '<div class=' + expectation + '>' + |
| 1145 EXPECTATIONS_MAP[expectation] + '</div>'; | 1261 EXPECTATIONS_MAP[expectation] + '</div>'; |
| 1146 } | 1262 } |
| 1147 return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' + | 1263 return html + '<div class=wrong-expectations>WRONG EXPECTATIONS</div>' + |
| 1148 '</div>'; | 1264 '<div class=merge>WEBKIT MERGE</div></div>'; |
| 1149 } | 1265 } |
| 1150 | 1266 |
| 1151 function getLinkHTMLToToggleState(key, linkText) { | 1267 function getLinkHTMLToToggleState(key, linkText) { |
| 1152 var isTrue = currentState[key]; | 1268 var isTrue = currentState[key]; |
| 1153 return '<span class=link onclick="setState(\'' + key + '\', ' + !isTrue + | 1269 return '<span class=link onclick="setState(\'' + key + '\', ' + !isTrue + |
| 1154 ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span> | '; | 1270 ')">' + (isTrue ? 'Hide' : 'Show') + ' ' + linkText + '</span>'; |
| 1155 } | 1271 } |
| 1156 | 1272 |
| 1157 function generatePageForBuilder(builderName) { | 1273 function generatePageForBuilder(builderName) { |
| 1158 processTestRunsForBuilder(builderName); | 1274 processTestRunsForBuilder(builderName); |
| 1159 | 1275 |
| 1160 var tableRowsHTML = ''; | 1276 var tableRowsHTML = ''; |
| 1161 var results = perBuilderFailures[builderName]; | 1277 var results = perBuilderFailures[builderName]; |
| 1162 sortTests(results, currentState.sortColumn, currentState.sortOrder); | 1278 sortTests(results, currentState.sortColumn, currentState.sortOrder); |
| 1163 for (var i = 0; i < results.length; i++) { | 1279 for (var i = 0; i < results.length; i++) { |
| 1164 tableRowsHTML += getHTMLForSingleTestRow(results[i], builderName); | 1280 tableRowsHTML += getHTMLForSingleTestRow(results[i], builderName); |
| 1165 } | 1281 } |
| 1166 | 1282 |
| 1167 var testsHTML = tableRowsHTML ? getHTMLForTestTable(tableRowsHTML) : | 1283 var testsHTML = tableRowsHTML ? getHTMLForTestTable(tableRowsHTML) : |
| 1168 '<div>No tests. Try showing tests with correct expectations.</div>'; | 1284 '<div>No tests. Try showing tests with correct expectations.</div>'; |
| 1169 | 1285 |
| 1170 var html = getHTMLForNavBar(builderName) + | 1286 var html = getHTMLForNavBar(builderName) + |
| 1171 getHTMLForTestsWithExpectationsButNoFailures(builderName) + | 1287 getHTMLForTestsWithExpectationsButNoFailures(builderName) + |
| 1172 '<h2>Failing tests</h2><div>' + | 1288 '<h2>Failing tests</h2><div>' + |
| 1173 getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') + | 1289 getLinkHTMLToToggleState('showWontFix', 'WONTFIX tests') + ' | ' + |
| 1174 getLinkHTMLToToggleState('showCorrectExpectations', | 1290 getLinkHTMLToToggleState('showCorrectExpectations', |
| 1175 'tests with correct expectations') + | 1291 'tests with correct expectations') + ' | ' + |
| 1176 getLinkHTMLToToggleState('showFlaky', 'flaky tests') + | 1292 getLinkHTMLToToggleState('showFlaky', 'flaky tests') + ' | ' + |
| 1177 '<form id=max-results-form ' + | 1293 '<form id=max-results-form ' + |
| 1178 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' + | 1294 'onsubmit="setState(\'maxResults\', maxResults.value);return false;"' + |
| 1179 '><span>Max results to show: </span>' + | 1295 '><span>Number of results to show: </span>' + |
| 1180 '<input name=maxResults id=max-results-input></form> | ' + | 1296 '<input name=maxResults id=max-results-input></form> | ' + |
| 1181 '<b>All columns are sortable. | Skipped tests are not listed. | ' + | 1297 '<b>All columns are sortable. | Skipped tests are not listed. | ' + |
| 1182 'Flakiness reader order is newer --> older runs.</b></div>' + | 1298 'Flakiness reader order is newer --> older runs.</b></div>' + |
| 1183 testsHTML; | 1299 testsHTML; |
| 1184 | 1300 |
| 1185 setFullPageHTML(html); | 1301 setFullPageHTML(html); |
| 1186 | 1302 |
| 1187 var ths = document.getElementsByTagName('th'); | 1303 var ths = document.getElementsByTagName('th'); |
| 1188 for (var i = 0; i < ths.length; i++) { | 1304 for (var i = 0; i < ths.length; i++) { |
| 1189 ths[i].addEventListener('click', changeSort, false); | 1305 ths[i].addEventListener('click', changeSort, false); |
| 1190 ths[i].className = "sortable"; | 1306 ths[i].className = "sortable"; |
| 1191 } | 1307 } |
| 1192 | 1308 |
| 1193 $('max-results-input').value = currentState.maxResults; | 1309 $('max-results-input').value = currentState.maxResults; |
| 1194 } | 1310 } |
| 1195 | 1311 |
| 1196 var singleBuilderViewParameters = ['sortOrder', 'sortColumn', 'showWontFix', | |
| 1197 'showCorrectExpectations', 'showFlaky: true', 'maxResults']; | |
| 1198 | |
| 1199 /** | 1312 /** |
| 1200 * Sets the page state and regenerates the page. Takes varargs of key, value | 1313 * Sets the page state and regenerates the page. Takes varargs of key, value |
| 1201 * pairs. | 1314 * pairs. |
| 1202 */ | 1315 */ |
| 1203 function setState(key, value) { | 1316 function setState(key, value) { |
| 1204 for (var i = 0; i < arguments.length; i = i + 2) { | 1317 for (var i = 0; i < arguments.length; i = i + 2) { |
| 1205 var key = arguments[i]; | 1318 var key = arguments[i]; |
| 1206 if (key == 'tests') { | 1319 if (key != 'tests') { |
| 1207 for (var state in singleBuilderViewParameters) { | |
| 1208 delete currentState[state]; | |
| 1209 } | |
| 1210 } else { | |
| 1211 delete currentState.tests; | 1320 delete currentState.tests; |
| 1212 } | 1321 } |
| 1213 | 1322 |
| 1214 currentState[key] = arguments[i + 1]; | 1323 currentState[key] = arguments[i + 1]; |
| 1215 } | 1324 } |
| 1216 window.location.replace(getPermaLinkURL()); | 1325 window.location.replace(getPermaLinkURL()); |
| 1217 handleLocationChange(); | 1326 handleLocationChange(); |
| 1218 } | 1327 } |
| 1219 | 1328 |
| 1220 function handleLocationChange() { | 1329 function handleLocationChange() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1234 for (var key in stateObject) { | 1343 for (var key in stateObject) { |
| 1235 state.push(key + '=' + encodeURIComponent(stateObject[key])); | 1344 state.push(key + '=' + encodeURIComponent(stateObject[key])); |
| 1236 } | 1345 } |
| 1237 return state.join('&'); | 1346 return state.join('&'); |
| 1238 } | 1347 } |
| 1239 | 1348 |
| 1240 function logTime(msg, startTime) { | 1349 function logTime(msg, startTime) { |
| 1241 console.log(msg + ': ' + (Date.now() - startTime)); | 1350 console.log(msg + ': ' + (Date.now() - startTime)); |
| 1242 } | 1351 } |
| 1243 | 1352 |
| 1353 function hidePopup() { |
| 1354 var popup = $('popup'); |
| 1355 popup.parentNode.removeChild(popup); |
| 1356 } |
| 1357 |
| 1358 function showPopup(e, html) { |
| 1359 var popup = $('popup'); |
| 1360 if (!popup) { |
| 1361 popup = document.createElement('div'); |
| 1362 popup.id = 'popup'; |
| 1363 document.body.appendChild(popup); |
| 1364 } |
| 1365 |
| 1366 // Set html first so that we can get accurate size metrics on the popup. |
| 1367 popup.innerHTML = html; |
| 1368 |
| 1369 var targetRect = e.target.getBoundingClientRect(); |
| 1370 |
| 1371 var x = Math.min(targetRect.left - 10, |
| 1372 document.documentElement.clientWidth - popup.offsetWidth); |
| 1373 popup.style.left = x + document.body.scrollLeft + 'px'; |
| 1374 |
| 1375 var y = targetRect.top + targetRect.height; |
| 1376 if (y + popup.offsetHeight > document.documentElement.clientHeight) { |
| 1377 y = targetRect.top - popup.offsetHeight; |
| 1378 } |
| 1379 popup.style.top = y + document.body.scrollTop + 'px'; |
| 1380 } |
| 1381 |
| 1382 document.onmousedown = function(e) { |
| 1383 // Clear the open popup, unless the click was inside the popup. |
| 1384 var popup = $('popup'); |
| 1385 if (popup && e.target != popup && |
| 1386 !(popup.compareDocumentPosition(e.target) & 16)) { |
| 1387 hidePopup(); |
| 1388 } |
| 1389 }; |
| 1390 |
| 1244 window.onload = function() { | 1391 window.onload = function() { |
| 1245 // This doesn't seem totally accurate as there is a race between | 1392 // This doesn't seem totally accurate as there is a race between |
| 1246 // onload firing and the last script tag being executed. | 1393 // onload firing and the last script tag being executed. |
| 1247 logTime('Time to load JS', pageLoadStartTime); | 1394 logTime('Time to load JS', pageLoadStartTime); |
| 1248 setInterval(function() { | 1395 setInterval(function() { |
| 1249 if (oldLocation != window.location.href) { | 1396 if (oldLocation != window.location.href) { |
| 1250 parseAllParameters(); | 1397 parseAllParameters(); |
| 1251 handleLocationChange(); | 1398 handleLocationChange(); |
| 1252 } | 1399 } |
| 1253 }, 100); | 1400 }, 100); |
| 1254 } | 1401 } |
| 1255 </script> | 1402 </script> |
| 1256 </head> | 1403 </head> |
| 1257 | 1404 |
| 1258 <body></body> | 1405 <body></body> |
| 1259 </html> | 1406 </html> |
| OLD | NEW |