browser_async_window_flushing.js (6878B)
1 "use strict"; 2 3 const PAGE = "http://example.com/"; 4 5 /** 6 * Tests that if we initially discard a window as not interesting 7 * to save in the closed windows array, that we revisit that decision 8 * after a window flush has completed. 9 */ 10 add_task(async function test_add_interesting_window() { 11 // We want to suppress all non-final updates from the browser tabs 12 // so as to eliminate any racy-ness with this test. 13 await pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]); 14 15 // Depending on previous tests, we might already have some closed 16 // windows stored. We'll use its length to determine whether or not 17 // the window was added or not. 18 let initialClosedWindows = ss.getClosedWindowCount(); 19 20 // Make sure we can actually store another closed window 21 await pushPrefs([ 22 "browser.sessionstore.max_windows_undo", 23 initialClosedWindows + 1, 24 ]); 25 26 // Create a new browser window. Since the default window will start 27 // at about:blank, SessionStore should find this tab (and therefore the 28 // whole window) uninteresting, and should not initially put it into 29 // the closed windows array. 30 let newWin = await BrowserTestUtils.openNewBrowserWindow(); 31 32 let browser = newWin.gBrowser.selectedBrowser; 33 34 // Send a message that will cause the content to change its location 35 // to someplace more interesting. We've disabled auto updates from 36 // the browser, so the parent won't know about this 37 await SpecialPowers.spawn(browser, [PAGE], async function (newPage) { 38 content.location = newPage; 39 }); 40 41 await promiseOnHistoryReplaceEntry(browser); 42 43 // Clear out the userTypedValue so that the new window looks like 44 // it's really not worth restoring. 45 browser.userTypedValue = null; 46 47 // Once this windowClosed Promise resolves, we should have finished 48 // the flush and revisited our decision to put this window into 49 // the closed windows array. 50 let windowClosed = BrowserTestUtils.windowClosed(newWin); 51 52 let handled = false; 53 whenDomWindowClosedHandled(() => { 54 // SessionStore's onClose handler should have just run. 55 let currentClosedWindows = ss.getClosedWindowCount(); 56 is( 57 currentClosedWindows, 58 initialClosedWindows, 59 "We should not have added the window to the closed windows array" 60 ); 61 62 handled = true; 63 }); 64 65 // Ok, let's close the window. 66 newWin.close(); 67 68 await windowClosed; 69 70 ok(handled, "domwindowclosed should already be handled here"); 71 72 // The window flush has finished 73 let currentClosedWindows = ss.getClosedWindowCount(); 74 is( 75 currentClosedWindows, 76 initialClosedWindows + 1, 77 "We should have added the window to the closed windows array" 78 ); 79 }); 80 81 /** 82 * Tests that if we initially store a closed window as interesting 83 * to save in the closed windows array, that we revisit that decision 84 * after a window flush has completed, and stop storing a window that 85 * we've deemed no longer interesting. 86 */ 87 add_task(async function test_remove_uninteresting_window() { 88 // We want to suppress all non-final updates from the browser tabs 89 // so as to eliminate any racy-ness with this test. 90 await pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]); 91 92 // Depending on previous tests, we might already have some closed 93 // windows stored. We'll use its length to determine whether or not 94 // the window was added or not. 95 let initialClosedWindows = ss.getClosedWindowCount(); 96 97 // Make sure we can actually store another closed window 98 await pushPrefs([ 99 "browser.sessionstore.max_windows_undo", 100 initialClosedWindows + 1, 101 ]); 102 103 let newWin = await BrowserTestUtils.openNewBrowserWindow(); 104 105 // Now browse the initial tab of that window to an interesting 106 // site. 107 let tab = newWin.gBrowser.selectedTab; 108 let browser = tab.linkedBrowser; 109 BrowserTestUtils.startLoadingURIString(browser, PAGE); 110 111 await BrowserTestUtils.browserLoaded(browser, false, PAGE); 112 await TabStateFlusher.flush(browser); 113 114 // Send a message that will cause the content to purge its 115 // history entries and make itself seem uninteresting. 116 await SpecialPowers.spawn(browser, [], async function () { 117 // Epic hackery to make this browser seem suddenly boring. 118 docShell.setCurrentURIForSessionStore(Services.io.newURI("about:blank")); 119 }); 120 121 let { sessionHistory } = browser.browsingContext; 122 sessionHistory.purgeHistory(sessionHistory.count); 123 124 // Once this windowClosed Promise resolves, we should have finished 125 // the flush and revisited our decision to put this window into 126 // the closed windows array. 127 let windowClosed = BrowserTestUtils.windowClosed(newWin); 128 129 let handled = false; 130 whenDomWindowClosedHandled(() => { 131 // SessionStore's onClose handler should have just run. 132 let currentClosedWindows = ss.getClosedWindowCount(); 133 is( 134 currentClosedWindows, 135 initialClosedWindows + 1, 136 "We should have added the window to the closed windows array" 137 ); 138 139 handled = true; 140 }); 141 142 // Ok, let's close the window. 143 newWin.close(); 144 145 await windowClosed; 146 147 ok(handled, "domwindowclosed should already be handled here"); 148 149 // The window flush has finished 150 let currentClosedWindows = ss.getClosedWindowCount(); 151 is( 152 currentClosedWindows, 153 initialClosedWindows, 154 "We should have removed the window from the closed windows array" 155 ); 156 }); 157 158 /** 159 * Tests that when we close a window, it is immediately removed from the 160 * _windows array. 161 */ 162 add_task(async function test_synchronously_remove_window_state() { 163 // Depending on previous tests, we might already have some closed 164 // windows stored. We'll use its length to determine whether or not 165 // the window was added or not. 166 let state = JSON.parse(ss.getBrowserState()); 167 ok(state, "Make sure we can get the state"); 168 let initialWindows = state.windows.length; 169 170 // Open a new window and send the first tab somewhere 171 // interesting. 172 let newWin = await BrowserTestUtils.openNewBrowserWindow(); 173 let browser = newWin.gBrowser.selectedBrowser; 174 BrowserTestUtils.startLoadingURIString(browser, PAGE); 175 await BrowserTestUtils.browserLoaded(browser, false, PAGE); 176 await TabStateFlusher.flush(browser); 177 178 state = JSON.parse(ss.getBrowserState()); 179 is( 180 state.windows.length, 181 initialWindows + 1, 182 "The new window to be in the state" 183 ); 184 185 // Now close the window, and make sure that the window was removed 186 // from the windows list from the SessionState. We're specifically 187 // testing the case where the window is _not_ removed in between 188 // the close-initiated flush request and the flush response. 189 let windowClosed = BrowserTestUtils.windowClosed(newWin); 190 newWin.close(); 191 192 state = JSON.parse(ss.getBrowserState()); 193 is( 194 state.windows.length, 195 initialWindows, 196 "The new window should have been removed from the state" 197 ); 198 199 // Wait for our window to go away 200 await windowClosed; 201 });