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.

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

mercurial