Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / base / unittest / html_test_results.html
1 <!DOCTYPE html>
2 <!--
3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7 <link rel="import" href="/base/events.html">
8 <link rel="import" href="/base/utils.html">
9 <link rel="import" href="/base/unittest/constants.html">
10 <link rel="import" href="/base/ui.html">
11 <link rel="stylesheet" href="/base/unittest/common.css">
12 <style>
13   x-tv.unittest-test-resultsbase
14     display: -webkit-flex;
15     -webkit-flex-direction: column;
16   }
17
18   x-tv.unittest-test-results > x-html-test-case-result.dark {
19     background-color: #eee;
20   }
21
22   x-html-test-case-result {
23     display: block;
24   }
25   x-html-test-case-result > #title,
26   x-html-test-case-result > #status,
27   x-html-test-case-result > #details > x-html-test-case-error > #message,
28   x-html-test-case-result > #details > x-html-test-case-error > #stack,
29   x-html-test-case-result > #details > x-html-test-case-error > #return-value {
30     -webkit-user-select: auto;
31   }
32
33   x-html-test-case-result > #details > x-html-test-case-error {
34     display: block;
35     border: 1px solid grey;
36     border-radius: 5px;
37     font-family: monospace;
38     margin-bottom: 14px;
39   }
40
41   x-html-test-case-result > #details > x-html-test-case-error > #message,
42   x-html-test-case-result > #details > x-html-test-case-error > #stack {
43     white-space: pre;
44   }
45
46   x-html-test-case-result > #details > x-html-test-case-html-result {
47     display: block;
48   }
49
50 </style>
51 <template id="x-html-test-case-result-template">
52   <span id="title"></span> <span id="status"></span> <span id="return-value"></span>
53   <div id="details"></div>
54 </template>
55
56 <template id="x-html-test-case-error-template">
57   <div id="stack"></div>
58 </template>
59
60 <script>
61 'use strict';
62 tv.exportTo('tv.unittest', function() {
63   var THIS_DOC = document.currentScript.ownerDocument;
64
65   var TestStatus = tv.unittest.TestStatus;
66   var TestTypes = tv.unittest.TestTypes;
67
68   /**
69    * @constructor
70    */
71   var HTMLTestCaseResult = tv.ui.define('x-html-test-case-result');
72
73   HTMLTestCaseResult.prototype = {
74     __proto__: HTMLUnknownElement.prototype,
75
76     decorate: function() {
77       this.appendChild(tv.instantiateTemplate(
78           '#x-html-test-case-result-template', THIS_DOC));
79       this.testCase_ = undefined;
80       this.testCaseHRef_ = undefined;
81       this.duration_ = undefined;
82       this.testStatus_ = TestStatus.PENDING;
83       this.testReturnValue_ = undefined;
84       this.showHTMLOutput_ = false;
85       this.updateColorAndStatus_();
86     },
87
88     get showHTMLOutput() {
89       return this.showHTMLOutput_;
90     },
91
92     set showHTMLOutput(showHTMLOutput) {
93       this.showHTMLOutput_ = showHTMLOutput;
94       this.updateHTMLOutputDisplayState_();
95     },
96
97     get testCase() {
98       return this.testCase_;
99     },
100
101     set testCase(testCase) {
102       this.testCase_ = testCase;
103       this.updateTitle_();
104     },
105
106     get testCaseHRef() {
107       return this.testCaseHRef_;
108     },
109
110     set testCaseHRef(href) {
111       this.testCaseHRef_ = href;
112       this.updateTitle_();
113     },
114     updateTitle_: function() {
115       var titleEl = this.querySelector('#title');
116       if (this.testCase_ === undefined) {
117         titleEl.textContent = '';
118         return;
119       }
120
121       if (this.testCaseHRef_) {
122         titleEl.innerHTML = '<a href="' + this.testCaseHRef_ + '">' +
123             this.testCase_.fullyQualifiedName + '</a>';
124       } else {
125         titleEl.textContent = this.testCase_.fullyQualifiedName;
126       }
127     },
128
129     addError: function(normalizedException) {
130       var errorEl = document.createElement('x-html-test-case-error');
131       errorEl.appendChild(tv.instantiateTemplate(
132           '#x-html-test-case-error-template', THIS_DOC));
133       errorEl.querySelector('#stack').textContent = normalizedException.stack;
134       this.querySelector('#details').appendChild(errorEl);
135       this.updateColorAndStatus_();
136     },
137
138     addHTMLOutput: function(element) {
139       var htmlResultEl = document.createElement('x-html-test-case-html-result');
140       htmlResultEl.appendChild(element);
141       this.querySelector('#details').appendChild(htmlResultEl);
142     },
143
144     updateHTMLOutputDisplayState_: function() {
145       var htmlResults = this.querySelectorAll('x-html-test-case-html-result');
146       var display;
147       if (this.showHTMLOutput)
148         display = '';
149       else
150         display = (this.testStatus_ == TestStatus.RUNNING) ? '' : 'none';
151       for (var i = 0; i < htmlResults.length; i++)
152         htmlResults[i].style.display = display;
153     },
154
155     get hadErrors() {
156       return !!this.querySelector('x-html-test-case-error');
157     },
158
159     get duration() {
160       return this.duration_;
161     },
162
163     set duration(duration) {
164       this.duration_ = duration;
165       this.updateColorAndStatus_();
166     },
167
168     get testStatus() {
169       return this.testStatus_;
170     },
171
172     set testStatus(testStatus) {
173       this.testStatus_ = testStatus;
174       this.updateColorAndStatus_();
175       this.updateHTMLOutputDisplayState_();
176     },
177
178     updateColorAndStatus_: function() {
179       var colorCls;
180       var status;
181       if (this.hadErrors) {
182         colorCls = 'unittest-failed';
183         status = 'failed';
184       } else if (this.testStatus_ == TestStatus.PENDING) {
185         colorCls = 'unittest-pending';
186         status = 'pending';
187       } else if (this.testStatus_ == TestStatus.RUNNING) {
188         colorCls = 'unittest-running';
189         status = 'running';
190       } else { // DONE_RUNNING and no errors
191         colorCls = 'unittest-passed';
192         status = 'passed';
193       }
194
195       var statusEl = this.querySelector('#status');
196       if (this.duration_)
197         statusEl.textContent = status + ' (' +
198             this.duration_.toFixed(2) + 'ms)';
199       else
200         statusEl.textContent = status;
201       statusEl.className = colorCls;
202     },
203
204     get testReturnValue() {
205       return this.testReturnValue_;
206     },
207
208     set testReturnValue(testReturnValue) {
209       this.testReturnValue_ = testReturnValue;
210       this.querySelector('#return-value').textContent = testReturnValue;
211     }
212   };
213
214
215
216
217   /**
218    * @constructor
219    */
220   var HTMLTestResults = tv.ui.define('x-tv.unittest-test-results');
221
222   HTMLTestResults.prototype = {
223     __proto__: HTMLUnknownElement.prototype,
224
225     decorate: function() {
226       this.currentTestCaseStartTime_ = undefined;
227       this.totalRunTime_ = 0;
228       this.numTestsThatPassed_ = 0;
229       this.numTestsThatFailed_ = 0;
230       this.showHTMLOutput_ = false;
231       this.showPendingAndPassedTests_ = false;
232       this.linkifyCallback_ = undefined;
233     },
234
235     getHRefForTestCase: function(testCase) {
236       /* Override this to create custom links */
237       return undefined;
238     },
239
240     get showHTMLOutput() {
241       return this.showHTMLOutput_;
242     },
243
244     set showHTMLOutput(showHTMLOutput) {
245       this.showHTMLOutput_ = showHTMLOutput;
246       var testCaseResults = this.querySelectorAll('x-html-test-case-result');
247       for (var i = 0; i < testCaseResults.length; i++)
248         testCaseResults[i].showHTMLOutput = showHTMLOutput;
249     },
250
251     get showPendingAndPassedTests() {
252       return this.showPendingAndPassedTests_;
253     },
254
255     set showPendingAndPassedTests(showPendingAndPassedTests) {
256       this.showPendingAndPassedTests_ = showPendingAndPassedTests;
257
258       var testCaseResults = this.querySelectorAll('x-html-test-case-result');
259       for (var i = 0; i < testCaseResults.length; i++)
260         this.updateDisplayStateForResult_(testCaseResults[i]);
261     },
262
263     updateDisplayStateForResult_: function(res) {
264       var display;
265       if (this.showPendingAndPassedTests_) {
266         if (res.testStatus == TestStatus.RUNNING ||
267             res.hadErrors) {
268           display = '';
269         } else {
270           display = 'none';
271         }
272       } else {
273         display = '';
274       }
275       res.style.display = display;
276
277       // This bit of mess gives res objects a dark class based on whether their
278       // last visible sibling was not dark. It relies on the
279       // updateDisplayStateForResult_ being called on all previous siblings of
280       // an element before being called on the element itself. Yay induction.
281       var dark;
282       if (!res.previousSibling) {
283         dark = true;
284       } else {
285         var lastVisible;
286         for (var cur = res.previousSibling;
287              cur;
288              cur = cur.previousSibling) {
289           if (cur.style.display == '') {
290             lastVisible = cur;
291             break;
292           }
293         }
294         if (lastVisible) {
295           dark = !lastVisible.classList.contains('dark');
296         } else {
297           dark = true;
298         }
299       }
300
301       if (dark)
302         res.classList.add('dark');
303       else
304         res.classList.remove('dark');
305     },
306
307     willRunTest: function(testCase) {
308       this.currentTestCaseResult_ = new HTMLTestCaseResult();
309       this.currentTestCaseResult_.showHTMLOutput = this.showHTMLOutput_;
310       this.currentTestCaseResult_.testCase = testCase;
311       var href = this.getHRefForTestCase(testCase);
312       if (href)
313         this.currentTestCaseResult_.testCaseHRef = href;
314       this.currentTestCaseResult_.testStatus = TestStatus.RUNNING;
315       this.currentTestCaseStartTime_ = window.performance.now();
316       this.appendChild(this.currentTestCaseResult_);
317       this.updateDisplayStateForResult_(this.currentTestCaseResult_);
318       this.log_(testCase.fullyQualifiedName + ': ');
319     },
320
321     addErrorForCurrentTest: function(error) {
322       this.log_('\n');
323
324       var normalizedException = tv.normalizeException(error);
325       this.log_('Exception: ' + normalizedException.message + '\n' +
326           normalizedException.stack);
327
328       this.currentTestCaseResult_.addError(normalizedException);
329       this.updateDisplayStateForResult_(this.currentTestCaseResult_);
330     },
331
332     addHTMLOutputForCurrentTest: function(element) {
333       this.currentTestCaseResult_.addHTMLOutput(element);
334       this.updateDisplayStateForResult_(this.currentTestCaseResult_);
335     },
336
337     setReturnValueFromCurrentTest: function(returnValue) {
338       this.currentTestCaseResult_.testReturnValue = returnValue;
339     },
340
341     didCurrentTestEnd: function() {
342       var testCaseResult = this.currentTestCaseResult_;
343       var testCaseDuration = window.performance.now() -
344           this.currentTestCaseStartTime_;
345       this.currentTestCaseResult_.testStatus = TestStatus.DONE_RUNNING;
346       testCaseResult.duration = testCaseDuration;
347       this.totalRunTime_ += testCaseDuration;
348       if (testCaseResult.hadErrors) {
349         this.log_('[FAILED]\n');
350         this.numTestsThatFailed_ += 1;
351         tv.dispatchSimpleEvent(this, 'testfailed');
352       } else {
353         this.log_('[PASSED]\n');
354         this.numTestsThatPassed_ += 1;
355         tv.dispatchSimpleEvent(this, 'testpassed');
356       }
357
358       this.updateDisplayStateForResult_(this.currentTestCaseResult_);
359       this.currentTestCaseResult_ = undefined;
360     },
361
362     didRunTests: function() {
363       this.log_('[DONE]\n');
364     },
365
366     getStats: function() {
367       return {
368         numTestsThatPassed: this.numTestsThatPassed_,
369         numTestsThatFailed: this.numTestsThatFailed_,
370         totalRunTime: this.totalRunTime_
371       };
372     },
373
374     log_: function(msg) {
375       //this.textContent += msg;
376       tv.dispatchSimpleEvent(this, 'statschange');
377     }
378   };
379
380   return {
381     HTMLTestResults: HTMLTestResults
382   };
383 });
384 </script>