forked from mirrors/gecko-dev
260 lines
7.6 KiB
JavaScript
260 lines
7.6 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
const { SessionStoreTestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/SessionStoreTestUtils.sys.mjs"
|
|
);
|
|
|
|
const triggeringPrincipal_base64 = E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;
|
|
|
|
SessionStoreTestUtils.init(this, window);
|
|
// take a state snapshot we can restore to after each test
|
|
const ORIG_STATE = SessionStore.getBrowserState();
|
|
|
|
const SECOND_MS = 1000;
|
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
const today = new Date().getTime();
|
|
const yesterday = new Date(Date.now() - DAY_MS).getTime();
|
|
|
|
function tabEntry(url, lastAccessed) {
|
|
return {
|
|
entries: [{ url, triggeringPrincipal_base64 }],
|
|
lastAccessed,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Make the given window focused and active
|
|
*/
|
|
async function switchToWindow(win) {
|
|
info("switchToWindow, waiting for promiseFocus");
|
|
await SimpleTest.promiseFocus(win);
|
|
info("switchToWindow, waiting for correct Services.focus.activeWindow");
|
|
await BrowserTestUtils.waitForCondition(
|
|
() => Services.focus.activeWindow == win
|
|
);
|
|
}
|
|
|
|
async function changeSizeMode(win, mode) {
|
|
let promise = BrowserTestUtils.waitForEvent(win, "sizemodechange");
|
|
win[mode]();
|
|
await promise;
|
|
}
|
|
|
|
async function cleanup() {
|
|
await switchToWindow(window);
|
|
await SessionStoreTestUtils.promiseBrowserState(ORIG_STATE);
|
|
is(
|
|
BrowserWindowTracker.orderedWindows.length,
|
|
1,
|
|
"One window at the end of test cleanup"
|
|
);
|
|
info("cleanup, browser state restored");
|
|
}
|
|
|
|
function deltaTime(time, expectedTime) {
|
|
return Math.abs(expectedTime - time);
|
|
}
|
|
|
|
function getWindowUrl(win) {
|
|
return win.gBrowser.selectedBrowser?.currentURI?.spec;
|
|
}
|
|
|
|
function getWindowByTabUrl(url) {
|
|
return BrowserWindowTracker.orderedWindows.find(
|
|
win => getWindowUrl(win) == url
|
|
);
|
|
}
|
|
|
|
add_task(async function restoredTabs() {
|
|
const now = Date.now();
|
|
await SessionStoreTestUtils.promiseBrowserState({
|
|
windows: [
|
|
{
|
|
tabs: [
|
|
tabEntry("data:,Window0-Tab0", yesterday),
|
|
tabEntry("data:,Window0-Tab1", yesterday),
|
|
],
|
|
selected: 2,
|
|
},
|
|
],
|
|
});
|
|
is(
|
|
gBrowser.visibleTabs[1],
|
|
gBrowser.selectedTab,
|
|
"The selected tab is the 2nd visible tab"
|
|
);
|
|
is(
|
|
getWindowUrl(window),
|
|
"data:,Window0-Tab1",
|
|
"The expected tab is selected"
|
|
);
|
|
Assert.greaterOrEqual(
|
|
gBrowser.selectedTab.lastSeenActive,
|
|
now,
|
|
"The selected tab's lastSeenActive is now"
|
|
);
|
|
Assert.greaterOrEqual(
|
|
gBrowser.selectedTab.lastAccessed,
|
|
now,
|
|
"The selected tab's lastAccessed is now"
|
|
);
|
|
|
|
// tab restored from session but never seen or active
|
|
is(
|
|
gBrowser.visibleTabs[0].lastSeenActive,
|
|
yesterday,
|
|
"The restored tab's lastSeenActive is yesterday"
|
|
);
|
|
await cleanup();
|
|
});
|
|
|
|
add_task(async function switchingTabs() {
|
|
let now = Date.now();
|
|
let initialTab = gBrowser.selectedTab;
|
|
let applicationStart = Services.startup.getStartupInfo().start.getTime();
|
|
let openedTab = BrowserTestUtils.addTab(gBrowser, "data:,Tab1");
|
|
await BrowserTestUtils.browserLoaded(openedTab.linkedBrowser);
|
|
|
|
ok(!openedTab.selected, "The background tab we opened isn't selected");
|
|
Assert.greaterOrEqual(
|
|
initialTab.selected && initialTab.lastSeenActive,
|
|
now,
|
|
"The initial tab is selected and last seen now"
|
|
);
|
|
|
|
is(
|
|
openedTab.lastSeenActive,
|
|
applicationStart,
|
|
`Background tab got default lastSeenActive value, delta: ${deltaTime(
|
|
openedTab.lastSeenActive,
|
|
applicationStart
|
|
)}`
|
|
);
|
|
|
|
now = Date.now();
|
|
await BrowserTestUtils.switchTab(gBrowser, openedTab);
|
|
Assert.greaterOrEqual(
|
|
openedTab.lastSeenActive,
|
|
now,
|
|
"The tab we switched to is last seen now"
|
|
);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
add_task(async function switchingWindows() {
|
|
info("Restoring to the test browser state");
|
|
await SessionStoreTestUtils.promiseBrowserState({
|
|
windows: [
|
|
{
|
|
tabs: [tabEntry("data:,Window1-Tab0", yesterday)],
|
|
selected: 1,
|
|
sizemodeBeforeMinimized: "normal",
|
|
sizemode: "maximized",
|
|
zIndex: 1, // this will be the selected window
|
|
},
|
|
{
|
|
tabs: [tabEntry("data:,Window2-Tab0", yesterday)],
|
|
selected: 1,
|
|
sizemodeBeforeMinimized: "normal",
|
|
sizemode: "maximized",
|
|
zIndex: 2,
|
|
},
|
|
],
|
|
});
|
|
info("promiseBrowserState resolved");
|
|
info(
|
|
`BrowserWindowTracker.pendingWindows: ${BrowserWindowTracker.pendingWindows.size}`
|
|
);
|
|
await Promise.all(
|
|
Array.from(BrowserWindowTracker.pendingWindows.values()).map(
|
|
win => win.deferred.promise
|
|
)
|
|
);
|
|
info("All the pending windows are resolved");
|
|
info("Waiting for the firstBrowserLoaded in each of the windows");
|
|
await Promise.all(
|
|
BrowserWindowTracker.orderedWindows.map(win => {
|
|
const selectedUrl = getWindowUrl(win);
|
|
if (selectedUrl && selectedUrl !== "about:blank") {
|
|
return Promise.resolve();
|
|
}
|
|
return BrowserTestUtils.firstBrowserLoaded(win, false);
|
|
})
|
|
);
|
|
let expectedTabURLs = ["data:,Window1-Tab0", "data:,Window2-Tab0"];
|
|
let [win1, win2] = expectedTabURLs.map(url => getWindowByTabUrl(url));
|
|
if (BrowserWindowTracker.getTopWindow() !== win1) {
|
|
info("Switch to win1 which isn't active/top after restoring session");
|
|
// In theory the zIndex values in the session state should make win1 active
|
|
// But in practice that isn't always true. To ensure we're testing from a known state,
|
|
// ensure the first window is active before proceeding with the test
|
|
await switchToWindow(win1);
|
|
[win1, win2] = expectedTabURLs.map(url => getWindowByTabUrl(url));
|
|
}
|
|
|
|
let actualTabURLs = Array.from(BrowserWindowTracker.orderedWindows).map(win =>
|
|
getWindowUrl(win)
|
|
);
|
|
Assert.deepEqual(
|
|
actualTabURLs,
|
|
expectedTabURLs,
|
|
"Both windows are open with selected tab URLs in the expected order"
|
|
);
|
|
|
|
let lastSeenTimes = [win1, win2].map(
|
|
win => win.gBrowser.selectedTab.lastSeenActive
|
|
);
|
|
|
|
info("Focusing the other window");
|
|
await switchToWindow(win2);
|
|
// wait a little so the timestamps will differ and then check again
|
|
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
|
await new Promise(res => setTimeout(res, 100));
|
|
Assert.greater(
|
|
win2.gBrowser.selectedTab.lastSeenActive,
|
|
lastSeenTimes[1],
|
|
"The foreground window selected tab is last seen more recently than it was before being focused"
|
|
);
|
|
Assert.greater(
|
|
win2.gBrowser.selectedTab.lastSeenActive,
|
|
win1.gBrowser.selectedTab.lastSeenActive,
|
|
"The foreground window selected tab is last seen more recently than the backgrounded one"
|
|
);
|
|
|
|
lastSeenTimes = [win1, win2].map(
|
|
win => win.gBrowser.selectedTab.lastSeenActive
|
|
);
|
|
// minimize the foreground window and focus the other
|
|
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
|
|
win2,
|
|
"sizemodechange"
|
|
);
|
|
win2.minimize();
|
|
info("Waiting for the sizemodechange on minimized window");
|
|
await promiseSizeModeChange;
|
|
await switchToWindow(win1);
|
|
|
|
ok(
|
|
!win2.gBrowser.selectedTab.linkedBrowser.docShellIsActive,
|
|
"Docshell should be Inactive"
|
|
);
|
|
ok(win2.document.hidden, "Minimized windows's document should be hidden");
|
|
|
|
// wait a little so the timestamps will differ and then check again
|
|
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
|
await new Promise(res => setTimeout(res, 100));
|
|
Assert.greater(
|
|
win1.gBrowser.selectedTab.lastSeenActive,
|
|
win2.gBrowser.selectedTab.lastSeenActive,
|
|
"The foreground window selected tab is last seen more recently than the minimized one"
|
|
);
|
|
Assert.greater(
|
|
win1.gBrowser.selectedTab.lastSeenActive,
|
|
lastSeenTimes[0],
|
|
"The foreground window selected tab is last seen more recently than it was before being focused"
|
|
);
|
|
|
|
await cleanup();
|
|
});
|