mirror of
https://github.com/Feodor2/Mypal68.git
synced 2025-06-18 14:55:44 -04:00
486 lines
15 KiB
JavaScript
486 lines
15 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/**
|
|
* Checks that restoring the last browser window in session is actually
|
|
* working.
|
|
*
|
|
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=354894
|
|
* @note It is implicitly tested that restoring the last window works when
|
|
* non-browser windows are around. The "Run Tests" window as well as the main
|
|
* browser window (wherein the test code gets executed) won't be considered
|
|
* browser windows. To achiveve this said main browser window has its windowtype
|
|
* attribute modified so that it's not considered a browser window any longer.
|
|
* This is crucial, because otherwise there would be two browser windows around,
|
|
* said main test window and the one opened by the tests, and hence the new
|
|
* logic wouldn't be executed at all.
|
|
* @note Mac only tests the new notifications, as restoring the last window is
|
|
* not enabled on that platform (platform shim; the application is kept running
|
|
* although there are no windows left)
|
|
* @note There is a difference when closing a browser window with
|
|
* BrowserTryToCloseWindow() as opposed to close(). The former will make
|
|
* nsSessionStore restore a window next time it gets a chance and will post
|
|
* notifications. The latter won't.
|
|
*/
|
|
|
|
ChromeUtils.import("resource:///modules/sessionstore/SessionStartup.jsm", this);
|
|
// The rejection "BrowserWindowTracker.getTopWindow(...) is null" is left
|
|
// unhandled in some cases. This bug should be fixed, but for the moment this
|
|
// file is whitelisted.
|
|
//
|
|
// NOTE: Whitelisting a class of rejections should be limited. Normally you
|
|
// should use "expectUncaughtRejection" to flag individual failures.
|
|
ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", this);
|
|
PromiseTestUtils.whitelistRejectionsGlobally(/getTopWindow/);
|
|
|
|
// Some urls that might be opened in tabs and/or popups
|
|
// Do not use about:blank:
|
|
// That one is reserved for special purposes in the tests
|
|
const TEST_URLS = ["about:mozilla", "about:buildconfig"];
|
|
|
|
// Number of -request notifications to except
|
|
// remember to adjust when adding new tests
|
|
const NOTIFICATIONS_EXPECTED = 6;
|
|
|
|
// Window features of popup windows
|
|
const POPUP_FEATURES = "toolbar=no,resizable=no,status=no";
|
|
|
|
// Window features of browser windows
|
|
const CHROME_FEATURES = "chrome,all,dialog=no";
|
|
|
|
const IS_MAC = navigator.platform.match(/Mac/);
|
|
|
|
/**
|
|
* Returns an Object with two properties:
|
|
* open (int):
|
|
* A count of how many non-closed navigator:browser windows there are.
|
|
* winstates (int):
|
|
* A count of how many windows there are in the SessionStore state.
|
|
*/
|
|
function getBrowserWindowsCount() {
|
|
let open = 0;
|
|
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
|
if (!win.closed) {
|
|
++open;
|
|
}
|
|
}
|
|
|
|
let winstates = JSON.parse(ss.getBrowserState()).windows.length;
|
|
|
|
return { open, winstates };
|
|
}
|
|
|
|
add_task(async function setup() {
|
|
// Make sure we've only got one browser window to start with
|
|
let { open, winstates } = getBrowserWindowsCount();
|
|
is(open, 1, "Should only be one open window");
|
|
is(winstates, 1, "Should only be one window state in SessionStore");
|
|
|
|
// This test takes some time to run, and it could timeout randomly.
|
|
// So we require a longer timeout. See bug 528219.
|
|
requestLongerTimeout(3);
|
|
|
|
// Make the main test window not count as a browser window any longer
|
|
let oldWinType = document.documentElement.getAttribute("windowtype");
|
|
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
|
|
|
|
registerCleanupFunction(() => {
|
|
document.documentElement.setAttribute("windowtype", oldWinType);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Sets up one of our tests by setting the right preferences, and
|
|
* then opening up a browser window preloaded with some tabs.
|
|
*
|
|
* @param options (Object)
|
|
* An object that can contain the following properties:
|
|
*
|
|
* private:
|
|
* Whether or not the opened window should be private.
|
|
*
|
|
* denyFirst:
|
|
* Whether or not the first window that attempts to close
|
|
* via closeWindowForRestoration should be denied.
|
|
*
|
|
* @param testFunction (Function*)
|
|
* A generator function that yields Promises to be run
|
|
* once the test has been set up.
|
|
*
|
|
* @returns Promise
|
|
* Resolves once the test has been cleaned up.
|
|
*/
|
|
let setupTest = async function(options, testFunction) {
|
|
await pushPrefs(
|
|
["browser.startup.page", 3],
|
|
["browser.tabs.warnOnClose", false]
|
|
);
|
|
// SessionStartup caches pref values, but as this test tries to simulate a
|
|
// startup scenario, we'll reset them here.
|
|
SessionStartup.resetForTest();
|
|
|
|
// Observe these, and also use to count the number of hits
|
|
let observing = {
|
|
"browser-lastwindow-close-requested": 0,
|
|
"browser-lastwindow-close-granted": 0,
|
|
};
|
|
|
|
/**
|
|
* Helper: Will observe and handle the notifications for us
|
|
*/
|
|
let hitCount = 0;
|
|
function observer(aCancel, aTopic, aData) {
|
|
// count so that we later may compare
|
|
observing[aTopic]++;
|
|
|
|
// handle some tests
|
|
if (options.denyFirst && ++hitCount == 1) {
|
|
aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
|
|
}
|
|
}
|
|
|
|
for (let o in observing) {
|
|
Services.obs.addObserver(observer, o);
|
|
}
|
|
|
|
let private = options.private || false;
|
|
let newWin = await promiseNewWindowLoaded({ private });
|
|
|
|
await injectTestTabs(newWin);
|
|
|
|
await testFunction(newWin, observing);
|
|
|
|
let count = getBrowserWindowsCount();
|
|
is(count.open, 0, "Got right number of open windows");
|
|
is(count.winstates, 1, "Got right number of stored window states");
|
|
|
|
for (let o in observing) {
|
|
Services.obs.removeObserver(observer, o);
|
|
}
|
|
|
|
await popPrefs();
|
|
// Act like nothing ever happened.
|
|
SessionStartup.resetForTest();
|
|
};
|
|
|
|
/**
|
|
* Loads a TEST_URLS into a browser window.
|
|
*
|
|
* @param win (Window)
|
|
* The browser window to load the tabs in
|
|
*/
|
|
function injectTestTabs(win) {
|
|
let promises = TEST_URLS.map(url =>
|
|
BrowserTestUtils.addTab(win.gBrowser, url)
|
|
).map(tab => BrowserTestUtils.browserLoaded(tab.linkedBrowser));
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
/**
|
|
* Attempts to close a window via BrowserTryToCloseWindow so that
|
|
* we get the browser-lastwindow-close-requested and
|
|
* browser-lastwindow-close-granted observer notifications.
|
|
*
|
|
* @param win (Window)
|
|
* The window to try to close
|
|
* @returns Promise
|
|
* Resolves to true if the window closed, or false if the window
|
|
* was denied the ability to close.
|
|
*/
|
|
function closeWindowForRestoration(win) {
|
|
return new Promise(resolve => {
|
|
let closePromise = BrowserTestUtils.windowClosed(win);
|
|
win.BrowserTryToCloseWindow();
|
|
if (!win.closed) {
|
|
resolve(false);
|
|
return;
|
|
}
|
|
|
|
closePromise.then(() => {
|
|
resolve(true);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Normal in-session restore
|
|
*
|
|
* @note: Non-Mac only
|
|
*
|
|
* Should do the following:
|
|
* 1. Open a new browser window
|
|
* 2. Add some tabs
|
|
* 3. Close that window
|
|
* 4. Opening another window
|
|
* 5. Checks that state is restored
|
|
*/
|
|
add_task(async function test_open_close_normal() {
|
|
if (IS_MAC) {
|
|
return;
|
|
}
|
|
|
|
await setupTest({ denyFirst: true }, async function(newWin, obs) {
|
|
let closed = await closeWindowForRestoration(newWin);
|
|
ok(!closed, "First close request should have been denied");
|
|
|
|
closed = await closeWindowForRestoration(newWin);
|
|
ok(closed, "Second close request should be accepted");
|
|
|
|
newWin = await promiseNewWindowLoaded();
|
|
is(
|
|
newWin.gBrowser.browsers.length,
|
|
TEST_URLS.length + 2,
|
|
"Restored window in-session with otherpopup windows around"
|
|
);
|
|
|
|
// Note that this will not result in the the browser-lastwindow-close
|
|
// notifications firing for this other newWin.
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
|
|
// setupTest gave us a window which was denied for closing once, and then
|
|
// closed.
|
|
is(
|
|
obs["browser-lastwindow-close-requested"],
|
|
2,
|
|
"Got expected browser-lastwindow-close-requested notifications"
|
|
);
|
|
is(
|
|
obs["browser-lastwindow-close-granted"],
|
|
1,
|
|
"Got expected browser-lastwindow-close-granted notifications"
|
|
);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* PrivateBrowsing in-session restore
|
|
*
|
|
* @note: Non-Mac only
|
|
*
|
|
* Should do the following:
|
|
* 1. Open a new browser window A
|
|
* 2. Add some tabs
|
|
* 3. Close the window A as the last window
|
|
* 4. Open a private browsing window B
|
|
* 5. Make sure that B didn't restore the tabs from A
|
|
* 6. Close private browsing window B
|
|
* 7. Open a new window C
|
|
* 8. Make sure that new window C has restored tabs from A
|
|
*/
|
|
add_task(async function test_open_close_private_browsing() {
|
|
if (IS_MAC) {
|
|
return;
|
|
}
|
|
|
|
await setupTest({}, async function(newWin, obs) {
|
|
let closed = await closeWindowForRestoration(newWin);
|
|
ok(closed, "Should be able to close the window");
|
|
|
|
newWin = await promiseNewWindowLoaded({ private: true });
|
|
is(
|
|
newWin.gBrowser.browsers.length,
|
|
1,
|
|
"Did not restore in private browing mode"
|
|
);
|
|
|
|
closed = await closeWindowForRestoration(newWin);
|
|
ok(closed, "Should be able to close the window");
|
|
|
|
newWin = await promiseNewWindowLoaded();
|
|
is(
|
|
newWin.gBrowser.browsers.length,
|
|
TEST_URLS.length + 2,
|
|
"Restored tabs in a new non-private window"
|
|
);
|
|
|
|
// Note that this will not result in the the browser-lastwindow-close
|
|
// notifications firing for this other newWin.
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
|
|
// We closed two windows with closeWindowForRestoration, and both
|
|
// should have been successful.
|
|
is(
|
|
obs["browser-lastwindow-close-requested"],
|
|
2,
|
|
"Got expected browser-lastwindow-close-requested notifications"
|
|
);
|
|
is(
|
|
obs["browser-lastwindow-close-granted"],
|
|
2,
|
|
"Got expected browser-lastwindow-close-granted notifications"
|
|
);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Open some popup window to check it isn't restored. Instead nothing at all
|
|
* should be restored
|
|
*
|
|
* @note: Non-Mac only
|
|
*
|
|
* Should do the following:
|
|
* 1. Open a popup
|
|
* 2. Add another tab to the popup (so that it gets stored) and close it again
|
|
* 3. Open a window
|
|
* 4. Check that nothing at all is restored
|
|
* 5. Open two browser windows and close them again
|
|
* 6. undoCloseWindow() one
|
|
* 7. Open another browser window
|
|
* 8. Check that nothing at all is restored
|
|
*/
|
|
add_task(async function test_open_close_only_popup() {
|
|
if (IS_MAC) {
|
|
return;
|
|
}
|
|
|
|
await setupTest({}, async function(newWin, obs) {
|
|
// We actually don't care about the initial window in this test.
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
|
|
// This will cause nsSessionStore to restore a window the next time it
|
|
// gets a chance.
|
|
let popupPromise = BrowserTestUtils.waitForNewWindow();
|
|
openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
|
|
let popup = await popupPromise;
|
|
|
|
is(
|
|
popup.gBrowser.browsers.length,
|
|
1,
|
|
"Did not restore the popup window (1)"
|
|
);
|
|
|
|
let closed = await closeWindowForRestoration(popup);
|
|
ok(closed, "Should be able to close the window");
|
|
|
|
popupPromise = BrowserTestUtils.waitForNewWindow();
|
|
openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
|
|
popup = await popupPromise;
|
|
|
|
BrowserTestUtils.addTab(popup.gBrowser, TEST_URLS[0]);
|
|
is(
|
|
popup.gBrowser.browsers.length,
|
|
2,
|
|
"Did not restore to the popup window (2)"
|
|
);
|
|
|
|
await BrowserTestUtils.closeWindow(popup);
|
|
|
|
newWin = await promiseNewWindowLoaded();
|
|
isnot(
|
|
newWin.gBrowser.browsers.length,
|
|
2,
|
|
"Did not restore the popup window"
|
|
);
|
|
is(
|
|
TEST_URLS.indexOf(newWin.gBrowser.browsers[0].currentURI.spec),
|
|
-1,
|
|
"Did not restore the popup window (2)"
|
|
);
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
|
|
// We closed one popup window with closeWindowForRestoration, and popup
|
|
// windows should never fire the browser-lastwindow notifications.
|
|
is(
|
|
obs["browser-lastwindow-close-requested"],
|
|
0,
|
|
"Got expected browser-lastwindow-close-requested notifications"
|
|
);
|
|
is(
|
|
obs["browser-lastwindow-close-granted"],
|
|
0,
|
|
"Got expected browser-lastwindow-close-granted notifications"
|
|
);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Open some windows and do undoCloseWindow. This should prevent any
|
|
* restoring later in the test
|
|
*
|
|
* @note: Non-Mac only
|
|
*
|
|
* Should do the following:
|
|
* 1. Open two browser windows and close them again
|
|
* 2. undoCloseWindow() one
|
|
* 3. Open another browser window
|
|
* 4. Make sure nothing at all is restored
|
|
*/
|
|
add_task(async function test_open_close_restore_from_popup() {
|
|
if (IS_MAC) {
|
|
return;
|
|
}
|
|
|
|
await setupTest({}, async function(newWin, obs) {
|
|
let newWin2 = await promiseNewWindowLoaded();
|
|
await injectTestTabs(newWin2);
|
|
|
|
let closed = await closeWindowForRestoration(newWin);
|
|
ok(closed, "Should be able to close the window");
|
|
closed = await closeWindowForRestoration(newWin2);
|
|
ok(closed, "Should be able to close the window");
|
|
|
|
let counts = getBrowserWindowsCount();
|
|
is(counts.open, 0, "Got right number of open windows");
|
|
is(counts.winstates, 1, "Got right number of window states");
|
|
|
|
newWin = undoCloseWindow(0);
|
|
await BrowserTestUtils.waitForEvent(newWin, "load");
|
|
|
|
// Make sure we wait until this window is restored.
|
|
await BrowserTestUtils.waitForEvent(
|
|
newWin.gBrowser.tabContainer,
|
|
"SSTabRestored"
|
|
);
|
|
|
|
newWin2 = await promiseNewWindowLoaded();
|
|
|
|
is(
|
|
TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec),
|
|
-1,
|
|
"Did not restore, as undoCloseWindow() was last called (2)"
|
|
);
|
|
|
|
counts = getBrowserWindowsCount();
|
|
is(counts.open, 2, "Got right number of open windows");
|
|
is(counts.winstates, 3, "Got right number of window states");
|
|
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
await BrowserTestUtils.closeWindow(newWin2);
|
|
|
|
counts = getBrowserWindowsCount();
|
|
is(counts.open, 0, "Got right number of open windows");
|
|
is(counts.winstates, 1, "Got right number of window states");
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Test if closing can be denied on Mac.
|
|
* @note: Mac only
|
|
*/
|
|
add_task(async function test_mac_notifications() {
|
|
if (!IS_MAC) {
|
|
return;
|
|
}
|
|
|
|
await setupTest({ denyFirst: true }, async function(newWin, obs) {
|
|
let closed = await closeWindowForRestoration(newWin);
|
|
ok(!closed, "First close attempt should be denied");
|
|
closed = await closeWindowForRestoration(newWin);
|
|
ok(closed, "Second close attempt should be granted");
|
|
|
|
// We tried closing once, and got denied. Then we tried again and
|
|
// succeeded. That means 2 close requests, and 1 close granted.
|
|
is(
|
|
obs["browser-lastwindow-close-requested"],
|
|
2,
|
|
"Got expected browser-lastwindow-close-requested notifications"
|
|
);
|
|
is(
|
|
obs["browser-lastwindow-close-granted"],
|
|
1,
|
|
"Got expected browser-lastwindow-close-granted notifications"
|
|
);
|
|
});
|
|
});
|