Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Test controller logic - used by unit test harness to embed tests in | 6 * Test controller logic - used by unit test harness to embed tests in |
| 7 * conent shell. | 7 * conent shell. |
|
ricow1
2013/10/23 11:42:32
conent -> content + this comment is outdated
| |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 // Clear the console before every test run - this is Firebug specific code. | 10 /* |
| 11 if (typeof console == "object" && typeof console.clear == "function") { | 11 * We will collect testing driver specific messages here instead of printing |
| 12 console.clear(); | 12 * them to the DOM. |
| 13 * Every entry will look like this: | |
| 14 * { | |
| 15 * 'type' : 'test_outcome' / 'print' / 'debug' / 'message_received' / 'dom' | |
| 16 * 'value' : 'some content', | |
| 17 * } | |
| 18 */ | |
| 19 var MESSAGES = []; | |
| 20 | |
| 21 function recordMessage(type, value) { | |
| 22 var message = { | |
| 23 type: type, | |
| 24 value: value | |
| 25 }; | |
| 26 MESSAGES.push(message); | |
| 27 if (usingBrowserController()) { | |
| 28 printToConsole(JSON.stringify(message, null, 2)); | |
| 29 } | |
| 13 } | 30 } |
| 14 | 31 |
| 32 function clearConsole() { | |
| 33 // Clear the console before every test run - this is Firebug specific code. | |
| 34 if (typeof console == 'object' && typeof console.clear == 'function') { | |
| 35 console.clear(); | |
| 36 } | |
| 37 } | |
| 38 | |
| 39 function printToConsole(message) { | |
| 40 if (typeof console === 'object') { | |
| 41 console.log(message); | |
| 42 } | |
| 43 if (!usingBrowserController()) { | |
| 44 var pre = document.createElement('pre'); | |
| 45 pre.appendChild(document.createTextNode(String(message))); | |
| 46 document.body.appendChild(pre); | |
| 47 document.body.appendChild(document.createTextNode('\n')); | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 clearConsole(); | |
| 52 | |
| 15 // Some tests may expect and have no way to suppress global errors. | 53 // Some tests may expect and have no way to suppress global errors. |
| 16 var testExpectsGlobalError = false; | 54 var testExpectsGlobalError = false; |
| 17 var testSuppressedGlobalErrors = []; | 55 var testSuppressedGlobalErrors = []; |
| 18 | 56 |
| 19 // Set window onerror to make sure that we catch test harness errors across all | 57 // Set window onerror to make sure that we catch test harness errors across all |
| 20 // browsers. | 58 // browsers. |
| 21 window.onerror = function (message, url, lineNumber) { | 59 window.onerror = function (message, url, lineNumber) { |
| 22 if (testExpectsGlobalError) { | 60 if (testExpectsGlobalError) { |
| 23 testSuppressedGlobalErrors.push({ | 61 testSuppressedGlobalErrors.push({ |
| 24 message: message | 62 message: message |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 if (window != window.parent) { | 95 if (window != window.parent) { |
| 58 // We're running in an iframe. | 96 // We're running in an iframe. |
| 59 return window.parent; | 97 return window.parent; |
| 60 } else if (window.opener) { | 98 } else if (window.opener) { |
| 61 // We were opened by another window. | 99 // We were opened by another window. |
| 62 return window.opener; | 100 return window.opener; |
| 63 } | 101 } |
| 64 return null; | 102 return null; |
| 65 } | 103 } |
| 66 | 104 |
| 105 function usingBrowserController() { | |
|
ricow1
2013/10/23 11:42:32
I am not sure we should special case on the browse
| |
| 106 return getDriverWindow() != null; | |
| 107 } | |
| 108 | |
| 67 function notifyStart() { | 109 function notifyStart() { |
| 68 var driver = getDriverWindow(); | 110 var driver = getDriverWindow(); |
| 69 if (driver) { | 111 if (driver) { |
| 70 driver.postMessage("STARTING", "*"); | 112 driver.postMessage("STARTING", "*"); |
| 71 } | 113 } |
| 72 } | 114 } |
| 73 // We call notifyStart here to notify the encapsulating browser. | 115 // We call notifyStart here to notify the encapsulating browser. |
| 74 notifyStart(); | 116 notifyStart(); |
| 75 | 117 |
| 76 function notifyDone() { | 118 function notifyDone(test_outcome) { |
| 119 recordMessage('debug', 'Test outcome: ' + test_outcome); | |
| 120 // If we are not using the browser controller (i.e. in the none-drt | |
|
ricow1
2013/10/23 11:42:32
again, I think this comment is bound to much to ou
| |
| 121 // configuration), we need to print 'test_outcome' as it is. | |
| 122 if (!usingBrowserController()) { | |
| 123 printToConsole(test_outcome); | |
| 124 } | |
| 125 | |
| 77 if (testRunner) testRunner.notifyDone(); | 126 if (testRunner) testRunner.notifyDone(); |
| 78 | |
| 79 // TODO(ricow): REMOVE, debug info, see issue 13292 | |
| 80 if (!testRunner) { | |
| 81 printMessage('Calling notifyDone()'); | |
| 82 } | |
| 83 // To support in browser launching of tests we post back start and result | 127 // To support in browser launching of tests we post back start and result |
| 84 // messages to the window.opener. | 128 // messages to the window.opener. |
| 85 var driver = getDriverWindow(); | 129 var driver = getDriverWindow(); |
| 86 if (driver) { | 130 if (driver) { |
| 87 driver.postMessage(window.document.body.innerHTML, "*"); | 131 // FIXME: we have to post the dom and all recorded messages |
| 132 var messages = MESSAGES.slice(0); | |
| 133 messages.push({ | |
| 134 type: 'dom', | |
| 135 value: '' + window.document.documentElement.innerHTML | |
| 136 }); | |
| 137 messages.push({ | |
| 138 type: 'test_outcome', | |
| 139 value: test_outcome | |
| 140 }); | |
| 141 | |
| 142 driver.postMessage(JSON.stringify(messages), '*'); | |
| 88 } | 143 } |
| 89 } | 144 } |
| 90 | 145 |
| 91 function processMessage(msg) { | 146 function processMessage(msg) { |
| 92 // TODO(ricow): REMOVE, debug info, see issue 13292 | 147 recordMessage('message_received', '' + msg); |
| 93 if (!testRunner) { | |
| 94 printMessage('processMessage(): ' + msg); | |
| 95 } | |
| 96 if (typeof msg != 'string') return; | 148 if (typeof msg != 'string') return; |
| 97 if (msg == 'unittest-suite-done') { | 149 if (msg == 'unittest-suite-wait-for-done') { |
| 98 notifyDone(); | |
| 99 } else if (msg == 'unittest-suite-wait-for-done') { | |
| 100 waitForDone = true; | 150 waitForDone = true; |
| 101 if (testRunner) { | 151 if (testRunner) { |
| 102 testRunner.startedDartTest = true; | 152 testRunner.startedDartTest = true; |
| 103 } | 153 } |
| 104 } else if (msg == 'dart-calling-main') { | 154 } else if (msg == 'dart-calling-main') { |
| 105 if (testRunner) { | 155 if (testRunner) { |
| 106 testRunner.startedDartTest = true; | 156 testRunner.startedDartTest = true; |
| 107 } | 157 } |
| 108 } else if (msg == 'dart-main-done') { | 158 } else if (msg == 'dart-main-done') { |
| 109 if (!waitForDone) { | 159 if (!waitForDone) { |
| 110 printMessage('PASS'); | 160 notifyDone('PASS'); |
| 111 notifyDone(); | |
| 112 } | 161 } |
| 113 } else if (msg == 'unittest-suite-success') { | 162 } else if (msg == 'unittest-suite-success') { |
| 114 printMessage('PASS'); | 163 notifyDone('PASS'); |
| 115 notifyDone(); | |
| 116 } else if (msg == 'unittest-suite-fail') { | 164 } else if (msg == 'unittest-suite-fail') { |
| 117 showErrorAndExit('Some tests failed.'); | 165 notifyDone('FAIL'); |
| 118 } | 166 } |
| 119 } | 167 } |
| 120 | 168 |
| 121 function onReceive(e) { | 169 function onReceive(e) { |
| 122 processMessage(e.data); | 170 processMessage(e.data); |
| 123 } | 171 } |
| 124 | 172 |
| 125 if (testRunner) { | 173 if (testRunner) { |
| 126 testRunner.dumpAsText(); | 174 testRunner.dumpAsText(); |
| 127 testRunner.waitUntilDone(); | 175 testRunner.waitUntilDone(); |
| 128 } | 176 } |
| 129 window.addEventListener("message", onReceive, false); | 177 window.addEventListener("message", onReceive, false); |
| 130 | 178 |
| 131 function showErrorAndExit(message) { | 179 function showErrorAndExit(message) { |
| 132 if (message) { | 180 if (message) { |
| 133 printMessage('Error: ' + String(message)); | 181 recordMessage('debug', 'Error: ' + String(message)); |
| 134 } | 182 } |
| 135 // dart/tools/testing/run_selenium.py is looking for either PASS or | 183 notifyDone('FAIL'); |
| 136 // FAIL and will continue polling until one of these words show up. | |
| 137 printMessage('FAIL'); | |
| 138 notifyDone(); | |
| 139 } | 184 } |
| 140 | 185 |
| 141 function onLoad(e) { | 186 function onLoad(e) { |
| 142 // needed for dartium compilation errors. | 187 // needed for dartium compilation errors. |
| 143 if (window.compilationError) { | 188 if (window.compilationError) { |
| 144 showErrorAndExit(window.compilationError); | 189 showErrorAndExit(window.compilationError); |
| 145 } | 190 } |
| 146 } | 191 } |
| 147 | 192 |
| 148 window.addEventListener("DOMContentLoaded", onLoad, false); | 193 window.addEventListener("DOMContentLoaded", onLoad, false); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 160 if (document.readyState != "loaded") return; | 205 if (document.readyState != "loaded") return; |
| 161 // If 'startedDartTest' is not set, that means that the test did not have | 206 // If 'startedDartTest' is not set, that means that the test did not have |
| 162 // a chance to load. This will happen when a load error occurs in the VM. | 207 // a chance to load. This will happen when a load error occurs in the VM. |
| 163 // Give the machine time to start up. | 208 // Give the machine time to start up. |
| 164 setTimeout(function() { | 209 setTimeout(function() { |
| 165 // A window.postMessage might have been enqueued after this timeout. | 210 // A window.postMessage might have been enqueued after this timeout. |
| 166 // Just sleep another time to give the browser the time to process the | 211 // Just sleep another time to give the browser the time to process the |
| 167 // posted message. | 212 // posted message. |
| 168 setTimeout(function() { | 213 setTimeout(function() { |
| 169 if (testRunner && !testRunner.startedDartTest) { | 214 if (testRunner && !testRunner.startedDartTest) { |
| 170 notifyDone(); | 215 notifyDone('NOT_STARTED'); |
| 171 } | 216 } |
| 172 }, 0); | 217 }, 0); |
| 173 }, 50); | 218 }, 50); |
| 174 }); | 219 }); |
| 175 | 220 |
| 176 // dart2js will generate code to call this function to handle the Dart | 221 // dart2js will generate code to call this function to handle the Dart |
| 177 // [print] method. | 222 // [print] method. |
| 178 // | 223 // |
| 179 // dartium will invoke this method for [print] calls if the environment variable | 224 // dartium will invoke this method for [print] calls if the environment variable |
| 180 // "DART_FORWARDING_PRINT" was set when launching dartium. | 225 // "DART_FORWARDING_PRINT" was set when launching dartium. |
| 181 // | 226 // |
| 182 // Our tests will be wrapped, so we can detect when [main] is called and when | 227 // Our tests will be wrapped, so we can detect when [main] is called and when |
| 183 // it has ended. | 228 // it has ended. |
| 184 // The wrapping happens either via "dartMainRunner" (for dart2js) or wrapped | 229 // The wrapping happens either via "dartMainRunner" (for dart2js) or wrapped |
| 185 // tests for dartium. | 230 // tests for dartium. |
| 186 // | 231 // |
| 187 // The following messages are handled specially: | 232 // The following messages are handled specially: |
| 188 // dart-calling-main: signals that the dart [main] function will be invoked | 233 // dart-calling-main: signals that the dart [main] function will be invoked |
| 189 // dart-main-done: signals that the dart [main] function has finished | 234 // dart-main-done: signals that the dart [main] function has finished |
| 190 // unittest-suite-wait-for-done: signals the start of an asynchronous test | 235 // unittest-suite-wait-for-done: signals the start of an asynchronous test |
| 191 // unittest-suite-success: signals the end of an asynchrounous test | 236 // unittest-suite-success: signals the end of an asynchrounous test |
| 192 // | 237 // |
| 193 // These messages are used to communicate with the test and will be posted so | 238 // These messages are used to communicate with the test and will be posted so |
| 194 // [processMessage] above can see it. | 239 // [processMessage] above can see it. |
| 195 function dartPrint(msg) { | 240 function dartPrint(message) { |
| 196 if ((msg === 'unittest-suite-success') | 241 recordMessage('print', message); |
| 197 || (msg === 'unittest-suite-done') | 242 if ((message === 'unittest-suite-success') |
| 198 || (msg === 'unittest-suite-wait-for-done') | 243 || (message === 'unittest-suite-wait-for-done') |
| 199 || (msg === 'dart-calling-main') | 244 || (message === 'dart-calling-main') |
| 200 || (msg === 'dart-main-done')) { | 245 || (message === 'dart-main-done')) { |
| 201 window.postMessage(msg, '*'); | 246 window.postMessage(message, '*'); |
| 202 return; | 247 return; |
| 203 } | 248 } |
| 204 printMessage(msg); | |
| 205 } | |
| 206 | |
| 207 // Prints 'msg' to the console (if available) and to the body of the html | |
| 208 // document. | |
| 209 function printMessage(msg) { | |
| 210 if (typeof console === 'object') console.warn(msg); | |
| 211 var pre = document.createElement('pre'); | |
| 212 pre.appendChild(document.createTextNode(String(msg))); | |
| 213 document.body.appendChild(pre); | |
| 214 document.body.appendChild(document.createTextNode('\n')); | |
| 215 } | 249 } |
| 216 | 250 |
| 217 // dart2js will generate code to call this function instead of calling | 251 // dart2js will generate code to call this function instead of calling |
| 218 // Dart [main] directly. The argument is a closure that invokes main. | 252 // Dart [main] directly. The argument is a closure that invokes main. |
| 219 function dartMainRunner(main) { | 253 function dartMainRunner(main) { |
| 220 dartPrint('dart-calling-main'); | 254 dartPrint('dart-calling-main'); |
| 221 try { | 255 try { |
| 222 main(); | 256 main(); |
| 223 } catch (e) { | 257 } catch (e) { |
| 224 dartPrint(e); | 258 showErrorAndExit('Exception: ' + e + '\nStack: ' + e.stack); |
| 225 if (e.stack) dartPrint(e.stack); | |
| 226 window.postMessage('unittest-suite-fail', '*'); | |
| 227 return; | 259 return; |
| 228 } | 260 } |
| 229 dartPrint('dart-main-done'); | 261 dartPrint('dart-main-done'); |
| 230 } | 262 } |
| OLD | NEW |