addon-sdk/source/test/test-window-utils.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.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 "use strict";
michael@0 5
michael@0 6 module.metadata = {
michael@0 7 engines: {
michael@0 8 'Firefox': '*'
michael@0 9 }
michael@0 10 };
michael@0 11
michael@0 12 const windowUtils = require("sdk/deprecated/window-utils");
michael@0 13 const timer = require("sdk/timers");
michael@0 14 const { Cc, Ci } = require("chrome");
michael@0 15 const { Loader } = require("sdk/test/loader");
michael@0 16 const { open, getFrames, getWindowTitle, onFocus, windows } = require('sdk/window/utils');
michael@0 17 const { close } = require('sdk/window/helpers');
michael@0 18 const { fromIterator: toArray } = require('sdk/util/array');
michael@0 19
michael@0 20 const WM = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
michael@0 21
michael@0 22 function makeEmptyWindow(options) {
michael@0 23 options = options || {};
michael@0 24 var xulNs = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
michael@0 25 var blankXul = ('<?xml version="1.0"?>' +
michael@0 26 '<?xml-stylesheet href="chrome://global/skin/" ' +
michael@0 27 ' type="text/css"?>' +
michael@0 28 '<window xmlns="' + xulNs + '" windowtype="test:window">' +
michael@0 29 '</window>');
michael@0 30
michael@0 31 return open("data:application/vnd.mozilla.xul+xml;charset=utf-8," + escape(blankXul), {
michael@0 32 features: {
michael@0 33 chrome: true,
michael@0 34 width: 10,
michael@0 35 height: 10
michael@0 36 }
michael@0 37 });
michael@0 38 }
michael@0 39
michael@0 40 exports['test close on unload'] = function(assert) {
michael@0 41 var timesClosed = 0;
michael@0 42 var fakeWindow = {
michael@0 43 _listeners: [],
michael@0 44 addEventListener: function(name, func, bool) {
michael@0 45 this._listeners.push(func);
michael@0 46 },
michael@0 47 removeEventListener: function(name, func, bool) {
michael@0 48 var index = this._listeners.indexOf(func);
michael@0 49 if (index == -1)
michael@0 50 throw new Error("event listener not found");
michael@0 51 this._listeners.splice(index, 1);
michael@0 52 },
michael@0 53 close: function() {
michael@0 54 timesClosed++;
michael@0 55 this._listeners.forEach(
michael@0 56 function(func) {
michael@0 57 func({target: fakeWindow.document});
michael@0 58 });
michael@0 59 },
michael@0 60 document: {
michael@0 61 get defaultView() { return fakeWindow; }
michael@0 62 }
michael@0 63 };
michael@0 64
michael@0 65 let loader = Loader(module);
michael@0 66 loader.require("sdk/deprecated/window-utils").closeOnUnload(fakeWindow);
michael@0 67 assert.equal(fakeWindow._listeners.length, 1,
michael@0 68 "unload listener added on closeOnUnload()");
michael@0 69 assert.equal(timesClosed, 0,
michael@0 70 "window not closed when registered.");
michael@0 71 loader.unload();
michael@0 72 assert.equal(timesClosed, 1,
michael@0 73 "window closed on module unload.");
michael@0 74 assert.equal(fakeWindow._listeners.length, 0,
michael@0 75 "unload event listener removed on module unload");
michael@0 76
michael@0 77 timesClosed = 0;
michael@0 78 loader = Loader(module);
michael@0 79 loader.require("sdk/deprecated/window-utils").closeOnUnload(fakeWindow);
michael@0 80 assert.equal(timesClosed, 0,
michael@0 81 "window not closed when registered.");
michael@0 82 fakeWindow.close();
michael@0 83 assert.equal(timesClosed, 1,
michael@0 84 "window closed when close() called.");
michael@0 85 assert.equal(fakeWindow._listeners.length, 0,
michael@0 86 "unload event listener removed on window close");
michael@0 87 loader.unload();
michael@0 88 assert.equal(timesClosed, 1,
michael@0 89 "window not closed again on module unload.");
michael@0 90 };
michael@0 91
michael@0 92 exports.testWindowTracker = function(assert, done) {
michael@0 93 var myWindow;
michael@0 94 var finished = false;
michael@0 95
michael@0 96 var delegate = {
michael@0 97 onTrack: function(window) {
michael@0 98 if (window == myWindow) {
michael@0 99 assert.pass("onTrack() called with our test window");
michael@0 100 timer.setTimeout(function() myWindow.close());
michael@0 101 }
michael@0 102 },
michael@0 103 onUntrack: function(window) {
michael@0 104 if (window == myWindow) {
michael@0 105 assert.pass("onUntrack() called with our test window");
michael@0 106 timer.setTimeout(function() {
michael@0 107 if (!finished) {
michael@0 108 finished = true;
michael@0 109 myWindow = null;
michael@0 110 wt.unload();
michael@0 111 done();
michael@0 112 }
michael@0 113 else {
michael@0 114 assert.fail("finishTest() called multiple times.");
michael@0 115 }
michael@0 116 });
michael@0 117 }
michael@0 118 }
michael@0 119 };
michael@0 120
michael@0 121 // test bug 638007 (new is optional), using new
michael@0 122 var wt = new windowUtils.WindowTracker(delegate);
michael@0 123 myWindow = makeEmptyWindow();
michael@0 124 };
michael@0 125
michael@0 126 exports['test window watcher untracker'] = function(assert, done) {
michael@0 127 var myWindow;
michael@0 128 var tracks = 0;
michael@0 129 var unloadCalled = false;
michael@0 130
michael@0 131 var delegate = {
michael@0 132 onTrack: function(window) {
michael@0 133 tracks = tracks + 1;
michael@0 134 if (window == myWindow) {
michael@0 135 assert.pass("onTrack() called with our test window");
michael@0 136 timer.setTimeout(function() {
michael@0 137 myWindow.close();
michael@0 138 }, 1);
michael@0 139 }
michael@0 140 },
michael@0 141 onUntrack: function(window) {
michael@0 142 tracks = tracks - 1;
michael@0 143 if (window == myWindow && !unloadCalled) {
michael@0 144 unloadCalled = true;
michael@0 145 timer.setTimeout(function() {
michael@0 146 wt.unload();
michael@0 147 }, 1);
michael@0 148 }
michael@0 149 if (0 > tracks) {
michael@0 150 assert.fail("WindowTracker onUntrack was called more times than onTrack..");
michael@0 151 }
michael@0 152 else if (0 == tracks) {
michael@0 153 timer.setTimeout(function() {
michael@0 154 myWindow = null;
michael@0 155 done();
michael@0 156 }, 1);
michael@0 157 }
michael@0 158 }
michael@0 159 };
michael@0 160
michael@0 161 // test bug 638007 (new is optional), not using new
michael@0 162 var wt = windowUtils.WindowTracker(delegate);
michael@0 163 myWindow = makeEmptyWindow();
michael@0 164 };
michael@0 165
michael@0 166 // test that _unregWindow calls _unregLoadingWindow
michael@0 167 exports['test window watcher unregs 4 loading wins'] = function(assert, done) {
michael@0 168 var myWindow;
michael@0 169 var finished = false;
michael@0 170 let browserWindow = WM.getMostRecentWindow("navigator:browser");
michael@0 171 var counter = 0;
michael@0 172
michael@0 173 var delegate = {
michael@0 174 onTrack: function(window) {
michael@0 175 var type = window.document.documentElement.getAttribute("windowtype");
michael@0 176 if (type == "test:window")
michael@0 177 assert.fail("onTrack shouldn't have been executed.");
michael@0 178 }
michael@0 179 };
michael@0 180 var wt = new windowUtils.WindowTracker(delegate);
michael@0 181
michael@0 182 // make a new window
michael@0 183 myWindow = makeEmptyWindow();
michael@0 184
michael@0 185 // make sure that the window hasn't loaded yet
michael@0 186 assert.notEqual(
michael@0 187 myWindow.document.readyState,
michael@0 188 "complete",
michael@0 189 "window hasn't loaded yet.");
michael@0 190
michael@0 191 // unload WindowTracker
michael@0 192 wt.unload();
michael@0 193
michael@0 194 // make sure that the window still hasn't loaded, which means that the onTrack
michael@0 195 // would have been removed successfully assuming that it doesn't execute.
michael@0 196 assert.notEqual(
michael@0 197 myWindow.document.readyState,
michael@0 198 "complete",
michael@0 199 "window still hasn't loaded yet.");
michael@0 200
michael@0 201 // wait for the window to load and then close it. onTrack wouldn't be called
michael@0 202 // until the window loads, so we must let it load before closing it to be
michael@0 203 // certain that onTrack was removed.
michael@0 204 myWindow.addEventListener("load", function() {
michael@0 205 // allow all of the load handles to execute before closing
michael@0 206 myWindow.setTimeout(function() {
michael@0 207 myWindow.addEventListener("unload", function() {
michael@0 208 // once the window unloads test is done
michael@0 209 done();
michael@0 210 }, false);
michael@0 211 myWindow.close();
michael@0 212 }, 0);
michael@0 213 }, false);
michael@0 214 }
michael@0 215
michael@0 216 exports['test window watcher without untracker'] = function(assert, done) {
michael@0 217 let myWindow;
michael@0 218 let wt = new windowUtils.WindowTracker({
michael@0 219 onTrack: function(window) {
michael@0 220 if (window == myWindow) {
michael@0 221 assert.pass("onTrack() called with our test window");
michael@0 222
michael@0 223 close(myWindow).then(function() {
michael@0 224 wt.unload();
michael@0 225 done();
michael@0 226 }, assert.fail);
michael@0 227 }
michael@0 228 }
michael@0 229 });
michael@0 230
michael@0 231 myWindow = makeEmptyWindow();
michael@0 232 };
michael@0 233
michael@0 234 exports['test active window'] = function(assert, done) {
michael@0 235 let browserWindow = WM.getMostRecentWindow("navigator:browser");
michael@0 236 let continueAfterFocus = function(window) onFocus(window).then(nextTest);
michael@0 237
michael@0 238 assert.equal(windowUtils.activeBrowserWindow, browserWindow,
michael@0 239 "Browser window is the active browser window.");
michael@0 240
michael@0 241
michael@0 242 let testSteps = [
michael@0 243 function() {
michael@0 244 continueAfterFocus(windowUtils.activeWindow = browserWindow);
michael@0 245 },
michael@0 246 function() {
michael@0 247 assert.equal(windowUtils.activeWindow, browserWindow,
michael@0 248 "Correct active window [1]");
michael@0 249 nextTest();
michael@0 250 },
michael@0 251 function() {
michael@0 252 assert.equal(windowUtils.activeBrowserWindow, browserWindow,
michael@0 253 "Correct active browser window [2]");
michael@0 254 continueAfterFocus(windowUtils.activeWindow = browserWindow);
michael@0 255 },
michael@0 256 function() {
michael@0 257 assert.equal(windowUtils.activeWindow, browserWindow,
michael@0 258 "Correct active window [3]");
michael@0 259 nextTest();
michael@0 260 },
michael@0 261 function() {
michael@0 262 assert.equal(windowUtils.activeBrowserWindow, browserWindow,
michael@0 263 "Correct active browser window [4]");
michael@0 264 done();
michael@0 265 }
michael@0 266 ];
michael@0 267
michael@0 268 function nextTest() {
michael@0 269 if (testSteps.length)
michael@0 270 testSteps.shift()();
michael@0 271 }
michael@0 272 nextTest();
michael@0 273 };
michael@0 274
michael@0 275 exports.testWindowIterator = function(assert, done) {
michael@0 276 // make a new window
michael@0 277 let window = makeEmptyWindow();
michael@0 278
michael@0 279 // make sure that the window hasn't loaded yet
michael@0 280 assert.notEqual(
michael@0 281 window.document.readyState,
michael@0 282 "complete",
michael@0 283 "window hasn't loaded yet.");
michael@0 284
michael@0 285 // this window should only appear in windowIterator() while its loading
michael@0 286 assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) === -1,
michael@0 287 "window isn't in windowIterator()");
michael@0 288
michael@0 289 // Then it should be in windowIterator()
michael@0 290 window.addEventListener("load", function onload() {
michael@0 291 window.addEventListener("load", onload, false);
michael@0 292 assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) !== -1,
michael@0 293 "window is now in windowIterator()");
michael@0 294
michael@0 295 // Wait for the window unload before ending test
michael@0 296 close(window).then(done);
michael@0 297 }, false);
michael@0 298 };
michael@0 299
michael@0 300 exports.testIgnoreClosingWindow = function(assert, done) {
michael@0 301 assert.equal(windows().length, 1, "Only one window open");
michael@0 302
michael@0 303 // make a new window
michael@0 304 let window = makeEmptyWindow();
michael@0 305
michael@0 306 assert.equal(windows().length, 2, "Two windows open");
michael@0 307
michael@0 308 window.addEventListener("load", function onload() {
michael@0 309 window.addEventListener("load", onload, false);
michael@0 310
michael@0 311 assert.equal(windows().length, 2, "Two windows open");
michael@0 312
michael@0 313 // Wait for the window unload before ending test
michael@0 314 let checked = false;
michael@0 315
michael@0 316 close(window).then(function() {
michael@0 317 assert.ok(checked, 'the test is finished');
michael@0 318 }).then(done, assert.fail)
michael@0 319
michael@0 320 assert.equal(windows().length, 1, "Only one window open");
michael@0 321 checked = true;
michael@0 322 }, false);
michael@0 323 };
michael@0 324
michael@0 325 require("test").run(exports);

mercurial