addon-sdk/source/test/windows/test-firefox-windows.js

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 { setTimeout } = require('sdk/timers');
     8 const { Loader } = require('sdk/test/loader');
     9 const { onFocus, getMostRecentWindow, windows, isBrowser, getWindowTitle } = require('sdk/window/utils');
    10 const { open, close, focus } = require('sdk/window/helpers');
    11 const { browserWindows } = require("sdk/windows");
    12 const tabs = require("sdk/tabs");
    13 const winUtils = require("sdk/deprecated/window-utils");
    14 const { WindowTracker } = winUtils;
    15 const { isPrivate } = require('sdk/private-browsing');
    16 const { isWindowPBSupported } = require('sdk/private-browsing/utils');
    17 const { viewFor } = require("sdk/view/core");
    18 const { defer } = require("sdk/lang/functional");
    20 // TEST: open & close window
    21 exports.testOpenAndCloseWindow = function(assert, done) {
    22   assert.equal(browserWindows.length, 1, "Only one window open");
    23   let title = 'testOpenAndCloseWindow';
    25   browserWindows.open({
    26     url: "data:text/html;charset=utf-8,<title>" + title + "</title>",
    27     onOpen: function(window) {
    28       assert.equal(this, browserWindows, "The 'this' object is the windows object.");
    29       assert.equal(window.tabs.length, 1, "Only one tab open");
    30       assert.equal(browserWindows.length, 2, "Two windows open");
    32       window.tabs.activeTab.once('ready', function onReady(tab) {
    33         assert.pass(RegExp(title).test(window.title), "URL correctly loaded");
    34         window.close();
    35       });
    36     },
    37     onClose: function(window) {
    38       assert.equal(window.tabs.length, 0, "Tabs were cleared");
    39       assert.equal(browserWindows.length, 1, "Only one window open");
    40       done();
    41     }
    42   });
    43 };
    45 exports.testAutomaticDestroy = function(assert, done) {
    46   let windows = browserWindows;
    48   // Create a second windows instance that we will unload
    49   let called = false;
    50   let loader = Loader(module);
    51   let windows2 = loader.require("sdk/windows").browserWindows;
    53   windows2.on("open", function() {
    54     called = true;
    55   });
    57   loader.unload();
    59   // Fire a windows event and check that this unloaded instance is inactive
    60   windows.open({
    61     url: "data:text/html;charset=utf-8,foo",
    62     onOpen: function(window) {
    63       setTimeout(function () {
    64         assert.ok(!called, "Unloaded windows instance is destroyed and inactive");
    66         window.close(done);
    67       });
    68     }
    69   });
    70 };
    72 exports.testWindowTabsObject = function(assert, done) {
    73   let window, count = 0;
    74   function runTest() {
    75     if (++count != 2)
    76       return;
    78     assert.equal(window.tabs.length, 1, "Only 1 tab open");
    79     assert.equal(window.tabs.activeTab.title, "tab 1", "Correct active tab");
    81     window.tabs.open({
    82       url: "data:text/html;charset=utf-8,<title>tab 2</title>",
    83       inBackground: true,
    84       onReady: function onReady(newTab) {
    85         assert.equal(window.tabs.length, 2, "New tab open");
    86         assert.equal(newTab.title, "tab 2", "Correct new tab title");
    87         assert.equal(window.tabs.activeTab.title, "tab 1", "Correct active tab");
    89         let i = 1;
    90         for (let tab of window.tabs)
    91           assert.equal(tab.title, "tab " + i++, "Correct title");
    93         window.close();
    94       }
    95     });
    96   }
    98   tabs.once("ready", runTest);
   100   browserWindows.open({
   101     url: "data:text/html;charset=utf-8,<title>tab 1</title>",
   102     onActivate: function onActivate(win) {
   103       window = win;
   104       runTest();
   105     },
   106     onClose: function onClose(window) {
   107       assert.equal(window.tabs.length, 0, "No more tabs on closed window");
   108       done();
   109     }
   110   });
   111 };
   113 exports.testOnOpenOnCloseListeners = function(assert, done) {
   114   let windows = browserWindows;
   116   assert.equal(browserWindows.length, 1, "Only one window open");
   118   let received = {
   119     listener1: false,
   120     listener2: false,
   121     listener3: false,
   122     listener4: false
   123   }
   125   function listener1() {
   126     assert.equal(this, windows, "The 'this' object is the windows object.");
   128     if (received.listener1)
   129       assert.fail("Event received twice");
   130     received.listener1 = true;
   131   }
   133   function listener2() {
   134     if (received.listener2)
   135       assert.fail("Event received twice");
   136     received.listener2 = true;
   137   }
   139   function listener3() {
   140     assert.equal(this, windows, "The 'this' object is the windows object.");
   141     if (received.listener3)
   142       assert.fail("Event received twice");
   143     received.listener3 = true;
   144   }
   146   function listener4() {
   147     if (received.listener4)
   148       assert.fail("Event received twice");
   149     received.listener4 = true;
   150   }
   152   windows.on('open', listener1);
   153   windows.on('open', listener2);
   154   windows.on('close', listener3);
   155   windows.on('close', listener4);
   157   windows.open({
   158     url: "data:text/html;charset=utf-8,foo",
   159     onOpen: function(window) {
   160       window.close(function() {
   161         assert.ok(received.listener1, "onOpen handler called");
   162         assert.ok(received.listener2, "onOpen handler called");
   163         assert.ok(received.listener3, "onClose handler called");
   164         assert.ok(received.listener4, "onClose handler called");
   166         windows.removeListener('open', listener1);
   167         windows.removeListener('open', listener2);
   168         windows.removeListener('close', listener3);
   169         windows.removeListener('close', listener4);
   171         done();
   172       });
   173     }
   174   });
   175 };
   177 exports.testActiveWindow = function(assert, done) {
   178   let windows = browserWindows;
   180   // API window objects
   181   let window2, window3;
   183   // Raw window objects
   184   let rawWindow2, rawWindow3;
   186   let testSteps = [
   187     function() {
   188       assert.equal(windows.length, 3, "Correct number of browser windows");
   190       let count = 0;
   191       for (let window in windows)
   192         count++;
   193       assert.equal(count, 3, "Correct number of windows returned by iterator");
   195       assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
   197       continueAfterFocus(rawWindow2);
   198       rawWindow2.focus();
   199     },
   200     function() {
   201       assert.equal(windows.activeWindow.title, window2.title, "Correct active window - 2");
   203       continueAfterFocus(rawWindow2);
   204       window2.activate();
   205     },
   206     function() {
   207       assert.equal(windows.activeWindow.title, window2.title, "Correct active window - 2");
   209       continueAfterFocus(rawWindow3);
   210       window3.activate();
   211     },
   212     function() {
   213       assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
   214       finishTest();
   215     }
   216   ];
   218   let newWindow = null;
   219   let tracker = new WindowTracker({
   220     onTrack: function(window) {
   221       newWindow = window;
   222     }
   223   });
   225   windows.open({
   226     url: "data:text/html;charset=utf-8,<title>window 2</title>",
   227     onOpen: function(window) {
   228       assert.pass('window 2 open');
   230       window.tabs.activeTab.on('ready', function() {
   231         assert.pass('window 2 tab activated');
   233         window2 = window;
   234         assert.ok(newWindow, "A new window was opened");
   235         rawWindow2 = newWindow;
   236         newWindow = null;
   238         assert.equal(rawWindow2.content.document.title, "window 2", "Got correct raw window 2");
   239         assert.equal(rawWindow2.document.title, window2.title, "Saw correct title on window 2");
   241         windows.open({
   242           url: "data:text/html;charset=utf-8,<title>window 3</title>",
   243           onOpen: function(window) {
   244             assert.pass('window 3 open');
   246             window.tabs.activeTab.on('ready', function onReady() {
   247               assert.pass('window 3 tab activated');
   249               window3 = window;
   250               assert.ok(newWindow, "A new window was opened");
   251               rawWindow3 = newWindow;
   252               tracker.unload();
   254               assert.equal(rawWindow3.content.document.title, "window 3", "Got correct raw window 3");
   255               assert.equal(rawWindow3.document.title, window3.title, "Saw correct title on window 3");
   257               continueAfterFocus(rawWindow3);
   258               rawWindow3.focus();
   259             });
   260           }
   261         });
   262       });
   263     }
   264   });
   266   function nextStep() {
   267     if (testSteps.length) {
   268       setTimeout(testSteps.shift())
   269     }
   270   }
   272   let continueAfterFocus = function(w) onFocus(w).then(nextStep);
   274   function finishTest() {
   275     // close unactive window first to avoid unnecessary focus changing
   276     window2.close(function() {
   277       window3.close(function() {
   278         assert.equal(rawWindow2.closed, true, 'window 2 is closed');
   279         assert.equal(rawWindow3.closed, true, 'window 3 is closed');
   281         done();
   282       });
   283     });
   284   }
   285 };
   287 exports.testTrackWindows = function(assert, done) {
   288   let windows = [];
   289   let actions = [];
   291   let expects = [
   292     "activate 0", "global activate 0", "deactivate 0", "global deactivate 0",
   293     "activate 1", "global activate 1", "deactivate 1", "global deactivate 1",
   294     "activate 2", "global activate 2"
   295   ];
   297   function windowsActivation(window) {
   298     let index = windows.indexOf(window);
   299     // only concerned with windows opened for this test
   300     if (index < 0)
   301       return;
   303     assert.equal(actions.join(), expects.slice(0, index*4 + 1).join(), expects[index*4 + 1]);
   304     actions.push("global activate " + index)
   305   }
   307   function windowsDeactivation(window) {
   308     let index = windows.indexOf(window);
   309     // only concerned with windows opened for this test
   310     if (index < 0)
   311       return;
   313     assert.equal(actions.join(), expects.slice(0, index*4 + 3).join(), expects[index*4 + 3]);
   314     actions.push("global deactivate " + index)
   315   }
   317   // listen to global activate events
   318   browserWindows.on("activate", windowsActivation);
   320   // listen to global deactivate events
   321   browserWindows.on("deactivate", windowsDeactivation);
   324   function openWindow() {
   325     windows.push(browserWindows.open({
   326       url: "data:text/html;charset=utf-8,<i>testTrackWindows</i>",
   327       onActivate: function(window) {
   328         let index = windows.indexOf(window);
   330         // Guard against windows that have already been removed.
   331         // See bug 874502 comment 32.
   332         if (index == -1)
   333           return;
   335         assert.equal(actions.join(),
   336                      expects.slice(0, index*4).join(),
   337                      "expecting " + expects[index*4]);
   338         actions.push("activate " + index);
   340         if (windows.length < 3) {
   341           openWindow()
   342         }
   343         else {
   344           (function closeWindows(windows) {
   345             if (!windows.length) {
   346               browserWindows.removeListener("activate", windowsActivation);
   347               browserWindows.removeListener("deactivate", windowsDeactivation);
   348               return done();
   349             }
   351             return windows.pop().close(function() {
   352               assert.pass('window was closed');
   353               closeWindows(windows);
   354             });
   355           })(windows)
   356         }
   357       },
   358       onDeactivate: function(window) {
   359         let index = windows.indexOf(window);
   361         // Guard against windows that have already been removed.
   362         // See bug 874502 comment 32.
   363         if (index == -1)
   364           return;
   366         assert.equal(actions.join(),
   367                      expects.slice(0, index*4 + 2).join(),
   368                      "expecting " + expects[index*4 + 2]);
   369         actions.push("deactivate " + index)
   370       }
   371     }));
   372   }
   373   openWindow();
   374 }
   376 // test that it is not possible to open a private window by default
   377 exports.testWindowOpenPrivateDefault = function(assert, done) {
   378   browserWindows.open({
   379     url: 'about:mozilla',
   380     isPrivate: true,
   381     onOpen: function(window) {
   382       let tab = window.tabs[0];
   384       tab.once('ready', function() {
   385         assert.equal(tab.url, 'about:mozilla', 'opened correct tab');
   386         assert.equal(isPrivate(tab), false, 'tab is not private');
   388         window.close(done);
   389       });
   390     }
   391   });
   392 }
   394 // test that it is not possible to find a private window in
   395 // windows module's iterator
   396 exports.testWindowIteratorPrivateDefault = function(assert, done) {
   397   assert.equal(browserWindows.length, 1, 'only one window open');
   399   open('chrome://browser/content/browser.xul', {
   400     features: {
   401       private: true,
   402       chrome: true
   403     }
   404   }).then(focus).then(function(window) {
   405     // test that there is a private window opened
   406     assert.equal(isPrivate(window), isWindowPBSupported, 'there is a private window open');
   407     assert.strictEqual(window, winUtils.activeWindow);
   408     assert.strictEqual(window, getMostRecentWindow());
   410     assert.ok(!isPrivate(browserWindows.activeWindow));
   412     assert.equal(browserWindows.length, 1, 'only one window in browserWindows');
   413     assert.equal(windows().length, 1, 'only one window in windows()');
   415     assert.equal(windows(null, { includePrivate: true }).length, 2);
   417     // test that all windows in iterator are not private
   418     for (let window of browserWindows)
   419       assert.ok(!isPrivate(window), 'no window in browserWindows is private');
   421     close(window).then(done);
   422   });
   423 };
   425 exports["test getView(window)"] = function(assert, done) {
   426   browserWindows.once("open", window => {
   427     const view = viewFor(window);
   429     assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window");
   430     assert.ok(isBrowser(view), "view is a browser window");
   431     assert.equal(getWindowTitle(view), window.title,
   432                  "window has a right title");
   434     window.close();
   435     // Defer handler cause window is destroyed after event is dispatched.
   436     browserWindows.once("close", defer(_ => {
   437       assert.equal(viewFor(window), null, "window view is gone");
   438       done();
   439     }));
   440   });
   442   browserWindows.open({ url: "data:text/html,<title>yo</title>" });
   443 };
   445 require('sdk/test').run(exports);

mercurial