dom/tests/browser/browser_ConsoleAPITests.js

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:39f7d4f1c392
1 /* vim:set ts=2 sw=2 sts=2 et: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html";
7
8 var gWindow, gLevel, gArgs, gTestDriver, gStyle;
9
10 function test() {
11 waitForExplicitFinish();
12
13 var tab = gBrowser.addTab(TEST_URI);
14 gBrowser.selectedTab = tab;
15 var browser = gBrowser.selectedBrowser;
16
17 registerCleanupFunction(function () {
18 gWindow = gLevel = gArgs = gTestDriver = null;
19 gBrowser.removeTab(tab);
20 });
21
22 ConsoleObserver.init();
23
24 browser.addEventListener("DOMContentLoaded", function onLoad(event) {
25 browser.removeEventListener("DOMContentLoaded", onLoad, false);
26 executeSoon(function test_executeSoon() {
27 gWindow = browser.contentWindow;
28 consoleAPISanityTest();
29 gTestDriver = observeConsoleTest();
30 gTestDriver.next();
31 });
32
33 }, false);
34 }
35
36 function testConsoleData(aMessageObject) {
37 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
38 is(messageWindow, gWindow, "found correct window by window ID");
39
40 is(aMessageObject.level, gLevel, "expected level received");
41 ok(aMessageObject.arguments, "we have arguments");
42
43 switch (gLevel) {
44 case "trace": {
45 is(aMessageObject.arguments.length, 0, "arguments.length matches");
46 is(aMessageObject.stacktrace.toSource(), gArgs.toSource(),
47 "stack trace is correct");
48 break
49 }
50 case "count": {
51 is(aMessageObject.counter.label, gArgs[0].label, "label matches");
52 is(aMessageObject.counter.count, gArgs[0].count, "count matches");
53 break;
54 }
55 default: {
56 is(aMessageObject.arguments.length, gArgs.length, "arguments.length matches");
57 gArgs.forEach(function (a, i) {
58 // Waive Xray so that we don't get messed up by Xray ToString.
59 //
60 // It'd be nice to just use XPCNativeWrapper.unwrap here, but there are
61 // a number of dumb reasons we can't. See bug 868675.
62 var arg = aMessageObject.arguments[i];
63 if (Components.utils.isXrayWrapper(arg))
64 arg = arg.wrappedJSObject;
65 is(arg, a, "correct arg " + i);
66 });
67
68 if (gStyle) {
69 is(aMessageObject.styles.length, gStyle.length, "styles.length matches");
70 is(aMessageObject.styles + "", gStyle + "", "styles match");
71 } else {
72 ok(!aMessageObject.styles || aMessageObject.styles.length === 0,
73 "styles match");
74 }
75 }
76 }
77
78 gTestDriver.next();
79 }
80
81 function testLocationData(aMessageObject) {
82 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
83 is(messageWindow, gWindow, "found correct window by window ID");
84
85 is(aMessageObject.level, gLevel, "expected level received");
86 ok(aMessageObject.arguments, "we have arguments");
87
88 is(aMessageObject.filename, gArgs[0].filename, "filename matches");
89 is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
90 is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
91 is(aMessageObject.arguments.length, gArgs[0].arguments.length, "arguments.length matches");
92 gArgs[0].arguments.forEach(function (a, i) {
93 is(aMessageObject.arguments[i], a, "correct arg " + i);
94 });
95
96 startNativeCallbackTest();
97 }
98
99 function startNativeCallbackTest() {
100 // Reset the observer function to cope with the fabricated test data.
101 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
102 try {
103 testNativeCallback(aSubject.wrappedJSObject);
104 } catch (ex) {
105 // XXX Bug 906593 - Exceptions in this function currently aren't
106 // reported, because of some XPConnect weirdness, so report them manually
107 ok(false, "Exception thrown in CO_observe: " + ex);
108 }
109 };
110
111 let button = gWindow.document.getElementById("test-nativeCallback");
112 ok(button, "found #test-nativeCallback button");
113 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
114 }
115
116 function testNativeCallback(aMessageObject) {
117 is(aMessageObject.level, "log", "expected level received");
118 is(aMessageObject.filename, "", "filename matches");
119 is(aMessageObject.lineNumber, 0, "lineNumber matches");
120 is(aMessageObject.functionName, "", "functionName matches");
121
122 startGroupTest();
123 }
124
125 function startGroupTest() {
126 // Reset the observer function to cope with the fabricated test data.
127 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
128 try {
129 testConsoleGroup(aSubject.wrappedJSObject);
130 } catch (ex) {
131 // XXX Bug 906593 - Exceptions in this function currently aren't
132 // reported, because of some XPConnect weirdness, so report them manually
133 ok(false, "Exception thrown in CO_observe: " + ex);
134 }
135 };
136 let button = gWindow.document.getElementById("test-groups");
137 ok(button, "found #test-groups button");
138 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
139 }
140
141 function testConsoleGroup(aMessageObject) {
142 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
143 is(messageWindow, gWindow, "found correct window by window ID");
144
145 ok(aMessageObject.level == "group" ||
146 aMessageObject.level == "groupCollapsed" ||
147 aMessageObject.level == "groupEnd",
148 "expected level received");
149
150 is(aMessageObject.functionName, "testGroups", "functionName matches");
151 ok(aMessageObject.lineNumber >= 46 && aMessageObject.lineNumber <= 50,
152 "lineNumber matches");
153 if (aMessageObject.level == "groupCollapsed") {
154 is(aMessageObject.groupName, "a group", "groupCollapsed groupName matches");
155 is(aMessageObject.arguments[0], "a", "groupCollapsed arguments[0] matches");
156 is(aMessageObject.arguments[1], "group", "groupCollapsed arguments[0] matches");
157 }
158 else if (aMessageObject.level == "group") {
159 is(aMessageObject.groupName, "b group", "group groupName matches");
160 is(aMessageObject.arguments[0], "b", "group arguments[0] matches");
161 is(aMessageObject.arguments[1], "group", "group arguments[1] matches");
162 }
163 else if (aMessageObject.level == "groupEnd") {
164 let groupName = Array.prototype.join.call(aMessageObject.arguments, " ");
165 is(groupName,"b group", "groupEnd arguments matches");
166 is(aMessageObject.groupName, "b group", "groupEnd groupName matches");
167 }
168
169 if (aMessageObject.level == "groupEnd") {
170 startTimeTest();
171 }
172 }
173
174 function startTraceTest() {
175 gLevel = "trace";
176 gArgs = [
177 {filename: TEST_URI, functionName: "window.foobar585956c", language: 2, lineNumber: 6},
178 {filename: TEST_URI, functionName: "foobar585956b", language: 2, lineNumber: 11},
179 {filename: TEST_URI, functionName: "foobar585956a", language: 2, lineNumber: 15},
180 {filename: TEST_URI, functionName: "onclick", language: 2, lineNumber: 1}
181 ];
182
183 let button = gWindow.document.getElementById("test-trace");
184 ok(button, "found #test-trace button");
185 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
186 }
187
188 function startLocationTest() {
189 // Reset the observer function to cope with the fabricated test data.
190 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
191 try {
192 testLocationData(aSubject.wrappedJSObject);
193 } catch (ex) {
194 // XXX Bug 906593 - Exceptions in this function currently aren't
195 // reported, because of some XPConnect weirdness, so report them manually
196 ok(false, "Exception thrown in CO_observe: " + ex);
197 }
198 };
199 gLevel = "log";
200 gArgs = [
201 {filename: TEST_URI, functionName: "foobar646025", arguments: ["omg", "o", "d"], lineNumber: 19}
202 ];
203
204 let button = gWindow.document.getElementById("test-location");
205 ok(button, "found #test-location button");
206 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
207 }
208
209 function expect(level) {
210 gLevel = level;
211 gArgs = Array.slice(arguments, 1);
212 }
213
214 function observeConsoleTest() {
215 let win = XPCNativeWrapper.unwrap(gWindow);
216 expect("log", "arg");
217 win.console.log("arg");
218 yield undefined;
219
220 expect("info", "arg", "extra arg");
221 win.console.info("arg", "extra arg");
222 yield undefined;
223
224 expect("warn", "Lesson 1: PI is approximately equal to 3");
225 win.console.warn("Lesson %d: %s is approximately equal to %1.0f",
226 1,
227 "PI",
228 3.14159);
229 yield undefined;
230
231 expect("warn", "Lesson 1: PI is approximately equal to 3.14");
232 win.console.warn("Lesson %d: %s is approximately equal to %1.2f",
233 1,
234 "PI",
235 3.14159);
236 yield undefined;
237
238 expect("warn", "Lesson 1: PI is approximately equal to 3.141590");
239 win.console.warn("Lesson %d: %s is approximately equal to %f",
240 1,
241 "PI",
242 3.14159);
243 yield undefined;
244
245 expect("warn", "Lesson 1: PI is approximately equal to 3.1415900");
246 win.console.warn("Lesson %d: %s is approximately equal to %0.7f",
247 1,
248 "PI",
249 3.14159);
250 yield undefined;
251
252 expect("log", "%d, %s, %l");
253 win.console.log("%d, %s, %l");
254 yield undefined;
255
256 expect("log", "%a %b %g");
257 win.console.log("%a %b %g");
258 yield undefined;
259
260 expect("log", "%a %b %g", "a", "b");
261 win.console.log("%a %b %g", "a", "b");
262 yield undefined;
263
264 expect("log", "2, a, %l", 3);
265 win.console.log("%d, %s, %l", 2, "a", 3);
266 yield undefined;
267
268 // Bug #692550 handle null and undefined.
269 expect("log", "null, undefined");
270 win.console.log("%s, %s", null, undefined);
271 yield undefined;
272
273 // Bug #696288 handle object as first argument.
274 let obj = { a: 1 };
275 expect("log", obj, "a");
276 win.console.log(obj, "a");
277 yield undefined;
278
279 expect("dir", win.toString());
280 win.console.dir(win);
281 yield undefined;
282
283 expect("error", "arg");
284 win.console.error("arg");
285 yield undefined;
286
287 expect("exception", "arg");
288 win.console.exception("arg");
289 yield undefined;
290
291 expect("log", "foobar");
292 gStyle = ["color:red;foobar;;"];
293 win.console.log("%cfoobar", gStyle[0]);
294 yield undefined;
295
296 let obj4 = { d: 4 };
297 expect("warn", "foobar", obj4, "test", "bazbazstr", "last");
298 gStyle = [null, null, null, "color:blue;", "color:red"];
299 win.console.warn("foobar%Otest%cbazbaz%s%clast", obj4, gStyle[3], "str", gStyle[4]);
300 yield undefined;
301
302 let obj3 = { c: 3 };
303 expect("info", "foobar", "bazbaz", obj3, "%comg", "color:yellow");
304 gStyle = [null, "color:pink;"];
305 win.console.info("foobar%cbazbaz", gStyle[1], obj3, "%comg", "color:yellow");
306 yield undefined;
307
308 gStyle = null;
309 let obj2 = { b: 2 };
310 expect("log", "omg ", obj, " foo ", 4, obj2);
311 win.console.log("omg %o foo %o", obj, 4, obj2);
312 yield undefined;
313
314 expect("assert", "message");
315 win.console.assert(false, "message");
316 yield undefined;
317
318 expect("count", { label: "label a", count: 1 })
319 win.console.count("label a");
320 yield undefined;
321
322 expect("count", { label: "label b", count: 1 })
323 win.console.count("label b");
324 yield undefined;
325
326 expect("count", { label: "label a", count: 2 })
327 win.console.count("label a");
328 yield undefined;
329
330 expect("count", { label: "label b", count: 2 })
331 win.console.count("label b");
332 yield undefined;
333
334 startTraceTest();
335 yield undefined;
336
337 startLocationTest();
338 yield undefined;
339 }
340
341 function consoleAPISanityTest() {
342 let win = XPCNativeWrapper.unwrap(gWindow);
343 ok(win.console, "we have a console attached");
344 ok(win.console, "we have a console attached, 2nd attempt");
345
346 ok(win.console.log, "console.log is here");
347 ok(win.console.info, "console.info is here");
348 ok(win.console.warn, "console.warn is here");
349 ok(win.console.error, "console.error is here");
350 ok(win.console.exception, "console.exception is here");
351 ok(win.console.trace, "console.trace is here");
352 ok(win.console.dir, "console.dir is here");
353 ok(win.console.group, "console.group is here");
354 ok(win.console.groupCollapsed, "console.groupCollapsed is here");
355 ok(win.console.groupEnd, "console.groupEnd is here");
356 ok(win.console.time, "console.time is here");
357 ok(win.console.timeEnd, "console.timeEnd is here");
358 ok(win.console.assert, "console.assert is here");
359 ok(win.console.count, "console.count is here");
360 }
361
362 function startTimeTest() {
363 // Reset the observer function to cope with the fabricated test data.
364 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
365 try {
366 testConsoleTime(aSubject.wrappedJSObject);
367 } catch (ex) {
368 // XXX Bug 906593 - Exceptions in this function currently aren't
369 // reported, because of some XPConnect weirdness, so report them manually
370 ok(false, "Exception thrown in CO_observe: " + ex);
371 }
372 };
373 gLevel = "time";
374 gArgs = [
375 {filename: TEST_URI, lineNumber: 23, functionName: "startTimer",
376 arguments: ["foo"],
377 timer: { name: "foo" },
378 }
379 ];
380
381 let button = gWindow.document.getElementById("test-time");
382 ok(button, "found #test-time button");
383 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
384 }
385
386 function testConsoleTime(aMessageObject) {
387 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
388 is(messageWindow, gWindow, "found correct window by window ID");
389
390 is(aMessageObject.level, gLevel, "expected level received");
391
392 is(aMessageObject.filename, gArgs[0].filename, "filename matches");
393 is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
394 is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
395 is(aMessageObject.timer.name, gArgs[0].timer.name, "timer.name matches");
396 ok(aMessageObject.timer.started, "timer.started exists");
397
398 gArgs[0].arguments.forEach(function (a, i) {
399 is(aMessageObject.arguments[i], a, "correct arg " + i);
400 });
401
402 startTimeEndTest();
403 }
404
405 function startTimeEndTest() {
406 // Reset the observer function to cope with the fabricated test data.
407 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
408 try {
409 testConsoleTimeEnd(aSubject.wrappedJSObject);
410 } catch (ex) {
411 // XXX Bug 906593 - Exceptions in this function currently aren't
412 // reported, because of some XPConnect weirdness, so report them manually
413 ok(false, "Exception thrown in CO_observe: " + ex);
414 }
415 };
416 gLevel = "timeEnd";
417 gArgs = [
418 {filename: TEST_URI, lineNumber: 27, functionName: "stopTimer",
419 arguments: ["foo"],
420 timer: { name: "foo" },
421 },
422 ];
423
424 let button = gWindow.document.getElementById("test-timeEnd");
425 ok(button, "found #test-timeEnd button");
426 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
427 }
428
429 function testConsoleTimeEnd(aMessageObject) {
430 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
431 is(messageWindow, gWindow, "found correct window by window ID");
432
433 is(aMessageObject.level, gLevel, "expected level received");
434 ok(aMessageObject.arguments, "we have arguments");
435
436 is(aMessageObject.filename, gArgs[0].filename, "filename matches");
437 is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
438 is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
439 is(aMessageObject.arguments.length, gArgs[0].arguments.length, "arguments.length matches");
440 is(aMessageObject.timer.name, gArgs[0].timer.name, "timer name matches");
441 is(typeof aMessageObject.timer.duration, "number", "timer duration is a number");
442 info("timer duration: " + aMessageObject.timer.duration);
443 ok(aMessageObject.timer.duration >= 0, "timer duration is positive");
444
445 gArgs[0].arguments.forEach(function (a, i) {
446 is(aMessageObject.arguments[i], a, "correct arg " + i);
447 });
448
449 startEmptyTimerTest();
450 }
451
452 function startEmptyTimerTest() {
453 // Reset the observer function to cope with the fabricated test data.
454 ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
455 try {
456 testEmptyTimer(aSubject.wrappedJSObject);
457 } catch (ex) {
458 // XXX Bug 906593 - Exceptions in this function currently aren't
459 // reported, because of some XPConnect weirdness, so report them manually
460 ok(false, "Exception thrown in CO_observe: " + ex);
461 }
462 };
463
464 let button = gWindow.document.getElementById("test-namelessTimer");
465 ok(button, "found #test-namelessTimer button");
466 EventUtils.synthesizeMouseAtCenter(button, {}, gWindow);
467 }
468
469 function testEmptyTimer(aMessageObject) {
470 let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
471 is(messageWindow, gWindow, "found correct window by window ID");
472
473 ok(aMessageObject.level == "time" || aMessageObject.level == "timeEnd",
474 "expected level received");
475 is(aMessageObject.arguments.length, 0, "we don't have arguments");
476 ok(!aMessageObject.timer, "we don't have a timer");
477
478 is(aMessageObject.functionName, "namelessTimer", "functionName matches");
479 ok(aMessageObject.lineNumber == 31 || aMessageObject.lineNumber == 32,
480 "lineNumber matches");
481 // Test finished
482 ConsoleObserver.destroy();
483 finish();
484 }
485
486 var ConsoleObserver = {
487 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
488
489 init: function CO_init() {
490 Services.obs.addObserver(this, "console-api-log-event", false);
491 },
492
493 destroy: function CO_destroy() {
494 Services.obs.removeObserver(this, "console-api-log-event");
495 },
496
497 observe: function CO_observe(aSubject, aTopic, aData) {
498 try {
499 testConsoleData(aSubject.wrappedJSObject);
500 } catch (ex) {
501 // XXX Bug 906593 - Exceptions in this function currently aren't
502 // reported, because of some XPConnect weirdness, so report them manually
503 ok(false, "Exception thrown in CO_observe: " + ex);
504 }
505 }
506 };
507
508 function getWindowId(aWindow)
509 {
510 return aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
511 .getInterface(Ci.nsIDOMWindowUtils)
512 .outerWindowID;
513 }

mercurial