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