Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(660)

Side by Side Diff: dart/pkg/unittest/lib/test_controller.js

Issue 36913002: test.py: Sending JSON between test_controller.js <-> browser_controller (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698