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

Side by Side Diff: src/site/samples/polymer_intl/example/packages/unittest/test_controller.js

Issue 1387723002: Updating the samples page to reflect the examples that have been retired. (Closed) Base URL: https://github.com/dart-lang/www.dartlang.org.git@master
Patch Set: Created 5 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
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 /*
6 * The communication protocol between test_controller.js and the driving
7 * page are JSON encoded messages of the following form:
8 * message = {
9 * is_first_message: true/false,
10 * is_status_update: true/false,
11 * is_done: true/false,
12 * message: message_content,
13 * }
14 *
15 * The first message should have [is_first_message] set, the last message
16 * should have [is_done] set. Status updates should have [is_status_update] set.
17 *
18 * The [message_content] can be be any content. In our case it will a list of
19 * events encoded in JSON. See the next comment further down about what an event
20 * is.
21 */
22
23 /*
24 * We will collect testing driver specific events here instead of printing
25 * them to the DOM.
26 * Every entry will look like this:
27 * {
28 * 'type' : 'sync_exception' / 'window_onerror' / 'script_onerror' / 'print'
29 * 'window_compilationerror' / 'message_received' / 'dom' / 'debug'
30 * 'value' : 'some content',
31 * 'timestamp' : TimestampInMs,
32 * }
33 */
34 var recordedEventList = [];
35 var timestampOfFirstEvent = null;
36
37 var STATUS_UPDATE_INTERVALL = 10000;
38
39 function getCurrentTimestamp() {
40 if (timestampOfFirstEvent == null) {
41 timestampOfFirstEvent = new Date().getTime();
42 }
43 return (new Date().getTime() - timestampOfFirstEvent) / 1000.0;
44 }
45
46 function stringifyEvent(event) {
47 return JSON.stringify(event, null, 2);
48 }
49
50 function recordEvent(type, value) {
51 var event = {
52 type: type,
53 value: value,
54 timestamp: getCurrentTimestamp()
55 };
56 recordedEventList.push(event);
57 printToConsole(stringifyEvent(event));
58 }
59
60 function clearConsole() {
61 // Clear the console before every test run - this is Firebug specific code.
62 if (typeof console == 'object' && typeof console.clear == 'function') {
63 console.clear();
64 }
65 }
66
67 function printToDOM(message) {
68 var pre = document.createElement('pre');
69 pre.appendChild(document.createTextNode(String(message)));
70 document.body.appendChild(pre);
71 document.body.appendChild(document.createTextNode('\n'));
72 }
73
74 function printToConsole(message) {
75 var consoleAvailable = typeof console === 'object';
76
77 if (consoleAvailable) {
78 console.log(message);
79 }
80 }
81
82 clearConsole();
83
84 // Some tests may expect and have no way to suppress global errors.
85 var testExpectsGlobalError = false;
86 var testSuppressedGlobalErrors = [];
87
88 // Set window onerror to make sure that we catch test harness errors across all
89 // browsers.
90 window.onerror = function (message, url, lineNumber) {
91 if (url) {
92 message = ('window.onerror called: \n\n' +
93 url + ':' + lineNumber + ':\n' + message + '\n\n');
94 }
95 if (testExpectsGlobalError) {
96 testSuppressedGlobalErrors.push({
97 message: message
98 });
99 return;
100 }
101 recordEvent('window_onerror', message);
102 notifyDone('FAIL');
103 };
104
105 // testRunner is provided by content shell.
106 // It is not available in browser tests.
107 var testRunner = window.testRunner || window.layoutTestController;
108 var isContentShell = testRunner;
109
110 var waitForDone = false;
111
112 var driverWindowCached = false;
113 var driverWindow;
114 var reportingDriverWindowError = false;
115
116 // Returns the driving window object if available
117 // This function occasionally returns null instead of the
118 // parent on Android content shell, so we cache the value
119 // to get a consistent answer.
120 function getDriverWindow() {
121 if (window != window.parent) {
122 // We're running in an iframe.
123 result = window.parent;
124 } else if (window.opener) {
125 // We were opened by another window.
126 result = window.opener;
127 } else {
128 result = null;
129 }
130 if (driverWindowCached) {
131 if (result != driverWindow) {
132 recordEvent('debug', 'Driver windows changed: was null == ' +
133 (driverWindow == null) + ', is null == ' + (result == null));
134 // notifyDone calls back into this function multiple times. Avoid loop.
135 if (!reportingDriverWindowError) {
136 reportingDriverWindowError = true;
137 notifyDone('FAIL');
138 }
139 }
140 } else {
141 driverWindowCached = true;
142 driverWindow = result;
143 }
144 return driverWindow;
145 }
146
147 function usingBrowserController() {
148 return getDriverWindow() != null;
149 }
150
151 function buildDomEvent() {
152 return {
153 type: 'dom',
154 value: '' + window.document.documentElement.innerHTML,
155 timestamp: getCurrentTimestamp()
156 };
157 }
158
159 function notifyUpdate(testOutcome, isFirstMessage, isStatusUpdate, isDone) {
160 // If we are not using the browser controller (e.g. in the none-drt
161 // configuration), we need to print 'testOutcome' as it is.
162 if (isDone && !usingBrowserController()) {
163 if (isContentShell) {
164 // We need this, since test.dart is looking for 'FAIL\n', 'PASS\n' in the
165 // DOM output of content shell.
166 printToDOM(testOutcome);
167 } else {
168 printToConsole('Test outcome: ' + testOutcome);
169 }
170 } else if (usingBrowserController()) {
171 // To support in browser launching of tests we post back start and result
172 // messages to the window.opener.
173 var driver = getDriverWindow();
174
175 recordEvent('debug', 'Sending events to driver page (isFirstMessage = ' +
176 isFirstMessage + ', isStatusUpdate = ' +
177 isStatusUpdate + ', isDone = ' + isDone + ')');
178 // Post the DOM and all events that happened.
179 var events = recordedEventList.slice(0);
180 events.push(buildDomEvent());
181
182 var message = JSON.stringify(events);
183 driver.postMessage(
184 JSON.stringify({
185 message: message,
186 is_first_message: isFirstMessage,
187 is_status_update: isStatusUpdate,
188 is_done: isDone
189 }), '*');
190 }
191 if (isDone) {
192 if (testRunner) testRunner.notifyDone();
193 }
194 }
195
196 function notifyDone(testOutcome) {
197 notifyUpdate(testOutcome, false, false, true);
198 }
199
200 // Repeatedly send back the current status of this test.
201 function sendStatusUpdate(isFirstMessage) {
202 notifyUpdate('', isFirstMessage, true, false);
203 setTimeout(function() {sendStatusUpdate(false)}, STATUS_UPDATE_INTERVALL);
204 }
205
206 // We call notifyStart here to notify the encapsulating browser.
207 recordEvent('debug', 'test_controller.js started');
208 sendStatusUpdate(true);
209
210 function processMessage(msg) {
211 // Filter out ShadowDOM polyfill messages which are random floats.
212 if (msg != parseFloat(msg)) {
213 recordEvent('message_received', '' + msg);
214 }
215 if (typeof msg != 'string') return;
216 if (msg == 'unittest-suite-wait-for-done') {
217 waitForDone = true;
218 if (testRunner) {
219 testRunner.startedDartTest = true;
220 }
221 } else if (msg == 'dart-calling-main') {
222 if (testRunner) {
223 testRunner.startedDartTest = true;
224 }
225 } else if (msg == 'dart-main-done') {
226 if (!waitForDone) {
227 notifyDone('PASS');
228 }
229 } else if (msg == 'unittest-suite-success' ||
230 msg == 'unittest-suite-done') {
231 notifyDone('PASS');
232 } else if (msg == 'unittest-suite-fail') {
233 notifyDone('FAIL');
234 }
235 }
236
237 function onReceive(e) {
238 processMessage(e.data);
239 }
240
241 if (testRunner) {
242 testRunner.dumpAsText();
243 testRunner.waitUntilDone();
244 }
245 window.addEventListener('message', onReceive, false);
246
247 function onLoad(e) {
248 // needed for dartium compilation errors.
249 if (window.compilationError) {
250 recordEvent('window_compilationerror',
251 'DOMContentLoaded event: window.compilationError = ' +
252 calledwindow.compilationError);
253 notifyDone('FAIL');
254 }
255 }
256
257 window.addEventListener('DOMContentLoaded', onLoad, false);
258
259 // Note: before renaming this function, note that it is also included in an
260 // inlined error handler in generated HTML files, and manually in tests that
261 // include an HTML file.
262 // See: tools/testing/dart/browser_test.dart
263 function scriptTagOnErrorCallback(e) {
264 var message = e && e.message;
265 recordEvent('script_onerror', 'script.onError called: ' + message);
266 notifyDone('FAIL');
267 }
268
269 // dart2js will generate code to call this function to handle the Dart
270 // [print] method.
271 //
272 // dartium will invoke this method for [print] calls if the environment variable
273 // "DART_FORWARDING_PRINT" was set when launching dartium.
274 //
275 // Our tests will be wrapped, so we can detect when [main] is called and when
276 // it has ended.
277 // The wrapping happens either via "dartMainRunner" (for dart2js) or wrapped
278 // tests for dartium.
279 //
280 // The following messages are handled specially:
281 // dart-calling-main: signals that the dart [main] function will be invoked
282 // dart-main-done: signals that the dart [main] function has finished
283 // unittest-suite-wait-for-done: signals the start of an asynchronous test
284 // unittest-suite-success: signals the end of an asynchrounous test
285 // unittest-suite-fail: signals that the asynchronous test failed
286 // unittest-suite-done: signals the end of an asynchronous test, the outcome
287 // is unknown
288 //
289 // These messages are used to communicate with the test and will be posted so
290 // [processMessage] above can see it.
291 function dartPrint(message) {
292 recordEvent('print', message);
293 if ((message === 'unittest-suite-wait-for-done') ||
294 (message === 'unittest-suite-success') ||
295 (message === 'unittest-suite-fail') ||
296 (message === 'unittest-suite-done') ||
297 (message === 'dart-calling-main') ||
298 (message === 'dart-main-done')) {
299 // We have to do this asynchronously, in case error messages are
300 // already in the message queue.
301 window.postMessage(message, '*');
302 return;
303 }
304 }
305
306 // dart2js will generate code to call this function instead of calling
307 // Dart [main] directly. The argument is a closure that invokes main.
308 function dartMainRunner(main) {
309 dartPrint('dart-calling-main');
310 try {
311 main();
312 } catch (e) {
313 recordEvent('sync_exception', 'Exception: ' + e + '\nStack: ' + e.stack);
314 notifyDone('FAIL');
315 return;
316 }
317 dartPrint('dart-main-done');
318 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698