/* Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { TabStateFlusher } = ChromeUtils.importESModule( "resource:///modules/sessionstore/TabStateFlusher.sys.mjs" ); // Go to example.com, do window.open() to obtain an initial about:blank with content principal const ABOUT_BLANK_FROM_CONTENT_STATE = { entries: [ { url: "about:blank", principalToInherit_base64: '{"1":{"0":"https://example.com/"}}', triggeringPrincipal_base64: '{"1":{"0":"https://example.com/"}}', }, ], index: 1, }; // Ensure ABOUT_BLANK_FROM_CONTENT_STATE matches a tab opened from a content document add_task(async function test_about_blank_tab_state_matches_fixture() { const openerTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "https://example.com/" ); const newTabPromise = BrowserTestUtils.waitForNewTab( gBrowser, "about:blank", true ); await SpecialPowers.spawn(openerTab.linkedBrowser, [], () => { content.open("about:blank"); }); const aboutBlankTab = await newTabPromise; await TabStateFlusher.flush(aboutBlankTab.linkedBrowser); const state = JSON.parse(SessionStore.getTabState(aboutBlankTab)); is(state.entries.length, 1, "Got one SH entry"); const actualEntryFixture = { url: state.entries[0].url, principalToInherit_base64: state.entries[0].principalToInherit_base64, triggeringPrincipal_base64: state.entries[0].triggeringPrincipal_base64, }; Assert.deepEqual( actualEntryFixture, ABOUT_BLANK_FROM_CONTENT_STATE.entries[0] ); BrowserTestUtils.removeTab(aboutBlankTab); BrowserTestUtils.removeTab(openerTab); }); // Crashtest for bug 2004165 and bug 2005202 add_task( async function test_restore_initial_about_blank_with_content_principal() { // Need to restore a whole window such that that restoring the about:blank // counts as the initial load and hits the synchronous path. const win = await BrowserTestUtils.openNewBrowserWindow(); // browserLoaded doesn't work reliably for a synchronous load in a different process let restored = BrowserTestUtils.waitForEvent( win.gBrowser.tabContainer, "SSTabRestored" ); const windowState = { windows: [ { tabs: [ABOUT_BLANK_FROM_CONTENT_STATE], selected: 1, }, ], selectedWindow: 1, }; SessionStore.setWindowState(win, JSON.stringify(windowState), true); await restored; ok(true, "Did not crash"); const tab = win.gBrowser.selectedTab; // Sanity check the restored tab await SpecialPowers.spawn(tab.linkedBrowser, [], function () { let principal = content.document.nodePrincipal; // The crash occured in the synchronous load path, so verify it was taken. // That should be equivalent to the document being initial and committed. const isInitialCommitted = content.document.isInitialDocument && !content.document.isUncommittedInitialDocument; // XXX The initial fix for bug 2004165 is to skip the sync path. So // assert the opposite till a better fix is implemented. (bug 2005205) Assert.ok( !isInitialCommitted, "about:blank was not restored as initial document" ); Assert.ok( principal.isContentPrincipal, "Restored about:blank document has a content principal" ); Assert.equal( principal.origin, "https://example.com", "Restored about:blank inherits the origin from https://example.com/" ); }); BrowserTestUtils.removeTab(tab); } );