Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 'use strict';
6 const { Cc, Ci } = require('chrome');
7 const { Loader, LoaderWithHookedConsole } = require('sdk/test/loader');
8 const timer = require('sdk/timers');
9 const tabs = require('sdk/tabs');
10 const windows = require('sdk/windows');
11 const { set: setPref } = require("sdk/preferences/service");
12 const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
14 const tabsLen = tabs.length;
15 const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
17 // Fennec error message dispatched on all currently unimplement tab features,
18 // that match LoaderWithHookedConsole messages object pattern
19 const ERR_FENNEC_MSG = {
20 type: "error",
21 msg: "This method is not yet supported by Fennec"
22 };
24 // TEST: tab unloader
25 exports.testAutomaticDestroy = function(assert, done) {
26 let called = false;
28 let loader2 = Loader(module);
29 let loader3 = Loader(module);
30 let tabs2 = loader2.require('sdk/tabs');
31 let tabs3 = loader3.require('sdk/tabs');
32 let tabs2Len = tabs2.length;
34 tabs2.on('open', function onOpen(tab) {
35 assert.fail("an onOpen listener was called that should not have been");
36 called = true;
37 });
38 tabs2.on('ready', function onReady(tab) {
39 assert.fail("an onReady listener was called that should not have been");
40 called = true;
41 });
42 tabs2.on('select', function onSelect(tab) {
43 assert.fail("an onSelect listener was called that should not have been");
44 called = true;
45 });
46 tabs2.on('close', function onClose(tab) {
47 assert.fail("an onClose listener was called that should not have been");
48 called = true;
49 });
50 loader2.unload();
52 tabs3.on('open', function onOpen(tab) {
53 assert.pass("an onOpen listener was called for tabs3");
55 tab.on('ready', function onReady(tab) {
56 assert.fail("an onReady listener was called that should not have been");
57 called = true;
58 });
59 tab.on('select', function onSelect(tab) {
60 assert.fail("an onSelect listener was called that should not have been");
61 called = true;
62 });
63 tab.on('close', function onClose(tab) {
64 assert.fail("an onClose listener was called that should not have been");
65 called = true;
66 });
67 });
68 tabs3.open(URL.replace(/#title#/, 'tabs3'));
69 loader3.unload();
71 // Fire a tab event and ensure that the destroyed tab is inactive
72 tabs.once('open', function(tab) {
73 assert.pass('tabs.once("open") works!');
75 assert.equal(tabs2Len, tabs2.length, "tabs2 length was not changed");
76 assert.equal(tabs.length, (tabs2.length+2), "tabs.length > tabs2.length");
78 tab.once('ready', function() {
79 assert.pass('tab.once("ready") works!');
81 tab.once('close', function() {
82 assert.pass('tab.once("close") works!');
84 timer.setTimeout(function () {
85 assert.ok(!called, "Unloaded tab module is destroyed and inactive");
87 // end test
88 done();
89 });
90 });
92 tab.close();
93 });
94 });
96 tabs.open('data:text/html;charset=utf-8,foo');
97 };
99 // TEST: tab properties
100 exports.testTabProperties = function(assert, done) {
101 setPref(DEPRECATE_PREF, true);
102 let { loader, messages } = LoaderWithHookedConsole();
103 let tabs = loader.require('sdk/tabs');
105 let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>";
106 let tabsLen = tabs.length;
107 tabs.open({
108 url: url,
109 onReady: function(tab) {
110 assert.equal(tab.title, "foo", "title of the new tab matches");
111 assert.equal(tab.url, url, "URL of the new tab matches");
112 assert.ok(tab.favicon, "favicon of the new tab is not empty");
113 // TODO: remove need for this test by implementing the favicon feature
114 assert.equal(messages[0].msg,
115 "tab.favicon is deprecated, and " +
116 "currently favicon helpers are not yet supported " +
117 "by Fennec",
118 "favicon logs an error for now");
119 assert.equal(tab.style, null, "style of the new tab matches");
120 assert.equal(tab.index, tabsLen, "index of the new tab matches");
121 assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
122 assert.notEqual(tab.id, null, "a tab object always has an id property");
124 tab.close(function() {
125 loader.unload();
127 // end test
128 done();
129 });
130 }
131 });
132 };
134 // TEST: tabs iterator and length property
135 exports.testTabsIteratorAndLength = function(assert, done) {
136 let newTabs = [];
137 let startCount = 0;
138 for each (let t in tabs) startCount++;
140 assert.equal(startCount, tabs.length, "length property is correct");
142 let url = "data:text/html;charset=utf-8,testTabsIteratorAndLength";
143 tabs.open({url: url, onOpen: function(tab) newTabs.push(tab)});
144 tabs.open({url: url, onOpen: function(tab) newTabs.push(tab)});
145 tabs.open({
146 url: url,
147 onOpen: function(tab) {
148 let count = 0;
149 for each (let t in tabs) count++;
150 assert.equal(count, startCount + 3, "iterated tab count matches");
151 assert.equal(startCount + 3, tabs.length, "iterated tab count matches length property");
153 let newTabsLength = newTabs.length;
154 newTabs.forEach(function(t) t.close(function() {
155 if (--newTabsLength > 0) return;
157 tab.close(done);
158 }));
159 }
160 });
161 };
163 // TEST: tab.url setter
164 exports.testTabLocation = function(assert, done) {
165 let url1 = "data:text/html;charset=utf-8,foo";
166 let url2 = "data:text/html;charset=utf-8,bar";
168 tabs.on('ready', function onReady(tab) {
169 if (tab.url != url2)
170 return;
172 tabs.removeListener('ready', onReady);
173 assert.pass("tab loaded the correct url");
175 tab.close(done);
176 });
178 tabs.open({
179 url: url1,
180 onOpen: function(tab) {
181 tab.url = url2;
182 }
183 });
184 };
186 // TEST: tab.move()
187 exports.testTabMove = function(assert, done) {
188 let { loader, messages } = LoaderWithHookedConsole();
189 let tabs = loader.require('sdk/tabs');
191 let url = "data:text/html;charset=utf-8,testTabMove";
193 tabs.open({
194 url: url,
195 onOpen: function(tab1) {
196 assert.ok(tab1.index >= 0, "opening a tab returns a tab w/ valid index");
198 tabs.open({
199 url: url,
200 onOpen: function(tab) {
201 let i = tab.index;
202 assert.ok(tab.index > tab1.index, "2nd tab has valid index");
203 tab.index = 0;
204 assert.equal(tab.index, i, "tab index after move matches");
205 assert.equal(JSON.stringify(messages),
206 JSON.stringify([ERR_FENNEC_MSG]),
207 "setting tab.index logs error");
208 // end test
209 tab1.close(function() tab.close(function() {
210 loader.unload();
211 done();
212 }));
213 }
214 });
215 }
216 });
217 };
219 // TEST: open tab with default options
220 exports.testTabsOpen_alt = function(assert, done) {
221 let { loader, messages } = LoaderWithHookedConsole();
222 let tabs = loader.require('sdk/tabs');
223 let url = "data:text/html;charset=utf-8,default";
225 tabs.open({
226 url: url,
227 onReady: function(tab) {
228 assert.equal(tab.url, url, "URL of the new tab matches");
229 assert.equal(tabs.activeTab, tab, "URL of active tab in the current window matches");
230 assert.equal(tab.isPinned, false, "The new tab is not pinned");
231 assert.equal(messages.length, 1, "isPinned logs error");
233 // end test
234 tab.close(function() {
235 loader.unload();
236 done();
237 });
238 }
239 });
240 };
242 // TEST: open pinned tab
243 exports.testOpenPinned_alt = function(assert, done) {
244 let { loader, messages } = LoaderWithHookedConsole();
245 let tabs = loader.require('sdk/tabs');
246 let url = "about:blank";
248 tabs.open({
249 url: url,
250 isPinned: true,
251 onOpen: function(tab) {
252 assert.equal(tab.isPinned, false, "The new tab is pinned");
253 // We get two error message: one for tabs.open's isPinned argument
254 // and another one for tab.isPinned
255 assert.equal(JSON.stringify(messages),
256 JSON.stringify([ERR_FENNEC_MSG, ERR_FENNEC_MSG]),
257 "isPinned logs error");
259 // end test
260 tab.close(function() {
261 loader.unload();
262 done();
263 });
264 }
265 });
266 };
268 // TEST: pin/unpin opened tab
269 exports.testPinUnpin_alt = function(assert, done) {
270 let { loader, messages } = LoaderWithHookedConsole();
271 let tabs = loader.require('sdk/tabs');
272 let url = "data:text/html;charset=utf-8,default";
274 tabs.open({
275 url: url,
276 onOpen: function(tab) {
277 tab.pin();
278 assert.equal(tab.isPinned, false, "The tab was pinned correctly");
279 assert.equal(JSON.stringify(messages),
280 JSON.stringify([ERR_FENNEC_MSG, ERR_FENNEC_MSG]),
281 "tab.pin() logs error");
283 // Clear console messages for the following test
284 messages.length = 0;
286 tab.unpin();
287 assert.equal(tab.isPinned, false, "The tab was unpinned correctly");
288 assert.equal(JSON.stringify(messages),
289 JSON.stringify([ERR_FENNEC_MSG, ERR_FENNEC_MSG]),
290 "tab.unpin() logs error");
292 // end test
293 tab.close(function() {
294 loader.unload();
295 done();
296 });
297 }
298 });
299 };
301 // TEST: open tab in background
302 exports.testInBackground = function(assert, done) {
303 let activeUrl = tabs.activeTab.url;
304 let url = "data:text/html;charset=utf-8,background";
305 let window = windows.browserWindows.activeWindow;
306 tabs.once('ready', function onReady(tab) {
307 assert.equal(tabs.activeTab.url, activeUrl, "URL of active tab has not changed");
308 assert.equal(tab.url, url, "URL of the new background tab matches");
309 assert.equal(windows.browserWindows.activeWindow, window, "a new window was not opened");
310 assert.notEqual(tabs.activeTab.url, url, "URL of active tab is not the new URL");
312 // end test
313 tab.close(done);
314 });
316 tabs.open({
317 url: url,
318 inBackground: true
319 });
320 };
322 // TEST: open tab in new window
323 exports.testOpenInNewWindow = function(assert, done) {
324 let url = "data:text/html;charset=utf-8,newwindow";
325 let window = windows.browserWindows.activeWindow;
327 tabs.open({
328 url: url,
329 inNewWindow: true,
330 onReady: function(tab) {
331 assert.equal(windows.browserWindows.length, 1, "a new window was not opened");
332 assert.equal(windows.browserWindows.activeWindow, window, "old window is active");
333 assert.equal(tab.url, url, "URL of the new tab matches");
334 assert.equal(tabs.activeTab, tab, "tab is the activeTab");
336 tab.close(done);
337 }
338 });
339 };
341 // TEST: onOpen event handler
342 exports.testTabsEvent_onOpen = function(assert, done) {
343 let url = URL.replace('#title#', 'testTabsEvent_onOpen');
344 let eventCount = 0;
346 // add listener via property assignment
347 function listener1(tab) {
348 eventCount++;
349 };
350 tabs.on('open', listener1);
352 // add listener via collection add
353 tabs.on('open', function listener2(tab) {
354 assert.equal(++eventCount, 2, "both listeners notified");
355 tabs.removeListener('open', listener1);
356 tabs.removeListener('open', listener2);
358 // ends test
359 tab.close(done);
360 });
362 tabs.open(url);
363 };
365 // TEST: onClose event handler
366 exports.testTabsEvent_onClose = function(assert, done) {
367 let url = "data:text/html;charset=utf-8,onclose";
368 let eventCount = 0;
370 // add listener via property assignment
371 function listener1(tab) {
372 eventCount++;
373 }
374 tabs.on('close', listener1);
376 // add listener via collection add
377 tabs.on('close', function listener2(tab) {
378 assert.equal(++eventCount, 2, "both listeners notified");
379 tabs.removeListener('close', listener1);
380 tabs.removeListener('close', listener2);
382 // end test
383 done();
384 });
386 tabs.on('ready', function onReady(tab) {
387 tabs.removeListener('ready', onReady);
388 tab.close();
389 });
391 tabs.open(url);
392 };
394 // TEST: onClose event handler when a window is closed
395 exports.testTabsEvent_onCloseWindow = function(assert, done) {
396 let closeCount = 0, individualCloseCount = 0;
397 function listener() {
398 closeCount++;
399 }
400 tabs.on('close', listener);
402 // One tab is already open with the window
403 let openTabs = 0;
404 function testCasePossiblyLoaded(tab) {
405 tab.close(function() {
406 if (++openTabs == 3) {
407 tabs.removeListener("close", listener);
409 assert.equal(closeCount, 3, "Correct number of close events received");
410 assert.equal(individualCloseCount, 3,
411 "Each tab with an attached onClose listener received a close " +
412 "event when the window was closed");
414 done();
415 }
416 });
417 }
419 tabs.open({
420 url: "data:text/html;charset=utf-8,tab2",
421 onOpen: testCasePossiblyLoaded,
422 onClose: function() individualCloseCount++
423 });
425 tabs.open({
426 url: "data:text/html;charset=utf-8,tab3",
427 onOpen: testCasePossiblyLoaded,
428 onClose: function() individualCloseCount++
429 });
431 tabs.open({
432 url: "data:text/html;charset=utf-8,tab4",
433 onOpen: testCasePossiblyLoaded,
434 onClose: function() individualCloseCount++
435 });
436 };
438 // TEST: onReady event handler
439 exports.testTabsEvent_onReady = function(assert, done) {
440 let url = "data:text/html;charset=utf-8,onready";
441 let eventCount = 0;
443 // add listener via property assignment
444 function listener1(tab) {
445 eventCount++;
446 };
447 tabs.on('ready', listener1);
449 // add listener via collection add
450 tabs.on('ready', function listener2(tab) {
451 assert.equal(++eventCount, 2, "both listeners notified");
452 tabs.removeListener('ready', listener1);
453 tabs.removeListener('ready', listener2);
455 // end test
456 tab.close(done);
457 });
459 tabs.open(url);
460 };
462 // TEST: onActivate event handler
463 exports.testTabsEvent_onActivate = function(assert, done) {
464 let url = "data:text/html;charset=utf-8,onactivate";
465 let eventCount = 0;
467 // add listener via property assignment
468 function listener1(tab) {
469 eventCount++;
470 };
471 tabs.on('activate', listener1);
473 // add listener via collection add
474 tabs.on('activate', function listener2(tab) {
475 assert.equal(++eventCount, 2, "both listeners notified");
476 assert.equal(tab, tabs.activeTab, 'the active tab is correct');
477 tabs.removeListener('activate', listener1);
478 tabs.removeListener('activate', listener2);
480 // end test
481 tab.close(done);
482 });
484 tabs.open(url);
485 };
487 // TEST: onDeactivate event handler
488 exports.testTabsEvent_onDeactivate = function(assert, done) {
489 let url = "data:text/html;charset=utf-8,ondeactivate";
490 let eventCount = 0;
492 // add listener via property assignment
493 function listener1(tab) {
494 eventCount++;
495 };
496 tabs.on('deactivate', listener1);
498 // add listener via collection add
499 tabs.on('deactivate', function listener2(tab) {
500 assert.equal(++eventCount, 2, 'both listeners notified');
501 assert.notEqual(tab, tabs.activeTab, 'the active tab is not the deactivated tab');
502 tabs.removeListener('deactivate', listener1);
503 tabs.removeListener('deactivate', listener2);
505 // end test
506 tab.close(done);
507 });
509 tabs.on('activate', function onActivate(tab) {
510 tabs.removeListener('activate', onActivate);
511 tabs.open("data:text/html;charset=utf-8,foo");
512 tab.close();
513 });
515 tabs.open(url);
516 };
518 // TEST: per-tab event handlers
519 exports.testPerTabEvents = function(assert, done) {
520 let eventCount = 0;
522 tabs.open({
523 url: "data:text/html;charset=utf-8,foo",
524 onOpen: function(tab) {
525 // add listener via property assignment
526 function listener1() {
527 eventCount++;
528 };
529 tab.on('ready', listener1);
531 // add listener via collection add
532 tab.on('ready', function listener2() {
533 assert.equal(eventCount, 1, "both listeners notified");
534 tab.removeListener('ready', listener1);
535 tab.removeListener('ready', listener2);
537 // end test
538 tab.close(done);
539 });
540 }
541 });
542 };
544 exports.testUniqueTabIds = function(assert, done) {
545 var tabs = require('sdk/tabs');
546 var tabIds = {};
547 var steps = [
548 function (index) {
549 tabs.open({
550 url: "data:text/html;charset=utf-8,foo",
551 onOpen: function(tab) {
552 tabIds['tab1'] = tab.id;
553 next(index);
554 }
555 });
556 },
557 function (index) {
558 tabs.open({
559 url: "data:text/html;charset=utf-8,bar",
560 onOpen: function(tab) {
561 tabIds['tab2'] = tab.id;
562 next(index);
563 }
564 });
565 },
566 function (index) {
567 assert.notEqual(tabIds.tab1, tabIds.tab2, "Tab ids should be unique.");
568 done();
569 }
570 ];
572 function next(index) {
573 if (index === steps.length) {
574 return;
575 }
576 let fn = steps[index];
577 index++;
578 fn(index);
579 }
581 next(0);
582 }
584 exports.testOnLoadEventWithDOM = function(assert, done) {
585 let count = 0;
586 let title = 'testOnLoadEventWithDOM';
588 tabs.open({
589 url: 'data:text/html;charset=utf-8,<title>' + title + '</title>',
590 inBackground: true,
591 onLoad: function(tab) {
592 assert.equal(tab.title, title, 'tab passed in as arg, load called');
594 if (++count > 1) {
595 assert.pass('onLoad event called on reload');
596 tab.close(done);
597 }
598 else {
599 assert.pass('first onLoad event occured');
600 tab.reload();
601 }
602 }
603 });
604 };
606 require('sdk/test').run(exports);