browser/components/sessionstore/test/browser_589246.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 // Mirrors WINDOW_ATTRIBUTES IN nsSessionStore.js
     6 const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
     8 let stateBackup = ss.getBrowserState();
    10 let originalWarnOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
    11 let originalStartupPage = gPrefService.getIntPref("browser.startup.page");
    12 let originalWindowType = document.documentElement.getAttribute("windowtype");
    14 let gotLastWindowClosedTopic = false;
    15 let shouldPinTab = false;
    16 let shouldOpenTabs = false;
    17 let shouldCloseTab = false;
    18 let testNum = 0;
    19 let afterTestCallback;
    21 // Set state so we know the closed windows content
    22 let testState = {
    23   windows: [
    24     { tabs: [{ entries: [{ url: "http://example.org" }] }] }
    25   ],
    26   _closedWindows: []
    27 };
    29 // We'll push a set of conditions and callbacks into this array
    30 // Ideally we would also test win/linux under a complete set of conditions, but
    31 // the tests for osx mirror the other set of conditions possible on win/linux.
    32 let tests = [];
    34 // the third & fourth test share a condition check, keep it DRY
    35 function checkOSX34Generator(num) {
    36   return function(aPreviousState, aCurState) {
    37     // In here, we should have restored the pinned tab, so only the unpinned tab
    38     // should be in aCurState. So let's shape our expectations.
    39     let expectedState = JSON.parse(aPreviousState);
    40     expectedState[0].tabs.shift();
    41     // size attributes are stripped out in _prepDataForDeferredRestore in nsSessionStore.
    42     // This isn't the best approach, but neither is comparing JSON strings
    43     WINDOW_ATTRIBUTES.forEach(function (attr) delete expectedState[0][attr]);
    45     is(aCurState, JSON.stringify(expectedState),
    46        "test #" + num + ": closedWindowState is as expected");
    47   };
    48 }
    49 function checkNoWindowsGenerator(num) {
    50   return function(aPreviousState, aCurState) {
    51     is(aCurState, "[]", "test #" + num + ": there should be no closedWindowsLeft");
    52   };
    53 }
    55 // The first test has 0 pinned tabs and 1 unpinned tab
    56 tests.push({
    57   pinned: false,
    58   extra: false,
    59   close: false,
    60   checkWinLin: checkNoWindowsGenerator(1),
    61   checkOSX: function(aPreviousState, aCurState) {
    62     is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
    63   }
    64 });
    66 // The second test has 1 pinned tab and 0 unpinned tabs.
    67 tests.push({
    68   pinned: true,
    69   extra: false,
    70   close: false,
    71   checkWinLin: checkNoWindowsGenerator(2),
    72   checkOSX: checkNoWindowsGenerator(2)
    73 });
    75 // The third test has 1 pinned tab and 2 unpinned tabs.
    76 tests.push({
    77   pinned: true,
    78   extra: true,
    79   close: false,
    80   checkWinLin: checkNoWindowsGenerator(3),
    81   checkOSX: checkOSX34Generator(3)
    82 });
    84 // The fourth test has 1 pinned tab, 2 unpinned tabs, and closes one unpinned tab.
    85 tests.push({
    86   pinned: true,
    87   extra: true,
    88   close: "one",
    89   checkWinLin: checkNoWindowsGenerator(4),
    90   checkOSX: checkOSX34Generator(4)
    91 });
    93 // The fifth test has 1 pinned tab, 2 unpinned tabs, and closes both unpinned tabs.
    94 tests.push({
    95   pinned: true,
    96   extra: true,
    97   close: "both",
    98   checkWinLin: checkNoWindowsGenerator(5),
    99   checkOSX: checkNoWindowsGenerator(5)
   100 });
   103 function test() {
   104   /** Test for Bug 589246 - Closed window state getting corrupted when closing
   105       and reopening last browser window without exiting browser **/
   106   waitForExplicitFinish();
   107   // windows opening & closing, so extending the timeout
   108   requestLongerTimeout(2);
   110   // We don't want the quit dialog pref
   111   gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
   112   // Ensure that we would restore the session (important for Windows)
   113   gPrefService.setIntPref("browser.startup.page", 3);
   115   runNextTestOrFinish();
   116 }
   118 function runNextTestOrFinish() {
   119   if (tests.length) {
   120     setupForTest(tests.shift())
   121   }
   122   else {
   123     // some state is cleaned up at the end of each test, but not all
   124     ["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
   125       if (gPrefService.prefHasUserValue(p))
   126         gPrefService.clearUserPref(p);
   127     });
   129     ss.setBrowserState(stateBackup);
   130     executeSoon(finish);
   131   }
   132 }
   134 function setupForTest(aConditions) {
   135   // reset some checks
   136   gotLastWindowClosedTopic = false;
   137   shouldPinTab = aConditions.pinned;
   138   shouldOpenTabs = aConditions.extra;
   139   shouldCloseTab = aConditions.close;
   140   testNum++;
   142   // set our test callback
   143   afterTestCallback = /Mac/.test(navigator.platform) ? aConditions.checkOSX
   144                                                      : aConditions.checkWinLin;
   146   // Add observers
   147   Services.obs.addObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
   149   // Set the state
   150   Services.obs.addObserver(onStateRestored, "sessionstore-browser-state-restored", false);
   151   ss.setBrowserState(JSON.stringify(testState));
   152 }
   154 function onStateRestored(aSubject, aTopic, aData) {
   155   info("test #" + testNum + ": onStateRestored");
   156   Services.obs.removeObserver(onStateRestored, "sessionstore-browser-state-restored");
   158   // change this window's windowtype so that closing a new window will trigger
   159   // browser-lastwindow-close-granted.
   160   document.documentElement.setAttribute("windowtype", "navigator:testrunner");
   162   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
   163   newWin.addEventListener("load", function(aEvent) {
   164     newWin.removeEventListener("load", arguments.callee, false);
   166     whenBrowserLoaded(newWin.gBrowser.selectedBrowser, function() {
   167       // pin this tab
   168       if (shouldPinTab)
   169         newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
   171       newWin.addEventListener("unload", function () {
   172         newWin.removeEventListener("unload", arguments.callee, false);
   173         onWindowUnloaded();
   174       }, false);
   175       // Open a new tab as well. On Windows/Linux this will be restored when the
   176       // new window is opened below (in onWindowUnloaded). On OS X we'll just
   177       // restore the pinned tabs, leaving the unpinned tab in the closedWindowsData.
   178       if (shouldOpenTabs) {
   179         let newTab = newWin.gBrowser.addTab("about:config");
   180         let newTab2 = newWin.gBrowser.addTab("about:buildconfig");
   182         newTab.linkedBrowser.addEventListener("load", function() {
   183           newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
   185           if (shouldCloseTab == "one") {
   186             newWin.gBrowser.removeTab(newTab2);
   187           }
   188           else if (shouldCloseTab == "both") {
   189             newWin.gBrowser.removeTab(newTab);
   190             newWin.gBrowser.removeTab(newTab2);
   191           }
   192           newWin.BrowserTryToCloseWindow();
   193         }, true);
   194       }
   195       else {
   196         newWin.BrowserTryToCloseWindow();
   197       }
   198     });
   199   }, false);
   200 }
   202 // This will be called before the window is actually closed
   203 function onLastWindowClosed(aSubject, aTopic, aData) {
   204   info("test #" + testNum + ": onLastWindowClosed");
   205   Services.obs.removeObserver(onLastWindowClosed, "browser-lastwindow-close-granted");
   206   gotLastWindowClosedTopic = true;
   207 }
   209 // This is the unload event listener on the new window (from onStateRestored).
   210 // Unload is fired after the window is closed, so sessionstore has already
   211 // updated _closedWindows (which is important). We'll open a new window here
   212 // which should actually trigger the bug.
   213 function onWindowUnloaded() {
   214   info("test #" + testNum + ": onWindowClosed");
   215   ok(gotLastWindowClosedTopic, "test #" + testNum + ": browser-lastwindow-close-granted was notified prior");
   217   let previousClosedWindowData = ss.getClosedWindowData();
   219   // Now we want to open a new window
   220   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:mozilla");
   221   newWin.addEventListener("load", function(aEvent) {
   222     newWin.removeEventListener("load", arguments.callee, false);
   224     newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
   225       newWin.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
   227       // Good enough for checking the state
   228       afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
   229       afterTestCleanup(newWin);
   230     }, true);
   232   }, false);
   233 }
   235 function afterTestCleanup(aNewWin) {
   236   executeSoon(function() {
   237     aNewWin.close();
   238     document.documentElement.setAttribute("windowtype", originalWindowType);
   239     runNextTestOrFinish();
   240   });
   241 }

mercurial