Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: Tools/GardeningServer/scripts/ui/results.js

Issue 405843002: Delete garden-o-matic. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: update run_unittests.html Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 var ui = ui || {};
27 ui.results = ui.results || {};
28
29 (function(){
30
31 var kResultsPrefetchDelayMS = 500;
32
33 ui.results.ResultsGrid = base.extends('div', {
34 init: function()
35 {
36 this.className = 'results-grid';
37 },
38 addResults: function(resultsURLs)
39 {
40 var resultsURLsByTypeAndKind = {};
41 resultsURLs.forEach(function(url) {
42 var resultType = results.resultType(url);
43 if (!resultsURLsByTypeAndKind[resultType])
44 resultsURLsByTypeAndKind[resultType] = {};
45 resultsURLsByTypeAndKind[resultType][results.resultKind(url)] = url;
46 });
47
48 Object.keys(resultsURLsByTypeAndKind, function(resultType, resultsURLsBy Kind) {
49 if (results.kUnknownKind in resultsURLsByKind) {
50 // This is something like "crash" that isn't a comparison.
51 var result = document.createElement('ct-test-output');
52 result.url = resultsURLsByKind[results.kUnknownKind];
53 result.type = results.kTextType;
54 this.appendChild(result);
55 return;
56 }
57
58 var comparison = document.createElement('ct-results-comparison');
59 comparison.type = resultType;
60
61 if (results.kActualKind in resultsURLsByKind)
62 comparison.actualUrl = resultsURLsByKind[results.kActualKind];
63 if (results.kExpectedKind in resultsURLsByKind)
64 comparison.expectedUrl = resultsURLsByKind[results.kExpectedKind ];
65 if (results.kDiffKind in resultsURLsByKind)
66 comparison.diffUrl = resultsURLsByKind[results.kDiffKind];
67
68 this.appendChild(comparison);
69 }.bind(this));
70
71 if (!this.children.length)
72 this.textContent = 'No results to display.'
73 }
74 });
75
76 ui.results.ResultsDetails = base.extends('div', {
77 init: function(delegate, failureInfo)
78 {
79 this.className = 'results-detail';
80 this._delegate = delegate;
81 this._failureInfo = failureInfo;
82 this._haveShownOnce = false;
83 },
84 show: function() {
85 if (this._haveShownOnce)
86 return;
87 this._haveShownOnce = true;
88 this._delegate.fetchResultsURLs(this._failureInfo).then(function(results URLs) {
89 var resultsGrid = new ui.results.ResultsGrid();
90 resultsGrid.addResults(resultsURLs);
91
92 this.innerHTML = ''
93 this.appendChild(
94 new ui.actions.List([
95 new ui.actions.Previous(),
96 new ui.actions.Next()
97 ]))
98 this.appendChild(resultsGrid);
99 }.bind(this));
100 },
101 });
102
103 ui.results.FlakinessData = base.extends('iframe', {
104 init: function()
105 {
106 this.className = 'flakiness-iframe';
107 this.src = ui.urlForEmbeddedFlakinessDashboard();
108 this.addEventListener('load', function() {
109 window.addEventListener('message', this._handleMessage.bind(this));
110 });
111 },
112 _handleMessage: function(event) {
113 if (!this.contentWindow)
114 return;
115
116 if (event.data.command != 'heightChanged') {
117 return;
118 }
119
120 this.style.height = event.data.height + 'px';
121 }
122 });
123
124 ui.results.TestSelector = base.extends('div', {
125 init: function(delegate, resultsByTest)
126 {
127 this.className = 'test-selector';
128 this._delegate = delegate;
129
130 var topPanel = document.createElement('div');
131 topPanel.className = 'top-panel';
132 this.appendChild(topPanel);
133
134 this._appendResizeHandle();
135
136 var bottomPanel = document.createElement('div');
137 bottomPanel.className = 'bottom-panel';
138 this.appendChild(bottomPanel);
139
140 this._flakinessData = new ui.results.FlakinessData();
141 this.appendChild(this._flakinessData);
142
143 var testNames = Object.keys(resultsByTest);
144 testNames.sort().forEach(function(testName) {
145 var nonLinkTitle = document.createElement('a');
146 nonLinkTitle.classList.add('non-link-title');
147 nonLinkTitle.textContent = testName;
148
149 var linkTitle = document.createElement('a');
150 linkTitle.classList.add('link-title');
151 linkTitle.setAttribute('href', ui.urlForFlakinessDashboard([testName ]));
152 ui.setTargetForLink(linkTitle);
153 linkTitle.textContent = testName;
154
155 var header = document.createElement('h3');
156 header.appendChild(nonLinkTitle);
157 header.appendChild(linkTitle);
158 header.addEventListener('click', this._showResults.bind(this, header , false));
159 topPanel.appendChild(header);
160 }, this);
161
162 // If we have a small amount of content, don't show the resize handler.
163 // Otherwise, set the minHeight so that the percentage height of the
164 // topPanel is not too small.
165 if (testNames.length <= 4)
166 this.removeChild(this.querySelector('.resize-handle'));
167 else
168 topPanel.style.minHeight = '100px';
169 },
170 _appendResizeHandle: function()
171 {
172 var resizeHandle = document.createElement('div');
173 resizeHandle.className = 'resize-handle';
174 this.appendChild(resizeHandle);
175
176 resizeHandle.addEventListener('mousedown', function(event) {
177 this._is_resizing = true;
178 event.preventDefault();
179 }.bind(this));
180
181 var cancelResize = function(event) { this._is_resizing = false; }.bind(t his);
182 this.addEventListener('mouseup', cancelResize);
183 document.body.addEventListener('mouseleave', cancelResize);
184
185 this.addEventListener('mousemove', function(event) {
186 if (!this._is_resizing)
187 return;
188 var mouseY = event.clientY + document.body.scrollTop - this.offsetTo p;
189 var percentage = 100 * mouseY / this.offsetHeight;
190 document.querySelector('.top-panel').style.maxHeight = percentage + '%';
191 }.bind(this))
192 },
193 _showResults: function(header, scrollInfoView)
194 {
195 if (!header)
196 return false;
197
198 var activeHeader = this.querySelector('.active')
199 if (activeHeader)
200 activeHeader.classList.remove('active');
201 header.classList.add('active');
202
203 var testName = this.currentTestName();
204 this._flakinessData.src = ui.urlForEmbeddedFlakinessDashboard([testName] );
205
206 var bottomPanel = this.querySelector('.bottom-panel')
207 bottomPanel.innerHTML = '';
208 bottomPanel.appendChild(this._delegate.contentForTest(testName));
209
210 var topPanel = this.querySelector('.top-panel');
211 if (scrollInfoView) {
212 topPanel.scrollTop = header.offsetTop;
213 if (header.offsetTop - topPanel.scrollTop < header.offsetHeight)
214 topPanel.scrollTop = topPanel.scrollTop - header.offsetHeight;
215 }
216
217 var resultsDetails = this.querySelectorAll('.results-detail');
218 if (resultsDetails.length)
219 resultsDetails[0].show();
220 setTimeout(function() {
221 Array.prototype.forEach.call(resultsDetails, function(resultsDetail) {
222 resultsDetail.show();
223 });
224 }, kResultsPrefetchDelayMS);
225
226 return true;
227 },
228 nextResult: function()
229 {
230 if (this.querySelector('.builder-selector').nextResult())
231 return true;
232 return this.nextTest();
233 },
234 previousResult: function()
235 {
236 if (this.querySelector('.builder-selector').previousResult())
237 return true;
238 return this.previousTest();
239 },
240 nextTest: function()
241 {
242 return this._showResults(this.querySelector('.active').nextSibling, true );
243 },
244 previousTest: function()
245 {
246 var succeeded = this._showResults(this.querySelector('.active').previous Sibling, true);
247 if (succeeded)
248 this.querySelector('.builder-selector').lastResult();
249 return succeeded;
250 },
251 firstResult: function()
252 {
253 this._showResults(this.querySelector('h3'), true);
254 },
255 currentTestName: function()
256 {
257 return this.querySelector('.active .non-link-title').textContent;
258 }
259 });
260
261 ui.results.BuilderSelector = base.extends('div', {
262 init: function(delegate, testName, resultsByBuilder)
263 {
264 this.className = 'builder-selector';
265 this._delegate = delegate;
266
267 var tabStrip = this.appendChild(document.createElement('ul'));
268
269 Object.keys(resultsByBuilder).sort().forEach(function(builderName) {
270 var builderHash = base.underscoredBuilderName(builderName);
271
272 var link = document.createElement('a');
273 link.href = "#" + builderHash;
274 link.textContent = ui.displayNameForBuilder(builderName);
275 tabStrip.appendChild(document.createElement('li')).appendChild(link) ;
276
277 var content = this._delegate.contentForTestAndBuilder(testName, buil derName);
278 content.id = builderHash;
279 this.appendChild(content);
280 }, this);
281
282 $(this).tabs();
283 },
284 nextResult: function()
285 {
286 var nextIndex = $(this).tabs('option', 'selected') + 1;
287 if (nextIndex >= $(this).tabs('length'))
288 return false
289 $(this).tabs('option', 'selected', nextIndex);
290 return true;
291 },
292 previousResult: function()
293 {
294 var previousIndex = $(this).tabs('option', 'selected') - 1;
295 if (previousIndex < 0)
296 return false;
297 $(this).tabs('option', 'selected', previousIndex);
298 return true;
299 },
300 firstResult: function()
301 {
302 $(this).tabs('option', 'selected', 0);
303 },
304 lastResult: function()
305 {
306 $(this).tabs('option', 'selected', $(this).tabs('length') - 1);
307 }
308 });
309
310 ui.results.View = base.extends('div', {
311 init: function(delegate)
312 {
313 this.className = 'results-view';
314 this._delegate = delegate;
315 },
316 contentForTest: function(testName)
317 {
318 var builderSelector = new ui.results.BuilderSelector(this, testName, thi s._resultsByTest[testName]);
319 $(builderSelector).bind('tabsselect', function(event, ui) {
320 // We will probably have pre-fetched the tab already, but we need to make sure.
321 ui.panel.show();
322 });
323 return builderSelector;
324 },
325 contentForTestAndBuilder: function(testName, builderName)
326 {
327 var failureInfo = results.failureInfoForTestAndBuilder(this._resultsByTe st, testName, builderName);
328 return new ui.results.ResultsDetails(this, failureInfo);
329 },
330 setResultsByTest: function(resultsByTest)
331 {
332 this.innerHTML = '';
333 this._resultsByTest = resultsByTest;
334 this._testSelector = new ui.results.TestSelector(this, resultsByTest);
335 this.appendChild(this._testSelector);
336 },
337 fetchResultsURLs: function(failureInfo)
338 {
339 return this._delegate.fetchResultsURLs(failureInfo);
340 },
341 nextResult: function()
342 {
343 return this._testSelector.nextResult();
344 },
345 previousResult: function()
346 {
347 return this._testSelector.previousResult();
348 },
349 nextTest: function()
350 {
351 return this._testSelector.nextTest();
352 },
353 previousTest: function()
354 {
355 return this._testSelector.previousTest();
356 },
357 firstResult: function()
358 {
359 this._testSelector.firstResult()
360 },
361 currentTestName: function()
362 {
363 return this._testSelector.currentTestName()
364 }
365 });
366
367 })();
OLDNEW
« no previous file with comments | « Tools/GardeningServer/scripts/ui/notifications_unittests.js ('k') | Tools/GardeningServer/scripts/ui/results_unittests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698