324 lines
9.8 KiB
JavaScript
324 lines
9.8 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
const REMOTE_URL = "https://www.example.com/";
|
|
const ABOUT_ROBOTS_URL = "about:robots";
|
|
const NO_TITLE_URL = "data:text/plain,foo";
|
|
|
|
const BACKUP_STATE = SessionStore.getBrowserState();
|
|
registerCleanupFunction(() => promiseBrowserState(BACKUP_STATE));
|
|
|
|
add_setup(async function () {
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["browser.sessionstore.restore_on_demand", true],
|
|
["browser.sessionstore.restore_tabs_lazily", true],
|
|
],
|
|
});
|
|
});
|
|
|
|
/**
|
|
* When implementing batch insertion of tabs as part of session restore,
|
|
* we started reversing the insertion order of pinned tabs (bug 1607441).
|
|
* This test checks we don't regress that again.
|
|
*/
|
|
add_task(async function test_pinned_tabs_order() {
|
|
// we expect 3 pinned tabs plus the selected tab get content restored.
|
|
let allTabsRestored = promiseSessionStoreLoads(4);
|
|
await promiseBrowserState({
|
|
windows: [
|
|
{
|
|
selected: 4, // SessionStore uses 1-based indexing.
|
|
tabs: [
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: ABOUT_ROBOTS_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
|
{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
await allTabsRestored;
|
|
let [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs;
|
|
ok(tab1.pinned, "First tab is pinned");
|
|
ok(tab2.pinned, "Second tab is pinned");
|
|
ok(tab3.pinned, "Third tab is pinned");
|
|
ok(!tab4.pinned, "Fourth tab is not pinned");
|
|
ok(!tab5.pinned, "Fifth tab is not pinned");
|
|
|
|
ok(tab4.selected, "Fourth tab is selected");
|
|
is(
|
|
tab1.linkedBrowser.currentURI.spec,
|
|
REMOTE_URL,
|
|
"First tab has matching URL"
|
|
);
|
|
is(
|
|
tab2.linkedBrowser.currentURI.spec,
|
|
ABOUT_ROBOTS_URL,
|
|
"Second tab has matching URL"
|
|
);
|
|
is(
|
|
tab3.linkedBrowser.currentURI.spec,
|
|
NO_TITLE_URL,
|
|
"Third tab has matching URL"
|
|
);
|
|
// Clean up for the next task.
|
|
await promiseBrowserState(BACKUP_STATE);
|
|
});
|
|
|
|
/**
|
|
* When fixing the previous regression, pinned tabs started disappearing out
|
|
* of sessions with selected pinned tabs. This test checks that case.
|
|
*/
|
|
add_task(async function test_selected_pinned_tab_dataloss() {
|
|
// we expect 3 pinned tabs (one of which is selected) get content restored.
|
|
let allTabsRestored = promiseSessionStoreLoads(3);
|
|
await promiseBrowserState({
|
|
windows: [
|
|
{
|
|
selected: 1, // SessionStore uses 1-based indexing.
|
|
tabs: [
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: ABOUT_ROBOTS_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
|
{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
await allTabsRestored;
|
|
let [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs;
|
|
ok(tab5, "Should have 5 tabs");
|
|
ok(tab1.pinned, "First tab is pinned");
|
|
ok(tab2.pinned, "Second tab is pinned");
|
|
ok(tab3.pinned, "Third tab is pinned");
|
|
ok(tab4 && !tab4.pinned, "Fourth tab is not pinned");
|
|
ok(tab5 && !tab5.pinned, "Fifth tab is not pinned");
|
|
|
|
ok(tab1 && tab1.selected, "First (pinned) tab is selected");
|
|
is(
|
|
tab1.linkedBrowser.currentURI.spec,
|
|
REMOTE_URL,
|
|
"First tab has matching URL"
|
|
);
|
|
is(
|
|
tab2.linkedBrowser.currentURI.spec,
|
|
ABOUT_ROBOTS_URL,
|
|
"Second tab has matching URL"
|
|
);
|
|
is(
|
|
tab3.linkedBrowser.currentURI.spec,
|
|
NO_TITLE_URL,
|
|
"Third tab has matching URL"
|
|
);
|
|
// Clean up for the next task.
|
|
await promiseBrowserState(BACKUP_STATE);
|
|
});
|
|
|
|
/**
|
|
* While we're here, it seems useful to have a test for mixed pinned and
|
|
* unpinned tabs in session store state, as well as userContextId.
|
|
*/
|
|
add_task(async function test_mixed_pinned_unpinned() {
|
|
// we expect 3 pinned tabs plus the selected tab get content restored.
|
|
let allTabsRestored = promiseSessionStoreLoads(4);
|
|
await promiseBrowserState({
|
|
windows: [
|
|
{
|
|
selected: 4, // SessionStore uses 1-based indexing.
|
|
tabs: [
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: ABOUT_ROBOTS_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
});
|
|
await allTabsRestored;
|
|
let [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs;
|
|
ok(tab1.pinned, "First tab is pinned");
|
|
ok(tab2.pinned, "Second tab is pinned");
|
|
ok(tab3.pinned, "Third tab is pinned");
|
|
ok(!tab4.pinned, "Fourth tab is not pinned");
|
|
ok(!tab5.pinned, "Fifth tab is not pinned");
|
|
|
|
// This is confusing to read - the 4th entry in the session data is
|
|
// selected. But the 5th entry is pinned, so it moves to the start of the
|
|
// tabstrip, so when we fetch `gBrowser.tabs`, the 4th entry in the list
|
|
// is actually the 5th tab.
|
|
ok(tab5.selected, "Fifth tab is selected");
|
|
is(
|
|
tab1.linkedBrowser.currentURI.spec,
|
|
REMOTE_URL,
|
|
"First tab has matching URL"
|
|
);
|
|
is(
|
|
tab2.linkedBrowser.currentURI.spec,
|
|
ABOUT_ROBOTS_URL,
|
|
"Second tab has matching URL"
|
|
);
|
|
is(
|
|
tab3.linkedBrowser.currentURI.spec,
|
|
NO_TITLE_URL,
|
|
"Third tab has matching URL"
|
|
);
|
|
// Clean up for the next task.
|
|
await promiseBrowserState(BACKUP_STATE);
|
|
});
|
|
|
|
/**
|
|
* After session restore, if we crash an unpinned tab, we noticed pinned tabs
|
|
* created in the same process would lose all data (Bug 1624511). This test
|
|
* checks that case.
|
|
*/
|
|
add_task(async function test_pinned_tab_dataloss() {
|
|
// We do not run if there are no crash reporters to avoid
|
|
// problems with the intentional crash.
|
|
if (!AppConstants.MOZ_CRASHREPORTER) {
|
|
return;
|
|
}
|
|
// If we end up increasing the process count limit in future,
|
|
// we want to ensure that we don't stop testing this case
|
|
// of pinned tab data loss.
|
|
if (SpecialPowers.getIntPref("dom.ipc.processCount") > 8) {
|
|
ok(
|
|
false,
|
|
"Process count is greater than 8, update the number of pinned tabs in test."
|
|
);
|
|
}
|
|
|
|
// We expect 17 pinned tabs plus the selected tab get content restored.
|
|
// Given that the default process count is currently 8, we need this
|
|
// number of pinned tabs to reproduce the data loss. If this changes,
|
|
// please add more pinned tabs.
|
|
let allTabsRestored = promiseSessionStoreLoads(18);
|
|
await promiseBrowserState({
|
|
windows: [
|
|
{
|
|
selected: 18, // SessionStore uses 1-based indexing.
|
|
tabs: [
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{
|
|
pinned: true,
|
|
entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }],
|
|
},
|
|
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
await allTabsRestored;
|
|
|
|
let tabs = gBrowser.tabs;
|
|
await BrowserTestUtils.crashFrame(tabs[17].linkedBrowser);
|
|
|
|
await TestUtils.topicObserved("sessionstore-state-write-complete");
|
|
|
|
for (let i = 0; i < tabs.length; i++) {
|
|
let tab = tabs[i];
|
|
is(
|
|
tab.linkedBrowser.currentURI.spec,
|
|
REMOTE_URL,
|
|
`Tab ${i + 1} should have matching URL`
|
|
);
|
|
}
|
|
|
|
// Clean up for the next task.
|
|
await promiseBrowserState(BACKUP_STATE);
|
|
});
|