browser_restore_container_tabs_oa.js (8188B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { UrlbarProviderOpenTabs } = ChromeUtils.importESModule( 8 "moz-src:///browser/components/urlbar/UrlbarProviderOpenTabs.sys.mjs" 9 ); 10 11 const PATH = "browser/browser/components/sessionstore/test/empty.html"; 12 13 /* import-globals-from ../../tabbrowser/test/browser/tabs/helper_origin_attrs_testing.js */ 14 loadTestSubscript( 15 "../../tabbrowser/test/browser/tabs/helper_origin_attrs_testing.js" 16 ); 17 18 var TEST_CASES = [ 19 "https://example.com/" + PATH, 20 "https://example.org/" + PATH, 21 "about:preferences", 22 "about:config", 23 ]; 24 25 var remoteTypes; 26 27 var xulFrameLoaderCreatedCounter = {}; 28 29 function handleEventLocal(aEvent) { 30 if (aEvent.type != "XULFrameLoaderCreated") { 31 return; 32 } 33 // Ignore <browser> element in about:preferences and any other special pages 34 if ("gBrowser" in aEvent.target.ownerGlobal) { 35 xulFrameLoaderCreatedCounter.numCalledSoFar++; 36 } 37 } 38 39 var NUM_DIFF_TAB_MODES = NUM_USER_CONTEXTS + 1; /** regular tab */ 40 41 add_setup(async function () { 42 await SpecialPowers.pushPrefEnv({ 43 set: [ 44 // Set the pref to true so we know exactly how many tabs should be restoring at 45 // any given time. This guarantees that a finishing load won't start another. 46 ["browser.sessionstore.restore_on_demand", true], 47 // Don't restore tabs lazily. 48 ["browser.sessionstore.restore_tabs_lazily", true], 49 // don't preload tabs so we don't have extra XULFrameLoaderCreated events 50 // firing 51 ["browser.newtab.preload", false], 52 ], 53 }); 54 55 requestLongerTimeout(7); 56 }); 57 58 function setupRemoteTypes() { 59 if (gFissionBrowser) { 60 remoteTypes = [ 61 "webIsolated=https://example.com", 62 "webIsolated=https://example.com^userContextId=1", 63 "webIsolated=https://example.com^userContextId=2", 64 "webIsolated=https://example.com^userContextId=3", 65 "webIsolated=https://example.org", 66 "webIsolated=https://example.org^userContextId=1", 67 "webIsolated=https://example.org^userContextId=2", 68 "webIsolated=https://example.org^userContextId=3", 69 ]; 70 } else { 71 remoteTypes = Array( 72 NUM_DIFF_TAB_MODES * 2 /** 2 is the number of non parent uris */ 73 ).fill("web"); 74 } 75 remoteTypes.push(...Array(NUM_DIFF_TAB_MODES * 2).fill(null)); // remote types for about: pages 76 77 forgetClosedWindows(); 78 is(SessionStore.getClosedWindowCount(), 0, "starting with no closed windows"); 79 } 80 /* 81 * 1. Open several tabs in different containers and in regular tabs 82 [page1, page2, page3] [ [(page1 - work) (page1 - home)] [(page2 - work) (page2 - home)] ] 83 * 2. Close the window 84 * 3. Restore session, window will have the following tabs 85 * [initial blank page, page1, page1-work, page1-home, page2, page2-work, page2-home] 86 * 4. Verify correct remote types and that XULFrameLoaderCreated gets fired correct number of times 87 */ 88 add_task(async function testRestore() { 89 setupRemoteTypes(); 90 let newWin = await promiseNewWindowLoaded(); 91 var regularPages = []; 92 var containerPages = {}; 93 // Go through all the test cases and open same set of urls in regular tabs and in container tabs 94 for (const uri of TEST_CASES) { 95 // Open a url in a regular tab 96 let regularPage = await openURIInRegularTab(uri, newWin); 97 regularPages.push(regularPage); 98 99 // Open the same url in different user contexts 100 for ( 101 var user_context_id = 1; 102 user_context_id <= NUM_USER_CONTEXTS; 103 user_context_id++ 104 ) { 105 let containerPage = await openURIInContainer( 106 uri, 107 newWin, 108 user_context_id 109 ); 110 containerPages[uri] = containerPage; 111 } 112 } 113 await TabStateFlusher.flushWindow(newWin); 114 115 // Close the window 116 await BrowserTestUtils.closeWindow(newWin); 117 await forceSaveState(); 118 119 is( 120 SessionStore.getClosedWindowCount(), 121 1, 122 "Should have restore data for the closed window" 123 ); 124 125 Assert.equal( 126 0, 127 (await UrlbarProviderOpenTabs.getDatabaseRegisteredOpenTabsForTests()) 128 .length, 129 "No registered open pages should be left" 130 ); 131 132 // Now restore the window 133 newWin = SessionStore.undoCloseWindow(0); 134 135 // Make sure to wait for the window to be restored. 136 await Promise.all([ 137 BrowserTestUtils.waitForEvent(newWin, "SSWindowStateReady"), 138 ]); 139 await BrowserTestUtils.waitForEvent( 140 newWin.gBrowser.tabContainer, 141 "SSTabRestored" 142 ); 143 144 var nonblank_pages_len = 145 TEST_CASES.length + NUM_USER_CONTEXTS * TEST_CASES.length; 146 is( 147 newWin.gBrowser.tabs.length, 148 nonblank_pages_len + 1 /* initial page */, 149 "Correct number of tabs restored" 150 ); 151 152 // Now we have pages opened in the following manner 153 // [blank page, page1, page1-work, page1-home, page2, page2-work, page2-home] 154 155 info(`Number of tabs restored: ${newWin.gBrowser.tabs.length}`); 156 var currRemoteType, expectedRemoteType; 157 let loaded; 158 for (var tab_idx = 1; tab_idx < nonblank_pages_len; ) { 159 info(`Accessing regular tab at index ${tab_idx}`); 160 var test_page_data = regularPages.shift(); 161 let regular_tab = newWin.gBrowser.tabs[tab_idx]; 162 let regular_browser = regular_tab.linkedBrowser; 163 164 // I would have used browserLoaded but for about:config it doesn't work 165 let ready = BrowserTestUtils.waitForCondition(async () => { 166 // Catch an error because the browser might change remoteness in between 167 // calls, so we will just wait for the document to finish loadig. 168 return SpecialPowers.spawn(regular_browser, [], () => { 169 return content.document.readyState == "complete"; 170 }).catch(console.error); 171 }); 172 newWin.gBrowser.selectedTab = regular_tab; 173 await TabStateFlusher.flush(regular_browser); 174 await ready; 175 176 currRemoteType = regular_browser.remoteType; 177 expectedRemoteType = remoteTypes.shift(); 178 is( 179 currRemoteType, 180 expectedRemoteType, 181 `correct remote type for regular tab with uri ${test_page_data.uri}` 182 ); 183 184 let page_uri = regular_browser.currentURI.spec; 185 info(`Current uri = ${page_uri}`); 186 187 // Iterate over container pages, starting after the regular page and ending before the next regular page 188 var userContextId = 1; 189 for ( 190 var container_tab_idx = tab_idx + 1; 191 container_tab_idx < tab_idx + 1 + NUM_USER_CONTEXTS; 192 container_tab_idx++, userContextId++ 193 ) { 194 info(`Accessing container tab at index ${container_tab_idx}`); 195 let container_tab = newWin.gBrowser.tabs[container_tab_idx]; 196 197 initXulFrameLoaderCreatedCounter(xulFrameLoaderCreatedCounter); 198 container_tab.ownerGlobal.gBrowser.addEventListener( 199 "XULFrameLoaderCreated", 200 handleEventLocal 201 ); 202 203 loaded = BrowserTestUtils.browserLoaded( 204 container_tab.linkedBrowser, 205 false, 206 test_page_data.uri 207 ); 208 209 newWin.gBrowser.selectedTab = container_tab; 210 await TabStateFlusher.flush(container_tab.linkedBrowser); 211 await loaded; 212 let uri = container_tab.linkedBrowser.currentURI.spec; 213 214 // Verify XULFrameLoaderCreated was fired once 215 is( 216 xulFrameLoaderCreatedCounter.numCalledSoFar, 217 1, 218 `XULFrameLoaderCreated was fired once, when restoring ${uri} in container ${userContextId} ` 219 ); 220 container_tab.ownerGlobal.gBrowser.removeEventListener( 221 "XULFrameLoaderCreated", 222 handleEventLocal 223 ); 224 225 // Verify correct remote type for container tab 226 currRemoteType = container_tab.linkedBrowser.remoteType; 227 expectedRemoteType = remoteTypes.shift(); 228 info( 229 `Remote type for container tab ${userContextId} is ${currRemoteType}` 230 ); 231 is( 232 currRemoteType, 233 expectedRemoteType, 234 "correct remote type for container tab" 235 ); 236 } 237 // Advance to the next regular page in our tabs list 238 tab_idx = container_tab_idx; 239 } 240 241 await BrowserTestUtils.closeWindow(newWin); 242 243 Assert.equal( 244 0, 245 (await UrlbarProviderOpenTabs.getDatabaseRegisteredOpenTabsForTests()) 246 .length, 247 "No registered open pages should be left" 248 ); 249 });