Changeset 94580 in webkit
- Timestamp:
- Sep 6, 2011 11:02:50 AM (13 years ago)
- Location:
- trunk/Tools
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/controllers.js
r94540 r94580 33 33 this._view = view; 34 34 this._resultsByTest = resultsByTest; 35 36 this._view.setTestList(Object.keys(this._resultsByTest));37 35 this._view.setResultsByTest(resultsByTest); 38 39 this._view.addAction(new ui.actions.Rebaseline().makeDefault()); 40 this._view.addAction(new ui.actions.Previous()); 41 this._view.addAction(new ui.actions.Next()); 42 43 $(this._view).bind('testselected', this.onTestSelected.bind(this)); 44 $(this._view).bind('builderselected', this.onBuilderSelected.bind(this)); 45 $(this._view).bind('rebaseline', this.onRebaseline.bind(this)); 46 }, 47 showTest: function(testName) 48 { 49 var builderNameList = Object.keys(this._resultsByTest[testName]); 50 this._view.setBuilderList(builderNameList) 51 this._view.showResults(results.failureInfoForTestAndBuilder(this._resultsByTest, testName, builderNameList[0])); 52 }, 53 onTestSelected: function() 54 { 55 this.showTest(this._view.currentTestName()); 56 }, 57 onBuilderSelected: function() { 58 this._view.showResults(results.failureInfoForTestAndBuilder(this._resultsByTest, this._view.currentTestName(), this._view.currentBuilderName())); 59 }, 60 onRebaseline: function() { 61 var testName = this._view.currentTestName(); 62 var builderName = this._view.currentBuilderName(); 63 model.queueForRebaseline({ 64 'testName': testName, 65 'builderName': builderName 66 }); 36 // FIXME: Wire up some actions. 67 37 }, 68 38 }); … … 115 85 116 86 var controller = new controllers.ResultsDetails(resultsView, failuresByTest); 117 controller.showTest(testNameList[0]);118 87 119 88 // FIXME: This doesn't belong here. -
trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/results.js
r94486 r94580 463 463 }; 464 464 465 function resultsDirectoryForBuilder(builderName)465 results.directoryForBuilder = function(builderName) 466 466 { 467 467 return builderName.replace(/[ .()]/g, '_'); … … 470 470 function resultsDirectoryURL(builderName) 471 471 { 472 return kLayoutTestResultsServer + results DirectoryForBuilder(builderName) + kLayoutTestResultsPath;472 return kLayoutTestResultsServer + results.directoryForBuilder(builderName) + kLayoutTestResultsPath; 473 473 } 474 474 -
trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js
r94539 r94580 29 29 (function(){ 30 30 31 var kResultsPrefetchDelayMS = 500; 32 31 33 // FIXME: Rather than using table, should we be using something fancier? 32 34 ui.results.Comparison = base.extends('table', { … … 138 140 139 141 ui.results.ResultsDetails = base.extends('div', { 140 init: function(delegate )142 init: function(delegate, failureInfo) 141 143 { 142 144 this.className = 'results-detail'; 143 145 this._delegate = delegate; 144 }, 145 show: function(failureInfo) { 146 this._delegate.fetchResultsURLs(failureInfo, function(resultsURLs) { 146 this._failureInfo = failureInfo; 147 this._haveShownOnce = false; 148 }, 149 show: function() { 150 if (this._haveShownOnce) 151 return; 152 this._haveShownOnce = true; 153 this._delegate.fetchResultsURLs(this._failureInfo, function(resultsURLs) { 147 154 var resultsGrid = new ui.results.ResultsGrid(); 148 155 resultsGrid.addResults(resultsURLs); … … 152 159 }); 153 160 154 var Selector = base.extends('select', { 155 init: function() 156 { 157 this._eventName = null; 158 $(this).change(function() { 159 if (this._eventName) 160 $(this).trigger(this._eventName); 161 }.bind(this)); 162 }, 163 setItemList: function(itemList) 164 { 165 $(this).empty(); 166 itemList.forEach(function(item) { 167 var element = document.createElement('option'); 168 element.textContent = item.displayName; 169 element.value = item.name; 170 this.appendChild(element); 171 }.bind(this)); 172 $(this).show(); 173 }, 174 select: function(itemName) { 175 var index = -1; 176 for (var i = 0; i < this.options.length; ++i) { 177 if (this.options[i].value == itemName) { 178 index = i; 179 break; 180 } 181 } 182 if (index == -1) 183 return; 184 this.selectedIndex = index; 185 }, 186 selectedItem: function() { 187 if (this.selectedIndex == -1) 188 return; 189 return this.options[this.selectedIndex].value; 190 } 191 }); 192 193 ui.results.TestSelector = base.extends(Selector, { 194 init: function() 161 ui.results.TestSelector = base.extends('div', { 162 init: function(delegate, resultsByTest) 195 163 { 196 164 this.className = 'test-selector'; 197 this._eventName = 'testselected'; 198 }, 199 setTestList: function(testNameList) 200 { 201 this.setItemList(testNameList.map(function(testName) { 202 return { 203 'displayName': testName, 204 'name': testName 205 }; 206 })); 207 } 208 }); 209 210 ui.results.BuilderSelector = base.extends(Selector, { 211 init: function() 165 this._delegate = delegate; 166 167 Object.keys(resultsByTest).forEach(function (testName) { 168 var link = document.createElement('a'); 169 $(link).attr('href', '#').text(testName); 170 this.appendChild(document.createElement('h3')).appendChild(link); 171 this.appendChild(this._delegate.contentForTest(testName)); 172 }, this); 173 174 $(this).accordion({ 175 collapsible: true, 176 autoHeight: false, 177 }); 178 $(this).accordion("activate", false); 179 } 180 }); 181 182 ui.results.BuilderSelector = base.extends('div', { 183 init: function(delegate, testName, resultsByBuilder) 212 184 { 213 185 this.className = 'builder-selector'; 214 this._eventName = 'builderselected'; 215 }, 216 setBuilderList: function(builderNameList) { 217 this.setItemList(builderNameList.map(function(builderName) { 218 return { 219 'displayName': ui.displayNameForBuilder(builderName), 220 'name': builderName 221 }; 222 })); 223 } 224 }); 225 226 ui.results.ResultsSelector = base.extends('table', { 227 init: function() 228 { 229 this.className = 'results-selector'; 230 }, 231 setResultsByTest: function(resultsByTest) 232 { 233 var buildersByTest = base.mapDictionary(resultsByTest, Object.keys); 234 235 var testNameList = Object.keys(buildersByTest); 236 var builderNameList = base.uniquifyArray(base.flattenArray(base.values(buildersByTest))); 237 builderNameList.sort(); 238 239 var titles = this.createTHead().insertRow(); 240 // Note the reverse iteration because insertCell() inserts at the beginning of the row. 241 for (var i = builderNameList.length - 1; i >= 0; --i) { 242 titles.insertCell().textContent = builderNameList[i]; 243 } 244 titles.insertCell(); // For the test names. 245 246 this._body = this.appendChild(document.createElement('tbody')); 247 248 testNameList.forEach(function(testName) { 249 var row = this._body.insertRow(); 250 for (var i = builderNameList.length - 1; i >= 0; --i) { 251 var cell = row.insertCell(); 252 var builderName = builderNameList[i]; 253 if (buildersByTest[testName].indexOf(builderName) != -1) { 254 cell.className = 'result'; 255 cell.textContent = resultsByTest[testName][builderName].actual; 256 } 257 } 258 var cell = row.insertCell() 259 cell.className = 'test-name'; 260 cell.textContent = testName; 261 }.bind(this)); 262 }, 186 this._delegate = delegate; 187 188 var tabStrip = this.appendChild(document.createElement('ul')); 189 190 Object.keys(resultsByBuilder).forEach(function(builderName) { 191 var builderDirectory = results.directoryForBuilder(builderName); 192 193 var link = document.createElement('a'); 194 $(link).attr('href', "#" + builderDirectory).text(ui.displayNameForBuilder(builderName)); 195 tabStrip.appendChild(document.createElement('li')).appendChild(link); 196 197 var content = this._delegate.contentForTestAndBuilder(testName, builderName); 198 content.id = builderDirectory; 199 this.appendChild(content); 200 }, this); 201 202 $(this).tabs(); 203 } 263 204 }); 264 205 … … 267 208 { 268 209 this.className = 'results-view'; 269 this.innerHTML = '<div class="toolbar"></div><div class="content"></div>'; 270 271 this._testSelector = new ui.results.TestSelector(); 272 this._builderSelector = new ui.results.BuilderSelector(); 273 this._resultsSelector = new ui.results.ResultsSelector(); 274 this._resultsDetails = new ui.results.ResultsDetails(delegate); 275 this._actionList = new ui.actions.List(); 276 277 $('.toolbar', this).append(this._testSelector).append(this._builderSelector).append(this._resultsSelector).append(this._actionList); 278 $('.content', this).append(this._resultsDetails); 279 }, 280 addAction: function(action) 281 { 282 this._actionList.add(action); 283 }, 284 setTestList: function(testNameList) 285 { 286 this._testSelector.setTestList(testNameList); 287 }, 288 setBuilderList: function(buildNameList) 289 { 290 this._builderSelector.setBuilderList(buildNameList); 210 this._delegate = delegate; 211 }, 212 contentForTest: function(testName) 213 { 214 var builderSelector = new ui.results.BuilderSelector(this, testName, this._resultsByTest[testName]); 215 $(builderSelector).bind('tabsselect', function(event, ui) { 216 // We will probably have pre-fetched the tab already, but we need to make sure. 217 ui.panel.show(); 218 }); 219 return builderSelector; 220 }, 221 contentForTestAndBuilder: function(testName, builderName) 222 { 223 var failureInfo = results.failureInfoForTestAndBuilder(this._resultsByTest, testName, builderName); 224 return new ui.results.ResultsDetails(this, failureInfo); 291 225 }, 292 226 setResultsByTest: function(resultsByTest) 293 227 { 294 this._resultsSelector.setResultsByTest(resultsByTest); 295 }, 296 currentTestName: function() 297 { 298 return this._testSelector.selectedItem(); 299 }, 300 currentBuilderName: function() 301 { 302 return this._builderSelector.selectedItem(); 303 }, 304 showResults: function(failureInfo) 305 { 306 this._testSelector.select(failureInfo.testName); 307 this._builderSelector.select(failureInfo.builderName); 308 this._resultsDetails.show(failureInfo); 228 $(this).empty(); 229 this._resultsByTest = resultsByTest; 230 231 var testSelector = new ui.results.TestSelector(this, resultsByTest); 232 $(testSelector).bind("accordionchangestart", function(event, ui) { 233 // Prefetch the first results from the network. 234 var resultsDetails = $('.results-detail', ui.newContent); 235 if (resultsDetails.length) 236 resultsDetails[0].show(); 237 // Prefetch the rest kResultsPrefetchDelayMS later. 238 setTimeout(function() { 239 resultsDetails.each(function() { 240 this.show(); 241 }); 242 }, kResultsPrefetchDelayMS); 243 }); 244 this.appendChild(testSelector); 245 }, 246 fetchResultsURLs: function(failureInfo, callback) 247 { 248 this._delegate.fetchResultsURLs(failureInfo, callback) 309 249 } 310 250 }); -
trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js
r94487 r94580 47 47 } 48 48 49 test("View", 6, function() { 50 var resultsView = new ui.results.View({ 51 fetchResultsURLs: $.noop 52 }); 53 var controller = new controllers.ResultsDetails(resultsView, kExampleResultsByTest); 54 controller.showTest("scrollbars/custom-scrollbar-with-incomplete-style.html"); 55 equal(resultsView.currentTestName(), "scrollbars/custom-scrollbar-with-incomplete-style.html"); 56 equal(resultsView.currentBuilderName(), "Mock Builder"); 57 resultsView.showResults({ 58 "testName": "userscripts/another-test.html", 59 "builderName": "Mock Builder", 60 }); 61 equal(resultsView.currentTestName(), "userscripts/another-test.html"); 62 equal(resultsView.currentBuilderName(), "Mock Builder"); 63 resultsView.showResults({ 64 "testName": "scrollbars/custom-scrollbar-with-incomplete-style.html", 65 "builderName": "Mock Linux", 66 }); 67 equal(resultsView.currentTestName(), "scrollbars/custom-scrollbar-with-incomplete-style.html"); 68 equal(resultsView.currentBuilderName(), "Mock Linux"); 69 }); 70 71 test("ResultsSelector", 1, function() { 72 var resultsSelector = new ui.results.ResultsSelector(); 73 resultsSelector.setResultsByTest(kExampleResultsByTest); 74 equal($(resultsSelector).wrap('<div>').parent().html(), 75 '<table class="results-selector">' + 76 '<thead>' + 77 '<tr><td></td><td>Mock Builder</td><td>Mock Linux</td></tr>' + 78 '</thead>' + 79 '<tbody>' + 80 '<tr>' + 81 '<td class="test-name">userscripts/another-test.html</td>' + 82 '<td class="result">TEXT</td>' + 83 '<td></td>' + 84 '</tr>' + 85 '<tr>' + 86 '<td class="test-name">scrollbars/custom-scrollbar-with-incomplete-style.html</td>' + 87 '<td class="result">CRASH</td>' + 88 '<td class="result">CRASH</td>' + 89 '</tr>' + 90 '</tbody>' + 91 '</table>'); 92 }); 93 49 // FIXME: Add some unit tests. 94 50 95 51 })(); -
trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css
r94200 r94580 24 24 */ 25 25 26 .results-view table { 26 .results-view>.toolbar { 27 padding-bottom: 15px; 28 } 29 30 .results-view>.toolbar ul.actions { 31 float: right; 32 margin: 0; 33 padding: 0; 34 list-style: none; 35 display: inline-block; 36 } 37 38 .results-view>.toolbar ul.actions li { 39 display: inline-block; 40 } 41 42 .results-grid table { 27 43 table-layout: fixed; 28 44 width: 100%; … … 30 46 } 31 47 32 .results- viewtable td, .results-view table th {48 .results-grid table td, .results-view table th { 33 49 overflow: hidden; 34 50 vertical-align: top; 35 51 } 36 52 37 .results- viewtable th {53 .results-grid table th { 38 54 padding: 3px; 39 55 border-bottom: 1px solid #AAA; 40 56 } 41 57 42 .results-view .toolbar { 43 padding-bottom: 15px; 44 } 45 46 .results-view .test-selector { 47 width: 400px; 48 margin-right: 6px; 49 } 50 51 .results-view .actions { 52 float: right; 53 } 54 55 .results-view .toolbar ul.actions { 56 margin: 0; 57 padding: 0; 58 list-style: none; 59 display: inline-block; 60 } 61 62 .results-view .toolbar ul.actions li { 63 display: inline-block; 64 } 65 66 .results-view .text-result { 58 .results-grid .text-result { 67 59 border: none; 68 60 width: 100%; … … 70 62 } 71 63 72 .results- view.image-result {64 .results-grid .image-result { 73 65 width: 100%; 74 66 height: auto; -
trunk/Tools/ChangeLog
r94579 r94580 1 2011-09-06 Adam Barth <abarth@webkit.org> 2 3 Use a hierarchial structure for the garden-o-matic results view 4 https://bugs.webkit.org/show_bug.cgi?id=67620 5 6 Reviewed by Dimitri Glazkov. 7 8 This patch re-organizes the results view to use a hierachial structure 9 for selection. At the top-level are sections for each test. Expanding 10 the test section shows a tab selector for builders. 11 12 This structure prepares us for wiring up various actions to this view. 13 14 * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/controllers.js: 15 (.): 16 * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/results.js: 17 (): 18 * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js: 19 (.): 20 * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js: 21 * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css: 22 (.results-view>.toolbar): 23 (.results-view>.toolbar ul.actions): 24 (.results-view>.toolbar ul.actions li): 25 (.results-grid table): 26 (.results-grid table td, .results-view table th): 27 (.results-grid table th): 28 (.results-grid .text-result): 29 (.results-grid .image-result): 30 1 31 2011-09-06 Adam Barth <abarth@webkit.org> 2 32
Note: See TracChangeset
for help on using the changeset viewer.