1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 tvcm.require('tvcm.unittest');
7 tvcm.require('tvcm.unittest.suite_loader');
8 tvcm.require('tvcm.unittest.test_runner');
9 tvcm.require('tvcm.unittest.html_test_results');
11 tvcm.requireStylesheet('tvcm.unittest.common');
12 tvcm.requireTemplate('tvcm.unittest.interactive_test_runner');
14 tvcm.exportTo('tvcm.unittest', function() {
18 var InteractiveTestRunner = tvcm.ui.define('x-base-interactive-test-runner');
20 InteractiveTestRunner.prototype = {
21 __proto__: HTMLUnknownElement.prototype,
23 decorate: function() {
24 this.allTests_ = undefined;
26 this.suppressStateChange_ = false;
28 this.testFilterString_ = '';
29 this.testTypeToRun_ = tvcm.unittest.TestTypes.UNITTEST;
30 this.shortFormat_ = false;
31 this.testSuiteName_ = '';
33 this.rerunPending_ = false;
34 this.runner_ = undefined;
35 this.results_ = undefined;
37 this.onResultsStatsChanged_ = this.onResultsStatsChanged_.bind(this);
38 this.onTestFailed_ = this.onTestFailed_.bind(this);
39 this.onTestPassed_ = this.onTestPassed_.bind(this);
42 this.appendChild(tvcm.instantiateTemplate(
43 '#x-base-interactive-test-runner-template'));
46 'input[name=test-type-to-run][value=unit]').checked = true;
47 var testTypeToRunEls = tvcm.asArray(this.querySelectorAll(
48 'input[name=test-type-to-run]'));
50 testTypeToRunEls.forEach(
52 inputEl.addEventListener(
53 'click', this.onTestTypeToRunClick_.bind(this));
56 var shortFormatEl = this.querySelector('#short-format');
57 shortFormatEl.checked = this.shortFormat_;
58 shortFormatEl.addEventListener(
59 'click', this.onShortFormatClick_.bind(this));
60 this.updateShortFormResultsDisplay_();
62 // Oh, DOM, how I love you. Title is such a convenient property name and I
63 // refuse to change my worldview because of tooltips.
64 this.__defineSetter__(
67 this.querySelector('#title').textContent = title;
72 return this.allTests_;
75 set allTests(allTests) {
76 this.allTests_ = allTests;
77 this.scheduleRerun_();
81 return this.testLinks_;
83 set testLinks(testLinks) {
84 this.testLinks_ = testLinks;
85 var linksEl = this.querySelector('#links');
86 linksEl.textContent = '';
87 this.testLinks_.forEach(function(l) {
88 var link = document.createElement('a');
89 link.href = l.linkPath;
90 link.textContent = l.title;
91 linksEl.appendChild(link);
95 get testFilterString() {
96 return this.testFilterString_;
99 set testFilterString(testFilterString) {
100 this.testFilterString_ = testFilterString;
101 this.scheduleRerun_();
102 if (!this.suppressStateChange_)
103 tvcm.dispatchSimpleEvent(this, 'statechange');
107 return this.shortFormat_;
110 set shortFormat(shortFormat) {
111 this.shortFormat_ = shortFormat;
112 this.querySelector('#short-format').checked = shortFormat;
114 this.results_.shortFormat = shortFormat;
115 if (!this.suppressStateChange_)
116 tvcm.dispatchSimpleEvent(this, 'statechange');
119 onShortFormatClick_: function(e) {
120 this.shortFormat_ = this.querySelector('#short-format').checked;
121 this.updateShortFormResultsDisplay_();
122 this.updateResultsGivenShortFormat_();
123 if (!this.suppressStateChange_)
124 tvcm.dispatchSimpleEvent(this, 'statechange');
127 updateShortFormResultsDisplay_: function() {
128 var display = this.shortFormat_ ? '' : 'none';
129 this.querySelector('#shortform-results').style.display = display;
132 updateResultsGivenShortFormat_: function() {
136 if (this.testFilterString_.length || this.testSuiteName_.length)
137 this.results_.showHTMLOutput = true;
139 this.results_.showHTMLOutput = false;
140 this.results_.showPendingAndPassedTests = this.shortFormat_;
143 get testTypeToRun() {
144 return this.testTypeToRun_;
147 set testTypeToRun(testTypeToRun) {
148 this.testTypeToRun_ = testTypeToRun;
150 if (testTypeToRun == tvcm.unittest.TestTypes.UNITTEST)
151 sel = 'input[name=test-type-to-run][value=unit]';
153 sel = 'input[name=test-type-to-run][value=perf]';
154 this.querySelector(sel).checked = true;
155 this.scheduleRerun_();
156 if (!this.suppressStateChange_)
157 tvcm.dispatchSimpleEvent(this, 'statechange');
160 onTestTypeToRunClick_: function(e) {
161 if (e.target.value == 'unit')
162 this.testTypeToRun_ = tvcm.unittest.TestTypes.UNITTEST;
163 else // e.value == 'perf'
164 this.testTypeToRun_ = tvcm.unittest.TestTypes.PERFTEST;
165 this.scheduleRerun_();
166 if (!this.suppressStateChange_)
167 tvcm.dispatchSimpleEvent(this, 'statechange');
170 onTestPassed_: function() {
171 this.querySelector('#shortform-results').textContent += '.';
174 onTestFailed_: function() {
175 this.querySelector('#shortform-results').textContent += 'F';
178 onResultsStatsChanged_: function() {
179 var statsEl = this.querySelector('#stats');
180 var stats = this.results_.getStats();
181 var numTestsOverall = this.runner_.testCases.length;
182 var numTestsThatRan = stats.numTestsThatPassed + stats.numTestsThatFailed;
184 '<span>' + numTestsThatRan + '/' + numTestsOverall +
185 '</span> tests run, ' +
186 '<span class="unittest-failed">' + stats.numTestsThatFailed +
187 '</span> failures, ' +
188 ' in ' + stats.totalRunTime.toFixed(2) + 'ms.';
191 scheduleRerun_: function() {
192 if (this.rerunPending_)
195 this.rerunPending_ = true;
196 this.runner_.beginToStopRunning();
197 var doRerun = function() {
198 this.rerunPending_ = false;
199 this.scheduleRerun_();
201 this.runner_.runCompletedPromise.then(
205 this.beginRunning_();
208 beginRunning_: function() {
209 var resultsContainer = this.querySelector('#results-container');
211 this.results_.removeEventListener('testpassed',
213 this.results_.removeEventListener('testfailed',
215 this.results_.removeEventListener('statschange',
216 this.onResultsStatsChanged_);
217 delete this.results_.getHRefForTestCase;
218 resultsContainer.removeChild(this.results_);
221 this.results_ = new tvcm.unittest.HTMLTestResults();
222 this.results_.getHRefForTestCase = this.getHRefForTestCase.bind(this);
223 this.updateResultsGivenShortFormat_();
225 this.results_.shortFormat = this.shortFormat_;
226 this.results_.addEventListener('testpassed',
228 this.results_.addEventListener('testfailed',
230 this.results_.addEventListener('statschange',
231 this.onResultsStatsChanged_);
232 resultsContainer.appendChild(this.results_);
234 var tests = this.allTests_.filter(function(test) {
235 var i = test.fullyQualifiedName.indexOf(this.testFilterString_);
238 if (test.testType != this.testTypeToRun_)
243 this.runner_ = new tvcm.unittest.TestRunner(this.results_, tests);
244 this.runner_.beginRunning();
246 this.runner_.runCompletedPromise.then(
247 this.runCompleted_.bind(this),
248 this.runCompleted_.bind(this));
251 setState: function(state, opt_suppressStateChange) {
252 this.suppressStateChange_ = true;
253 if (state.testFilterString !== undefined)
254 this.testFilterString = state.testFilterString;
256 this.testFilterString = '';
258 if (state.shortFormat === undefined)
259 this.shortFormat = false;
261 this.shortFormat = state.shortFormat;
263 if (state.testTypeToRun === undefined)
264 this.testTypeToRun = tvcm.unittest.TestTypes.UNITTEST;
266 this.testTypeToRun = state.testTypeToRun;
268 this.testSuiteName_ = state.testSuiteName || '';
270 if (!opt_suppressStateChange)
271 this.suppressStateChange_ = false;
273 this.onShortFormatClick_();
274 this.scheduleRerun_();
275 this.suppressStateChange_ = false;
278 getDefaultState: function() {
280 testFilterString: '',
283 testTypeToRun: tvcm.unittest.TestTypes.UNITTEST
287 getState: function() {
289 testFilterString: this.testFilterString_,
290 testSuiteName: this.testSuiteName_,
291 shortFormat: this.shortFormat_,
292 testTypeToRun: this.testTypeToRun_
296 getHRefForTestCase: function(testCases) {
300 runCompleted_: function() {
301 this.runner_ = undefined;
302 if (this.results_.getStats().numTestsThatFailed > 0) {
303 this.querySelector('#shortform-results').textContent +=
304 '[THERE WERE FAILURES]';
306 this.querySelector('#shortform-results').textContent += '[DONE]';
312 InteractiveTestRunner: InteractiveTestRunner