browser/components/sessionstore/test/browser_615394-SSWindowState_events.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:82674f065f3c
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
5 const stateBackup = JSON.parse(ss.getBrowserState());
6 const testState = {
7 windows: [{
8 tabs: [
9 { entries: [{ url: "about:blank" }] },
10 { entries: [{ url: "about:rights" }] }
11 ]
12 }]
13 };
14 const lameMultiWindowState = { windows: [
15 {
16 tabs: [
17 { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
18 { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } },
19 { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } },
20 { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }
21 ],
22 selected: 1
23 },
24 {
25 tabs: [
26 { entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
27 { entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
28 { entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
29 { entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
30 ],
31 selected: 3
32 }
33 ] };
34
35
36 function getOuterWindowID(aWindow) {
37 return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
38 getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
39 }
40
41 function test() {
42 /** Test for Bug 615394 - Session Restore should notify when it is beginning and ending a restore **/
43 waitForExplicitFinish();
44 // Preemptively extend the timeout to prevent [orange]
45 requestLongerTimeout(2);
46 runNextTest();
47 }
48
49
50 let tests = [
51 test_setTabState,
52 test_duplicateTab,
53 test_undoCloseTab,
54 test_setWindowState,
55 test_setBrowserState,
56 test_undoCloseWindow
57 ];
58 function runNextTest() {
59 // set an empty state & run the next test, or finish
60 if (tests.length) {
61 // Enumerate windows and close everything but our primary window. We can't
62 // use waitForFocus() because apparently it's buggy. See bug 599253.
63 var windowsEnum = Services.wm.getEnumerator("navigator:browser");
64 while (windowsEnum.hasMoreElements()) {
65 var currentWindow = windowsEnum.getNext();
66 if (currentWindow != window) {
67 currentWindow.close();
68 }
69 }
70
71 // If we closed a window, give it time to close
72 executeSoon(function() {
73 let currentTest = tests.shift();
74 info("prepping for " + currentTest.name);
75 waitForBrowserState(testState, currentTest);
76 });
77 }
78 else {
79 waitForBrowserState(stateBackup, finish);
80 }
81 }
82
83 /** ACTUAL TESTS **/
84
85 function test_setTabState() {
86 let tab = gBrowser.tabs[1];
87 let newTabState = JSON.stringify({ entries: [{ url: "http://example.org" }], extData: { foo: "bar" } });
88 let busyEventCount = 0;
89 let readyEventCount = 0;
90
91 function onSSWindowStateBusy(aEvent) {
92 busyEventCount++;
93 }
94
95 function onSSWindowStateReady(aEvent) {
96 readyEventCount++;
97 is(ss.getTabValue(tab, "foo"), "bar");
98 ss.setTabValue(tab, "baz", "qux");
99 }
100
101 function onSSTabRestored(aEvent) {
102 is(busyEventCount, 1);
103 is(readyEventCount, 1);
104 is(ss.getTabValue(tab, "baz"), "qux");
105 is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
106
107 window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
108 window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
109 gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
110
111 runNextTest();
112 }
113
114 window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
115 window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
116 gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
117 ss.setTabState(tab, newTabState);
118 }
119
120
121 function test_duplicateTab() {
122 let tab = gBrowser.tabs[1];
123 let busyEventCount = 0;
124 let readyEventCount = 0;
125 let newTab;
126
127 // We'll look to make sure this value is on the duplicated tab
128 ss.setTabValue(tab, "foo", "bar");
129
130 function onSSWindowStateBusy(aEvent) {
131 busyEventCount++;
132 }
133
134 function onSSWindowStateReady(aEvent) {
135 newTab = gBrowser.tabs[2];
136 readyEventCount++;
137 is(ss.getTabValue(newTab, "foo"), "bar");
138 ss.setTabValue(newTab, "baz", "qux");
139 }
140
141 function onSSTabRestored(aEvent) {
142 is(busyEventCount, 1);
143 is(readyEventCount, 1);
144 is(ss.getTabValue(newTab, "baz"), "qux");
145 is(newTab.linkedBrowser.currentURI.spec, "about:rights");
146
147 window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
148 window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
149 gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
150
151 runNextTest();
152 }
153
154 window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
155 window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
156 gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
157
158 newTab = ss.duplicateTab(window, tab);
159 }
160
161
162 function test_undoCloseTab() {
163 let tab = gBrowser.tabs[1],
164 busyEventCount = 0,
165 readyEventCount = 0,
166 reopenedTab;
167
168 ss.setTabValue(tab, "foo", "bar");
169
170 function onSSWindowStateBusy(aEvent) {
171 busyEventCount++;
172 }
173
174 function onSSWindowStateReady(aEvent) {
175 reopenedTab = gBrowser.tabs[1];
176 readyEventCount++;
177 is(ss.getTabValue(reopenedTab, "foo"), "bar");
178 ss.setTabValue(reopenedTab, "baz", "qux");
179 }
180
181 function onSSTabRestored(aEvent) {
182 is(busyEventCount, 1);
183 is(readyEventCount, 1);
184 is(ss.getTabValue(reopenedTab, "baz"), "qux");
185 is(reopenedTab.linkedBrowser.currentURI.spec, "about:rights");
186
187 window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
188 window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
189 gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
190
191 runNextTest();
192 }
193
194 window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
195 window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
196 gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
197
198 gBrowser.removeTab(tab);
199 reopenedTab = ss.undoCloseTab(window, 0);
200 }
201
202
203 function test_setWindowState() {
204 let testState = {
205 windows: [{
206 tabs: [
207 { entries: [{ url: "about:mozilla" }], extData: { "foo": "bar" } },
208 { entries: [{ url: "http://example.org" }], extData: { "baz": "qux" } }
209 ]
210 }]
211 };
212
213 let busyEventCount = 0,
214 readyEventCount = 0,
215 tabRestoredCount = 0;
216
217 function onSSWindowStateBusy(aEvent) {
218 busyEventCount++;
219 }
220
221 function onSSWindowStateReady(aEvent) {
222 readyEventCount++;
223 is(ss.getTabValue(gBrowser.tabs[0], "foo"), "bar");
224 is(ss.getTabValue(gBrowser.tabs[1], "baz"), "qux");
225 }
226
227 function onSSTabRestored(aEvent) {
228 if (++tabRestoredCount < 2)
229 return;
230
231 is(busyEventCount, 1);
232 is(readyEventCount, 1);
233 is(gBrowser.tabs[0].linkedBrowser.currentURI.spec, "about:mozilla");
234 is(gBrowser.tabs[1].linkedBrowser.currentURI.spec, "http://example.org/");
235
236 window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
237 window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
238 gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
239
240 runNextTest();
241 }
242
243 window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
244 window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
245 gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
246
247 ss.setWindowState(window, JSON.stringify(testState), true);
248 }
249
250
251 function test_setBrowserState() {
252 // We'll track events per window so we are sure that they are each happening once
253 // pre window.
254 let windowEvents = {};
255 windowEvents[getOuterWindowID(window)] = { busyEventCount: 0, readyEventCount: 0 };
256
257 // waitForBrowserState does it's own observing for windows, but doesn't attach
258 // the listeners we want here, so do it ourselves.
259 let newWindow;
260 function windowObserver(aSubject, aTopic, aData) {
261 if (aTopic == "domwindowopened") {
262 newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
263 newWindow.addEventListener("load", function() {
264 newWindow.removeEventListener("load", arguments.callee, false);
265
266 Services.ww.unregisterNotification(windowObserver);
267
268 windowEvents[getOuterWindowID(newWindow)] = { busyEventCount: 0, readyEventCount: 0 };
269
270 newWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
271 newWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
272 }, false);
273 }
274 }
275
276 function onSSWindowStateBusy(aEvent) {
277 windowEvents[getOuterWindowID(aEvent.originalTarget)].busyEventCount++;
278 }
279
280 function onSSWindowStateReady(aEvent) {
281 windowEvents[getOuterWindowID(aEvent.originalTarget)].readyEventCount++;
282 }
283
284 window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
285 window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
286 Services.ww.registerNotification(windowObserver);
287
288 waitForBrowserState(lameMultiWindowState, function() {
289 let checkedWindows = 0;
290 for (let id of Object.keys(windowEvents)) {
291 let winEvents = windowEvents[id];
292 is(winEvents.busyEventCount, 1,
293 "[test_setBrowserState] window" + id + " busy event count correct");
294 is(winEvents.readyEventCount, 1,
295 "[test_setBrowserState] window" + id + " ready event count correct");
296 checkedWindows++;
297 }
298 is(checkedWindows, 2,
299 "[test_setBrowserState] checked 2 windows");
300 window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
301 window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
302 newWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
303 newWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
304 runNextTest();
305 });
306 }
307
308
309 function test_undoCloseWindow() {
310 let newWindow, reopenedWindow;
311
312 function firstWindowObserver(aSubject, aTopic, aData) {
313 if (aTopic == "domwindowopened") {
314 newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
315 Services.ww.unregisterNotification(firstWindowObserver);
316 }
317 }
318 Services.ww.registerNotification(firstWindowObserver);
319
320 waitForBrowserState(lameMultiWindowState, function() {
321 // Close the window which isn't window
322 newWindow.close();
323 // Now give it time to close
324 executeSoon(function() {
325 reopenedWindow = ss.undoCloseWindow(0);
326 reopenedWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
327 reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
328
329 reopenedWindow.addEventListener("load", function() {
330 reopenedWindow.removeEventListener("load", arguments.callee, false);
331
332 reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
333 }, false);
334 });
335 });
336
337 let busyEventCount = 0,
338 readyEventCount = 0,
339 tabRestoredCount = 0;
340 // These will listen to the reopened closed window...
341 function onSSWindowStateBusy(aEvent) {
342 busyEventCount++;
343 }
344
345 function onSSWindowStateReady(aEvent) {
346 readyEventCount++;
347 }
348
349 function onSSTabRestored(aEvent) {
350 if (++tabRestoredCount < 4)
351 return;
352
353 is(busyEventCount, 1);
354 is(readyEventCount, 1);
355
356 reopenedWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
357 reopenedWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
358 reopenedWindow.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
359
360 reopenedWindow.close();
361
362 // Give it time to close
363 executeSoon(runNextTest);
364 }
365 }

mercurial