1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-window-utils.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,325 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +module.metadata = { 1.10 + engines: { 1.11 + 'Firefox': '*' 1.12 + } 1.13 +}; 1.14 + 1.15 +const windowUtils = require("sdk/deprecated/window-utils"); 1.16 +const timer = require("sdk/timers"); 1.17 +const { Cc, Ci } = require("chrome"); 1.18 +const { Loader } = require("sdk/test/loader"); 1.19 +const { open, getFrames, getWindowTitle, onFocus, windows } = require('sdk/window/utils'); 1.20 +const { close } = require('sdk/window/helpers'); 1.21 +const { fromIterator: toArray } = require('sdk/util/array'); 1.22 + 1.23 +const WM = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); 1.24 + 1.25 +function makeEmptyWindow(options) { 1.26 + options = options || {}; 1.27 + var xulNs = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; 1.28 + var blankXul = ('<?xml version="1.0"?>' + 1.29 + '<?xml-stylesheet href="chrome://global/skin/" ' + 1.30 + ' type="text/css"?>' + 1.31 + '<window xmlns="' + xulNs + '" windowtype="test:window">' + 1.32 + '</window>'); 1.33 + 1.34 + return open("data:application/vnd.mozilla.xul+xml;charset=utf-8," + escape(blankXul), { 1.35 + features: { 1.36 + chrome: true, 1.37 + width: 10, 1.38 + height: 10 1.39 + } 1.40 + }); 1.41 +} 1.42 + 1.43 +exports['test close on unload'] = function(assert) { 1.44 + var timesClosed = 0; 1.45 + var fakeWindow = { 1.46 + _listeners: [], 1.47 + addEventListener: function(name, func, bool) { 1.48 + this._listeners.push(func); 1.49 + }, 1.50 + removeEventListener: function(name, func, bool) { 1.51 + var index = this._listeners.indexOf(func); 1.52 + if (index == -1) 1.53 + throw new Error("event listener not found"); 1.54 + this._listeners.splice(index, 1); 1.55 + }, 1.56 + close: function() { 1.57 + timesClosed++; 1.58 + this._listeners.forEach( 1.59 + function(func) { 1.60 + func({target: fakeWindow.document}); 1.61 + }); 1.62 + }, 1.63 + document: { 1.64 + get defaultView() { return fakeWindow; } 1.65 + } 1.66 + }; 1.67 + 1.68 + let loader = Loader(module); 1.69 + loader.require("sdk/deprecated/window-utils").closeOnUnload(fakeWindow); 1.70 + assert.equal(fakeWindow._listeners.length, 1, 1.71 + "unload listener added on closeOnUnload()"); 1.72 + assert.equal(timesClosed, 0, 1.73 + "window not closed when registered."); 1.74 + loader.unload(); 1.75 + assert.equal(timesClosed, 1, 1.76 + "window closed on module unload."); 1.77 + assert.equal(fakeWindow._listeners.length, 0, 1.78 + "unload event listener removed on module unload"); 1.79 + 1.80 + timesClosed = 0; 1.81 + loader = Loader(module); 1.82 + loader.require("sdk/deprecated/window-utils").closeOnUnload(fakeWindow); 1.83 + assert.equal(timesClosed, 0, 1.84 + "window not closed when registered."); 1.85 + fakeWindow.close(); 1.86 + assert.equal(timesClosed, 1, 1.87 + "window closed when close() called."); 1.88 + assert.equal(fakeWindow._listeners.length, 0, 1.89 + "unload event listener removed on window close"); 1.90 + loader.unload(); 1.91 + assert.equal(timesClosed, 1, 1.92 + "window not closed again on module unload."); 1.93 +}; 1.94 + 1.95 +exports.testWindowTracker = function(assert, done) { 1.96 + var myWindow; 1.97 + var finished = false; 1.98 + 1.99 + var delegate = { 1.100 + onTrack: function(window) { 1.101 + if (window == myWindow) { 1.102 + assert.pass("onTrack() called with our test window"); 1.103 + timer.setTimeout(function() myWindow.close()); 1.104 + } 1.105 + }, 1.106 + onUntrack: function(window) { 1.107 + if (window == myWindow) { 1.108 + assert.pass("onUntrack() called with our test window"); 1.109 + timer.setTimeout(function() { 1.110 + if (!finished) { 1.111 + finished = true; 1.112 + myWindow = null; 1.113 + wt.unload(); 1.114 + done(); 1.115 + } 1.116 + else { 1.117 + assert.fail("finishTest() called multiple times."); 1.118 + } 1.119 + }); 1.120 + } 1.121 + } 1.122 + }; 1.123 + 1.124 + // test bug 638007 (new is optional), using new 1.125 + var wt = new windowUtils.WindowTracker(delegate); 1.126 + myWindow = makeEmptyWindow(); 1.127 +}; 1.128 + 1.129 +exports['test window watcher untracker'] = function(assert, done) { 1.130 + var myWindow; 1.131 + var tracks = 0; 1.132 + var unloadCalled = false; 1.133 + 1.134 + var delegate = { 1.135 + onTrack: function(window) { 1.136 + tracks = tracks + 1; 1.137 + if (window == myWindow) { 1.138 + assert.pass("onTrack() called with our test window"); 1.139 + timer.setTimeout(function() { 1.140 + myWindow.close(); 1.141 + }, 1); 1.142 + } 1.143 + }, 1.144 + onUntrack: function(window) { 1.145 + tracks = tracks - 1; 1.146 + if (window == myWindow && !unloadCalled) { 1.147 + unloadCalled = true; 1.148 + timer.setTimeout(function() { 1.149 + wt.unload(); 1.150 + }, 1); 1.151 + } 1.152 + if (0 > tracks) { 1.153 + assert.fail("WindowTracker onUntrack was called more times than onTrack.."); 1.154 + } 1.155 + else if (0 == tracks) { 1.156 + timer.setTimeout(function() { 1.157 + myWindow = null; 1.158 + done(); 1.159 + }, 1); 1.160 + } 1.161 + } 1.162 + }; 1.163 + 1.164 + // test bug 638007 (new is optional), not using new 1.165 + var wt = windowUtils.WindowTracker(delegate); 1.166 + myWindow = makeEmptyWindow(); 1.167 +}; 1.168 + 1.169 +// test that _unregWindow calls _unregLoadingWindow 1.170 +exports['test window watcher unregs 4 loading wins'] = function(assert, done) { 1.171 + var myWindow; 1.172 + var finished = false; 1.173 + let browserWindow = WM.getMostRecentWindow("navigator:browser"); 1.174 + var counter = 0; 1.175 + 1.176 + var delegate = { 1.177 + onTrack: function(window) { 1.178 + var type = window.document.documentElement.getAttribute("windowtype"); 1.179 + if (type == "test:window") 1.180 + assert.fail("onTrack shouldn't have been executed."); 1.181 + } 1.182 + }; 1.183 + var wt = new windowUtils.WindowTracker(delegate); 1.184 + 1.185 + // make a new window 1.186 + myWindow = makeEmptyWindow(); 1.187 + 1.188 + // make sure that the window hasn't loaded yet 1.189 + assert.notEqual( 1.190 + myWindow.document.readyState, 1.191 + "complete", 1.192 + "window hasn't loaded yet."); 1.193 + 1.194 + // unload WindowTracker 1.195 + wt.unload(); 1.196 + 1.197 + // make sure that the window still hasn't loaded, which means that the onTrack 1.198 + // would have been removed successfully assuming that it doesn't execute. 1.199 + assert.notEqual( 1.200 + myWindow.document.readyState, 1.201 + "complete", 1.202 + "window still hasn't loaded yet."); 1.203 + 1.204 + // wait for the window to load and then close it. onTrack wouldn't be called 1.205 + // until the window loads, so we must let it load before closing it to be 1.206 + // certain that onTrack was removed. 1.207 + myWindow.addEventListener("load", function() { 1.208 + // allow all of the load handles to execute before closing 1.209 + myWindow.setTimeout(function() { 1.210 + myWindow.addEventListener("unload", function() { 1.211 + // once the window unloads test is done 1.212 + done(); 1.213 + }, false); 1.214 + myWindow.close(); 1.215 + }, 0); 1.216 + }, false); 1.217 +} 1.218 + 1.219 +exports['test window watcher without untracker'] = function(assert, done) { 1.220 + let myWindow; 1.221 + let wt = new windowUtils.WindowTracker({ 1.222 + onTrack: function(window) { 1.223 + if (window == myWindow) { 1.224 + assert.pass("onTrack() called with our test window"); 1.225 + 1.226 + close(myWindow).then(function() { 1.227 + wt.unload(); 1.228 + done(); 1.229 + }, assert.fail); 1.230 + } 1.231 + } 1.232 + }); 1.233 + 1.234 + myWindow = makeEmptyWindow(); 1.235 +}; 1.236 + 1.237 +exports['test active window'] = function(assert, done) { 1.238 + let browserWindow = WM.getMostRecentWindow("navigator:browser"); 1.239 + let continueAfterFocus = function(window) onFocus(window).then(nextTest); 1.240 + 1.241 + assert.equal(windowUtils.activeBrowserWindow, browserWindow, 1.242 + "Browser window is the active browser window."); 1.243 + 1.244 + 1.245 + let testSteps = [ 1.246 + function() { 1.247 + continueAfterFocus(windowUtils.activeWindow = browserWindow); 1.248 + }, 1.249 + function() { 1.250 + assert.equal(windowUtils.activeWindow, browserWindow, 1.251 + "Correct active window [1]"); 1.252 + nextTest(); 1.253 + }, 1.254 + function() { 1.255 + assert.equal(windowUtils.activeBrowserWindow, browserWindow, 1.256 + "Correct active browser window [2]"); 1.257 + continueAfterFocus(windowUtils.activeWindow = browserWindow); 1.258 + }, 1.259 + function() { 1.260 + assert.equal(windowUtils.activeWindow, browserWindow, 1.261 + "Correct active window [3]"); 1.262 + nextTest(); 1.263 + }, 1.264 + function() { 1.265 + assert.equal(windowUtils.activeBrowserWindow, browserWindow, 1.266 + "Correct active browser window [4]"); 1.267 + done(); 1.268 + } 1.269 + ]; 1.270 + 1.271 + function nextTest() { 1.272 + if (testSteps.length) 1.273 + testSteps.shift()(); 1.274 + } 1.275 + nextTest(); 1.276 +}; 1.277 + 1.278 +exports.testWindowIterator = function(assert, done) { 1.279 + // make a new window 1.280 + let window = makeEmptyWindow(); 1.281 + 1.282 + // make sure that the window hasn't loaded yet 1.283 + assert.notEqual( 1.284 + window.document.readyState, 1.285 + "complete", 1.286 + "window hasn't loaded yet."); 1.287 + 1.288 + // this window should only appear in windowIterator() while its loading 1.289 + assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) === -1, 1.290 + "window isn't in windowIterator()"); 1.291 + 1.292 + // Then it should be in windowIterator() 1.293 + window.addEventListener("load", function onload() { 1.294 + window.addEventListener("load", onload, false); 1.295 + assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) !== -1, 1.296 + "window is now in windowIterator()"); 1.297 + 1.298 + // Wait for the window unload before ending test 1.299 + close(window).then(done); 1.300 + }, false); 1.301 +}; 1.302 + 1.303 +exports.testIgnoreClosingWindow = function(assert, done) { 1.304 + assert.equal(windows().length, 1, "Only one window open"); 1.305 + 1.306 + // make a new window 1.307 + let window = makeEmptyWindow(); 1.308 + 1.309 + assert.equal(windows().length, 2, "Two windows open"); 1.310 + 1.311 + window.addEventListener("load", function onload() { 1.312 + window.addEventListener("load", onload, false); 1.313 + 1.314 + assert.equal(windows().length, 2, "Two windows open"); 1.315 + 1.316 + // Wait for the window unload before ending test 1.317 + let checked = false; 1.318 + 1.319 + close(window).then(function() { 1.320 + assert.ok(checked, 'the test is finished'); 1.321 + }).then(done, assert.fail) 1.322 + 1.323 + assert.equal(windows().length, 1, "Only one window open"); 1.324 + checked = true; 1.325 + }, false); 1.326 +}; 1.327 + 1.328 +require("test").run(exports);