addon-sdk/source/test/tabs/test-fennec-tabs.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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);

mercurial