browser/components/sessionstore/test/browser_354894_perwindowpb.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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
michael@0 5 /**
michael@0 6 * Checks that restoring the last browser window in session is actually
michael@0 7 * working:
michael@0 8 * 1.1) Open a new browser window
michael@0 9 * 1.2) Add some tabs
michael@0 10 * 1.3) Close that window
michael@0 11 * 1.4) Opening another window
michael@0 12 * --> State is restored
michael@0 13 *
michael@0 14 * 2.1) Open a new browser window
michael@0 15 * 2.2) Add some tabs
michael@0 16 * 2.3) Enter private browsing mode
michael@0 17 * 2.4) Close the window while still in private browsing mode
michael@0 18 * 2.5) Opening a new window
michael@0 19 * --> State is not restored, because private browsing mode is still active
michael@0 20 * 2.6) Leaving private browsing mode
michael@0 21 * 2.7) Open another window
michael@0 22 * --> State (that was before entering PBM) is restored
michael@0 23 *
michael@0 24 * 3.1) Open a new browser window
michael@0 25 * 3.2) Add some tabs
michael@0 26 * 3.4) Open some popups
michael@0 27 * 3.5) Add another tab to one popup (so that it gets stored) and close it again
michael@0 28 * 3.5) Close the browser window
michael@0 29 * 3.6) Open another browser window
michael@0 30 * --> State of the closed browser window, but not of the popup, is restored
michael@0 31 *
michael@0 32 * 4.1) Open a popup
michael@0 33 * 4.2) Add another tab to the popup (so that it gets stored) and close it again
michael@0 34 * 4.3) Open a window
michael@0 35 * --> Nothing at all should be restored
michael@0 36 *
michael@0 37 * 5.1) Open two browser windows and close them again
michael@0 38 * 5.2) undoCloseWindow() one
michael@0 39 * 5.3) Open another browser window
michael@0 40 * --> Nothing at all should be restored
michael@0 41 *
michael@0 42 * Checks the new notifications are correctly posted and processed, that is
michael@0 43 * for each successful -requested a -granted is received, but omitted if
michael@0 44 * -requested was cnceled
michael@0 45 * Said notifications are:
michael@0 46 * - browser-lastwindow-close-requested
michael@0 47 * - browser-lastwindow-close-granted
michael@0 48 * Tests are:
michael@0 49 * 6) Cancel closing when first observe a -requested
michael@0 50 * --> Window is kept open
michael@0 51 * 7) Count the number of notifications
michael@0 52 * --> count(-requested) == count(-granted) + 1
michael@0 53 * --> (The first -requested was canceled, so off-by-one)
michael@0 54 * 8) (Mac only) Mac version of Test 5 additionally preparing Test 6
michael@0 55 *
michael@0 56 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=354894
michael@0 57 * @note It is implicitly tested that restoring the last window works when
michael@0 58 * non-browser windows are around. The "Run Tests" window as well as the main
michael@0 59 * browser window (wherein the test code gets executed) won't be considered
michael@0 60 * browser windows. To achiveve this said main browser window has it's windowtype
michael@0 61 * attribute modified so that it's not considered a browser window any longer.
michael@0 62 * This is crucial, because otherwise there would be two browser windows around,
michael@0 63 * said main test window and the one opened by the tests, and hence the new
michael@0 64 * logic wouldn't be executed at all.
michael@0 65 * @note Mac only tests the new notifications, as restoring the last window is
michael@0 66 * not enabled on that platform (platform shim; the application is kept running
michael@0 67 * although there are no windows left)
michael@0 68 * @note There is a difference when closing a browser window with
michael@0 69 * BrowserTryToCloseWindow() as opposed to close(). The former will make
michael@0 70 * nsSessionStore restore a window next time it gets a chance and will post
michael@0 71 * notifications. The latter won't.
michael@0 72 */
michael@0 73
michael@0 74 function browserWindowsCount(expected, msg) {
michael@0 75 if (typeof expected == "number")
michael@0 76 expected = [expected, expected];
michael@0 77 let count = 0;
michael@0 78 let e = Services.wm.getEnumerator("navigator:browser");
michael@0 79 while (e.hasMoreElements()) {
michael@0 80 if (!e.getNext().closed)
michael@0 81 ++count;
michael@0 82 }
michael@0 83 is(count, expected[0], msg + " (nsIWindowMediator)");
michael@0 84 let state = ss.getBrowserState();
michael@0 85 is(JSON.parse(state).windows.length, expected[1], msg + " (getBrowserState)");
michael@0 86 }
michael@0 87
michael@0 88 function test() {
michael@0 89 browserWindowsCount(1, "Only one browser window should be open initially");
michael@0 90
michael@0 91 waitForExplicitFinish();
michael@0 92 // This test takes some time to run, and it could timeout randomly.
michael@0 93 // So we require a longer timeout. See bug 528219.
michael@0 94 requestLongerTimeout(2);
michael@0 95
michael@0 96 // Some urls that might be opened in tabs and/or popups
michael@0 97 // Do not use about:blank:
michael@0 98 // That one is reserved for special purposes in the tests
michael@0 99 const TEST_URLS = ["about:mozilla", "about:buildconfig"];
michael@0 100
michael@0 101 // Number of -request notifications to except
michael@0 102 // remember to adjust when adding new tests
michael@0 103 const NOTIFICATIONS_EXPECTED = 6;
michael@0 104
michael@0 105 // Window features of popup windows
michael@0 106 const POPUP_FEATURES = "toolbar=no,resizable=no,status=no";
michael@0 107
michael@0 108 // Window features of browser windows
michael@0 109 const CHROME_FEATURES = "chrome,all,dialog=no";
michael@0 110
michael@0 111 // Store the old window type for cleanup
michael@0 112 let oldWinType = "";
michael@0 113 // Store the old tabs.warnOnClose pref so that we may reset it during
michael@0 114 // cleanup
michael@0 115 let oldWarnTabsOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
michael@0 116
michael@0 117 // Observe these, and also use to count the number of hits
michael@0 118 let observing = {
michael@0 119 "browser-lastwindow-close-requested": 0,
michael@0 120 "browser-lastwindow-close-granted": 0
michael@0 121 };
michael@0 122
michael@0 123 /**
michael@0 124 * Helper: Will observe and handle the notifications for us
michael@0 125 */
michael@0 126 let hitCount = 0;
michael@0 127 function observer(aCancel, aTopic, aData) {
michael@0 128 // count so that we later may compare
michael@0 129 observing[aTopic]++;
michael@0 130
michael@0 131 // handle some tests
michael@0 132 if (++hitCount == 1) {
michael@0 133 // Test 6
michael@0 134 aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
michael@0 135 }
michael@0 136 }
michael@0 137
michael@0 138 /**
michael@0 139 * Helper: Sets prefs as the testsuite requires
michael@0 140 * @note Will be reset in cleanTestSuite just before finishing the tests
michael@0 141 */
michael@0 142 function setPrefs() {
michael@0 143 gPrefService.setIntPref("browser.startup.page", 3);
michael@0 144 gPrefService.setBoolPref(
michael@0 145 "browser.privatebrowsing.keep_current_session",
michael@0 146 true
michael@0 147 );
michael@0 148 gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
michael@0 149 }
michael@0 150
michael@0 151 /**
michael@0 152 * Helper: Sets up this testsuite
michael@0 153 */
michael@0 154 function setupTestsuite(testFn) {
michael@0 155 // Register our observers
michael@0 156 for (let o in observing)
michael@0 157 Services.obs.addObserver(observer, o, false);
michael@0 158
michael@0 159 // Make the main test window not count as a browser window any longer
michael@0 160 oldWinType = document.documentElement.getAttribute("windowtype");
michael@0 161 document.documentElement.setAttribute("windowtype", "navigator:testrunner");
michael@0 162 }
michael@0 163
michael@0 164 /**
michael@0 165 * Helper: Cleans up behind the testsuite
michael@0 166 */
michael@0 167 function cleanupTestsuite(callback) {
michael@0 168 // Finally remove observers again
michael@0 169 for (let o in observing)
michael@0 170 Services.obs.removeObserver(observer, o);
michael@0 171
michael@0 172 // Reset the prefs we touched
michael@0 173 [
michael@0 174 "browser.startup.page",
michael@0 175 "browser.privatebrowsing.keep_current_session"
michael@0 176 ].forEach(function (pref) {
michael@0 177 if (gPrefService.prefHasUserValue(pref))
michael@0 178 gPrefService.clearUserPref(pref);
michael@0 179 });
michael@0 180 gPrefService.setBoolPref("browser.tabs.warnOnClose", oldWarnTabsOnClose);
michael@0 181
michael@0 182 // Reset the window type
michael@0 183 document.documentElement.setAttribute("windowtype", oldWinType);
michael@0 184 }
michael@0 185
michael@0 186 /**
michael@0 187 * Helper: sets the prefs and a new window with our test tabs
michael@0 188 */
michael@0 189 function setupTestAndRun(aIsPrivateWindow, testFn) {
michael@0 190 // Prepare the prefs
michael@0 191 setPrefs();
michael@0 192
michael@0 193 // Prepare a window; open it and add more tabs
michael@0 194 let options = {};
michael@0 195 if (aIsPrivateWindow) {
michael@0 196 options = {private: true};
michael@0 197 }
michael@0 198
michael@0 199 whenNewWindowLoaded(options, function (newWin) {
michael@0 200 TEST_URLS.forEach(function (url) {
michael@0 201 newWin.gBrowser.addTab(url);
michael@0 202 });
michael@0 203
michael@0 204 executeSoon(() => testFn(newWin));
michael@0 205 });
michael@0 206 }
michael@0 207
michael@0 208 /**
michael@0 209 * Test 1: Normal in-session restore
michael@0 210 * @note: Non-Mac only
michael@0 211 */
michael@0 212 function testOpenCloseNormal(nextFn) {
michael@0 213 setupTestAndRun(false, function(newWin) {
michael@0 214 // Close the window
michael@0 215 // window.close doesn't push any close events,
michael@0 216 // so use BrowserTryToCloseWindow
michael@0 217 newWin.BrowserTryToCloseWindow();
michael@0 218
michael@0 219 // The first request to close is denied by our observer (Test 6)
michael@0 220 ok(!newWin.closed, "First close request was denied");
michael@0 221 if (!newWin.closed) {
michael@0 222 newWin.BrowserTryToCloseWindow();
michael@0 223 ok(newWin.closed, "Second close request was granted");
michael@0 224 }
michael@0 225
michael@0 226 // Open a new window
michael@0 227 // The previously closed window should be restored
michael@0 228 whenNewWindowLoaded({}, function (newWin) {
michael@0 229 is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
michael@0 230 "Restored window in-session with otherpopup windows around");
michael@0 231
michael@0 232 // Cleanup
michael@0 233 newWin.close();
michael@0 234
michael@0 235 // Next please
michael@0 236 executeSoon(nextFn);
michael@0 237 });
michael@0 238 });
michael@0 239 }
michael@0 240
michael@0 241 /**
michael@0 242 * Test 2: PrivateBrowsing in-session restore
michael@0 243 * @note: Non-Mac only
michael@0 244 */
michael@0 245 function testOpenClosePrivateBrowsing(nextFn) {
michael@0 246 setupTestAndRun(false, function(newWin) {
michael@0 247 // Close the window
michael@0 248 newWin.BrowserTryToCloseWindow();
michael@0 249
michael@0 250 // Enter private browsing mode
michael@0 251 // Open a new window.
michael@0 252 // The previously closed window should NOT be restored
michael@0 253 whenNewWindowLoaded({private: true}, function (newWin) {
michael@0 254 is(newWin.gBrowser.browsers.length, 1,
michael@0 255 "Did not restore in private browing mode");
michael@0 256
michael@0 257 // Cleanup
michael@0 258 newWin.BrowserTryToCloseWindow();
michael@0 259
michael@0 260 // Exit private browsing mode again
michael@0 261 whenNewWindowLoaded({}, function (newWin) {
michael@0 262 is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
michael@0 263 "Restored after leaving private browsing again");
michael@0 264
michael@0 265 newWin.close();
michael@0 266
michael@0 267 // Next please
michael@0 268 executeSoon(nextFn);
michael@0 269 });
michael@0 270 });
michael@0 271 });
michael@0 272 }
michael@0 273
michael@0 274 /**
michael@0 275 * Test 3: Open some popup windows to check those aren't restored, but
michael@0 276 * the browser window is
michael@0 277 * @note: Non-Mac only
michael@0 278 */
michael@0 279 function testOpenCloseWindowAndPopup(nextFn) {
michael@0 280 setupTestAndRun(false, function(newWin) {
michael@0 281 // open some popups
michael@0 282 let popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[0]);
michael@0 283 let popup2 = openDialog(location, "popup2", POPUP_FEATURES, TEST_URLS[1]);
michael@0 284 popup2.addEventListener("load", function() {
michael@0 285 popup2.removeEventListener("load", arguments.callee, false);
michael@0 286 popup2.gBrowser.addEventListener("load", function() {
michael@0 287 popup2.gBrowser.removeEventListener("load", arguments.callee, true);
michael@0 288 popup2.gBrowser.addTab(TEST_URLS[0]);
michael@0 289 // close the window
michael@0 290 newWin.BrowserTryToCloseWindow();
michael@0 291
michael@0 292 // Close the popup window
michael@0 293 // The test is successful when not this popup window is restored
michael@0 294 // but instead newWin
michael@0 295 popup2.close();
michael@0 296
michael@0 297 // open a new window the previously closed window should be restored to
michael@0 298 whenNewWindowLoaded({}, function (newWin) {
michael@0 299 is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
michael@0 300 "Restored window and associated tabs in session");
michael@0 301
michael@0 302 // Cleanup
michael@0 303 newWin.close();
michael@0 304 popup.close();
michael@0 305
michael@0 306 // Next please
michael@0 307 executeSoon(nextFn);
michael@0 308 });
michael@0 309 }, true);
michael@0 310 }, false);
michael@0 311 });
michael@0 312 }
michael@0 313
michael@0 314 /**
michael@0 315 * Test 4: Open some popup window to check it isn't restored.
michael@0 316 * Instead nothing at all should be restored
michael@0 317 * @note: Non-Mac only
michael@0 318 */
michael@0 319 function testOpenCloseOnlyPopup(nextFn) {
michael@0 320 // prepare the prefs
michael@0 321 setPrefs();
michael@0 322
michael@0 323 // This will cause nsSessionStore to restore a window the next time it
michael@0 324 // gets a chance.
michael@0 325 let popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
michael@0 326 popup.addEventListener("load", function() {
michael@0 327 this.removeEventListener("load", arguments.callee, true);
michael@0 328 is(popup.gBrowser.browsers.length, 1,
michael@0 329 "Did not restore the popup window (1)");
michael@0 330 popup.BrowserTryToCloseWindow();
michael@0 331
michael@0 332 // Real tests
michael@0 333 popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
michael@0 334 popup.addEventListener("load", function() {
michael@0 335 popup.removeEventListener("load", arguments.callee, false);
michael@0 336 popup.gBrowser.addEventListener("load", function() {
michael@0 337 popup.gBrowser.removeEventListener("load", arguments.callee, true);
michael@0 338 popup.gBrowser.addTab(TEST_URLS[0]);
michael@0 339
michael@0 340 is(popup.gBrowser.browsers.length, 2,
michael@0 341 "Did not restore to the popup window (2)");
michael@0 342
michael@0 343 // Close the popup window
michael@0 344 // The test is successful when not this popup window is restored
michael@0 345 // but instead a new window is opened without restoring anything
michael@0 346 popup.close();
michael@0 347
michael@0 348 whenNewWindowLoaded({}, function (newWin) {
michael@0 349 isnot(newWin.gBrowser.browsers.length, 2,
michael@0 350 "Did not restore the popup window");
michael@0 351 is(TEST_URLS.indexOf(newWin.gBrowser.browsers[0].currentURI.spec), -1,
michael@0 352 "Did not restore the popup window (2)");
michael@0 353
michael@0 354 // Cleanup
michael@0 355 newWin.close();
michael@0 356
michael@0 357 // Next please
michael@0 358 executeSoon(nextFn);
michael@0 359 });
michael@0 360 }, true);
michael@0 361 }, false);
michael@0 362 }, true);
michael@0 363 }
michael@0 364
michael@0 365 /**
michael@0 366 * Test 5: Open some windows and do undoCloseWindow. This should prevent any
michael@0 367 * restoring later in the test
michael@0 368 * @note: Non-Mac only
michael@0 369 */
michael@0 370 function testOpenCloseRestoreFromPopup(nextFn) {
michael@0 371 setupTestAndRun(false, function(newWin) {
michael@0 372 setupTestAndRun(false, function(newWin2) {
michael@0 373 newWin.BrowserTryToCloseWindow();
michael@0 374 newWin2.BrowserTryToCloseWindow();
michael@0 375
michael@0 376 browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
michael@0 377
michael@0 378 newWin = undoCloseWindow(0);
michael@0 379
michael@0 380 whenNewWindowLoaded({}, function (newWin2) {
michael@0 381 is(newWin2.gBrowser.browsers.length, 1,
michael@0 382 "Did not restore, as undoCloseWindow() was last called");
michael@0 383 is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
michael@0 384 "Did not restore, as undoCloseWindow() was last called (2)");
michael@0 385
michael@0 386 browserWindowsCount([2, 3], "browser windows while running testOpenCloseRestoreFromPopup");
michael@0 387
michael@0 388 // Cleanup
michael@0 389 newWin.close();
michael@0 390 newWin2.close();
michael@0 391
michael@0 392 browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
michael@0 393
michael@0 394 // Next please
michael@0 395 executeSoon(nextFn);
michael@0 396 });
michael@0 397 });
michael@0 398 });
michael@0 399 }
michael@0 400
michael@0 401 /**
michael@0 402 * Test 7: Check whether the right number of notifications was received during
michael@0 403 * the tests
michael@0 404 */
michael@0 405 function testNotificationCount(nextFn) {
michael@0 406 is(observing["browser-lastwindow-close-requested"], NOTIFICATIONS_EXPECTED,
michael@0 407 "browser-lastwindow-close-requested notifications observed");
michael@0 408
michael@0 409 // -request must be one more as we cancel the first one we hit,
michael@0 410 // and hence won't produce a corresponding -grant
michael@0 411 // @see observer.observe
michael@0 412 is(observing["browser-lastwindow-close-requested"],
michael@0 413 observing["browser-lastwindow-close-granted"] + 1,
michael@0 414 "Notification count for -request and -grant matches");
michael@0 415
michael@0 416 executeSoon(nextFn);
michael@0 417 }
michael@0 418
michael@0 419 /**
michael@0 420 * Test 8: Test if closing can be denied on Mac
michael@0 421 * Futhermore prepares the testNotificationCount test (Test 7)
michael@0 422 * @note: Mac only
michael@0 423 */
michael@0 424 function testMacNotifications(nextFn, iteration) {
michael@0 425 iteration = iteration || 1;
michael@0 426 setupTestAndRun(false, function(newWin) {
michael@0 427 // close the window
michael@0 428 // window.close doesn't push any close events,
michael@0 429 // so use BrowserTryToCloseWindow
michael@0 430 newWin.BrowserTryToCloseWindow();
michael@0 431 if (iteration == 1) {
michael@0 432 ok(!newWin.closed, "First close attempt denied");
michael@0 433 if (!newWin.closed) {
michael@0 434 newWin.BrowserTryToCloseWindow();
michael@0 435 ok(newWin.closed, "Second close attempt granted");
michael@0 436 }
michael@0 437 }
michael@0 438
michael@0 439 if (iteration < NOTIFICATIONS_EXPECTED - 1) {
michael@0 440 executeSoon(function() testMacNotifications(nextFn, ++iteration));
michael@0 441 }
michael@0 442 else {
michael@0 443 executeSoon(nextFn);
michael@0 444 }
michael@0 445 });
michael@0 446 }
michael@0 447
michael@0 448 // Execution starts here
michael@0 449
michael@0 450 setupTestsuite();
michael@0 451 if (navigator.platform.match(/Mac/)) {
michael@0 452 // Mac tests
michael@0 453 testMacNotifications(function () {
michael@0 454 testNotificationCount(function () {
michael@0 455 cleanupTestsuite();
michael@0 456 browserWindowsCount(1, "Only one browser window should be open eventually");
michael@0 457 finish();
michael@0 458 });
michael@0 459 });
michael@0 460 }
michael@0 461 else {
michael@0 462 // Non-Mac Tests
michael@0 463 testOpenCloseNormal(function () {
michael@0 464 browserWindowsCount([0, 1], "browser windows after testOpenCloseNormal");
michael@0 465 testOpenClosePrivateBrowsing(function () {
michael@0 466 browserWindowsCount([0, 1], "browser windows after testOpenClosePrivateBrowsing");
michael@0 467 testOpenCloseWindowAndPopup(function () {
michael@0 468 browserWindowsCount([0, 1], "browser windows after testOpenCloseWindowAndPopup");
michael@0 469 testOpenCloseOnlyPopup(function () {
michael@0 470 browserWindowsCount([0, 1], "browser windows after testOpenCloseOnlyPopup");
michael@0 471 testOpenCloseRestoreFromPopup(function () {
michael@0 472 browserWindowsCount([0, 1], "browser windows after testOpenCloseRestoreFromPopup");
michael@0 473 testNotificationCount(function () {
michael@0 474 cleanupTestsuite();
michael@0 475 browserWindowsCount(1, "browser windows after testNotificationCount");
michael@0 476 finish();
michael@0 477 });
michael@0 478 });
michael@0 479 });
michael@0 480 });
michael@0 481 });
michael@0 482 });
michael@0 483 }
michael@0 484 }

mercurial