Add --verbose to ./test.sh and phantom-driver.js
[dygraphs.git] / phantom-driver.js
1 // Invoke via: ./test.sh
2 //
3 // or phantomjs phantom-driver.js [testCase.test]
4 //
5 // For more on phantomjs, visit www.phantomjs.org.
6
7 var RunAllAutoTests = function(done_callback) {
8
9 var page = require('webpage').create();
10
11 // NOTE: Cannot include '#' or '?' in this URL.
12 var url = 'auto_tests/misc/local.html';
13
14 // NOTE: changing the line below to this:
15 // page.open(url, function(status)) {
16 // makes phantomjs hang.
17 page.open(url, function(status) {
18 if (status !== 'success') {
19 console.warn('Page status: ' + status);
20 console.log(page);
21 phantom.exit();
22 }
23
24 var testCase, test;
25 var verbose = false;
26 var optIdx = 0;
27 if (phantom.args.length > 0 && phantom.args[0] === "--verbose") {
28 verbose = true;
29 optIdx = 1;
30 }
31 if (phantom.args.length == optIdx + 1) {
32 var parts = phantom.args[optIdx].split('.');
33 if (2 != parts.length) {
34 console.warn('Usage: phantomjs phantom-driver.js [--verbose] [testCase.test]');
35 phantom.exit();
36 }
37 testCase = parts[0];
38 test = parts[1];
39 }
40
41 var loggingOn = false;
42 page.onConsoleMessage = function (msg) {
43 if (msg == 'Running ' + test) {
44 loggingOn = true;
45 } else if (msg.substr(0, 'Running'.length) == 'Running') {
46 loggingOn = false;
47 }
48 if (verbose || loggingOn) console.log(msg);
49 };
50
51 page.onError = function (msg, trace) {
52 console.log(msg);
53 trace.forEach(function(item) {
54 console.log(' ', item.file, ':', item.line);
55 })
56 };
57
58 var results;
59
60 // Run all tests.
61 var start = new Date().getTime();
62 results = page.evaluate(function() {
63 // Phantom doesn't like stacktrace.js using the "arguments" object
64 // in stacktrace.js, which it interprets in strict mode.
65 printStackTrace = undefined;
66
67 var testCases = getAllTestCases();
68 var results = {};
69 for (var idx in testCases) {
70 var entry = testCases[idx];
71
72 var prototype = entry.testCase;
73 var tc = new entry.testCase();
74 var result = tc.runAllTests();
75 results[entry.name] = result;
76 }
77 return results;
78 });
79 var end = new Date().getTime();
80 var elapsed = (end - start) / 1000;
81
82 var num_passing = 0, num_failing = 0;
83 var failures = [];
84 for (var testCase in results) {
85 var caseResults = results[testCase];
86 for (var test in caseResults) {
87 if (caseResults[test] !== true) {
88 num_failing++;
89 failures.push(testCase + '.' + test);
90 } else {
91 // console.log(testCase + '.' + test + ' passed');
92 num_passing++;
93 }
94 }
95 }
96
97 console.log('Ran ' + (num_passing + num_failing) + ' tests in ' + elapsed + 's.');
98 console.log(num_passing + ' test(s) passed');
99 console.log(num_failing + ' test(s) failed:');
100 for (var i = 0; i < failures.length; i++) {
101 // TODO(danvk): print an auto_test/misc/local URL that runs this test.
102 console.log(' ' + failures[i] + ' failed.');
103 }
104
105 done_callback(num_failing, num_passing);
106 });
107
108 };
109
110 // Load all "tests/" pages.
111 var LoadAllManualTests = function(totally_done_callback) {
112
113 var fs = require('fs');
114 var tests = fs.list('tests');
115 var pages = [];
116
117 function make_barrier_closure(n, fn) {
118 var calls = 0;
119 return function() {
120 calls++;
121 if (calls == n) {
122 fn();
123 } else {
124 // console.log('' + calls + ' done, ' + (n - calls) + ' remain');
125 }
126 };
127 }
128
129 var tasks = [];
130 for (var i = 0; i < tests.length; i++) {
131 if (tests[i].substr(-5) != '.html') continue;
132 tasks.push(tests[i]);
133 }
134 tasks = [ 'independent-series.html' ];
135
136 var loaded_page = make_barrier_closure(tasks.length, function() {
137 // Wait 2 secs to allow JS errors to happen after page load.
138 setTimeout(function() {
139 var success = 0, failures = 0;
140 for (var i = 0; i < pages.length; i++) {
141 if (pages[i].success && !pages[i].hasErrors) {
142 success++;
143 } else {
144 failures++;
145 }
146 }
147 console.log('Successfully loaded ' + success + ' / ' +
148 (success + failures) + ' test pages.');
149 totally_done_callback(failures, success);
150 }, 2000);
151 });
152
153
154 for (var i = 0; i < tasks.length; i++) {
155 var url = 'file://' + fs.absolute('tests/' + tasks[i]);
156 pages.push(function(path, url) {
157 var page = require('webpage').create();
158 page.success = false;
159 page.hasErrors = false;
160 page.onError = function (msg, trace) {
161 console.log(path + ': ' + msg);
162 page.hasErrors = true;
163 trace.forEach(function(item) {
164 console.log(' ', item.file, ':', item.line);
165 });
166 };
167 page.onLoadFinished = function(status) {
168 if (status == 'success') {
169 page.success = true;
170 }
171 if (!page.done) loaded_page();
172 page.done = true;
173 };
174 page.open(url);
175 return page;
176 }(tasks[i], url));
177 }
178
179 };
180
181
182 // First run all auto_tests.
183 // If they all pass, load the manual tests.
184 RunAllAutoTests(function(num_failing, num_passing) {
185 if (num_failing !== 0) {
186 console.log('FAIL');
187 phantom.exit();
188 } else {
189 console.log('PASS');
190 }
191 phantom.exit();
192
193 // This is not yet reliable enough to be useful:
194 /*
195 LoadAllManualTests(function(failing, passing) {
196 if (failing !== 0) {
197 console.log('FAIL');
198 } else {
199 console.log('PASS');
200 }
201 phantom.exit();
202 });
203 */
204 });