gecko-dev/docshell/test/browser/browser_bfcache_after_auxiliary.js
Nika Layzell 460fbf9a53 Bug 1925653 - Don't restore from BFCache if navigated-from document has auxiliary BrowsingContexts, r=smaug
To implement BFCache in Gecko, we complete loads in new
BrowsingContextGroups when it would be invisible to the site. This
allows us to suspend the previous document and its entire
BrowsingContextGroup and restore it when navigating back through
history.

Unfortunately the current logic does not catch one web-visible case,
which is when a document is put into the BFCache, and then the next page
opens a named pop-up window. After navigating back to the previous page,
we switch back to the previous BrowsingContextGroup, and opening the
same named window will create a distinct pop-up.

This patch proposes avoiding this by not restoring a session history
entry from the BFCache when the navigating BrowsingContext has auxiliary
BrowsingContexts. This is done lazily, so if the pop-up is closed before
the back navigation (e.g. due to it being used for an oauth flow), it
will not invalidate the BFCache entry.

Differential Revision: https://phabricator.services.mozilla.com/D226184
2024-10-21 17:15:54 +00:00

87 lines
2.7 KiB
JavaScript

const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
add_task(async function restore_bfcache_after_auxiliary() {
await BrowserTestUtils.withNewTab(
TEST_PATH + "dummy_page.html",
async browser => {
let initialBC = browser.browsingContext;
// Mark the initial dummy page as having the dynamic state from the bfcache by replacing the body.
await SpecialPowers.spawn(browser, [], () => {
content.document.body.innerHTML = "bfcached";
});
BrowserTestUtils.startLoadingURIString(
browser,
TEST_PATH + "file_open_about_blank.html"
);
await BrowserTestUtils.browserLoaded(browser);
let openerBC = browser.browsingContext;
isnot(
initialBC,
openerBC,
"should have put the previous document into the bfcache"
);
// Check that the document is currently BFCached
info("going back for bfcache smoke test");
browser.goBack();
await BrowserTestUtils.waitForContentEvent(browser, "pageshow");
let restoredInnerHTML = await SpecialPowers.spawn(
browser,
[],
() => content.document.body.innerHTML
);
is(restoredInnerHTML, "bfcached", "page was restored from bfcache");
is(
initialBC,
browser.browsingContext,
"returned to previous browsingcontext"
);
// Go back forward, and open a pop-up.
info("restoring after bfcache smoke test");
browser.goForward();
await BrowserTestUtils.waitForContentEvent(browser, "pageshow");
is(
openerBC,
browser.browsingContext,
"returned to opener browsingContext"
);
info("opening a popup");
let waitForPopup = BrowserTestUtils.waitForNewTab(gBrowser);
await SpecialPowers.spawn(browser, [], () => {
content.eval(`window.open("dummy_page.html", "popup");`);
// content.document.querySelector("#open").click()
});
let popup = await waitForPopup;
info("got the popup");
let popupBC = popup.linkedBrowser.browsingContext;
is(popupBC.opener, openerBC, "opener is openerBC");
// Now that the pop-up is opened, try to go back again.
info("trying to go back with a popup");
browser.goBack();
await BrowserTestUtils.waitForContentEvent(browser, "pageshow");
let nonRestoredInnerHTML = await SpecialPowers.spawn(
browser,
[],
() => content.document.body.innerHTML
);
isnot(
nonRestoredInnerHTML,
"bfcached",
"page was not restored from bfcache"
);
is(openerBC, browser.browsingContext, "returned to the new bc");
await BrowserTestUtils.removeTab(popup);
}
);
});