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