browser_async_remove_tab.js (6069B)
1 "use strict"; 2 3 async function createTabWithRandomValue(url) { 4 let tab = BrowserTestUtils.addTab(gBrowser, url); 5 let browser = tab.linkedBrowser; 6 await BrowserTestUtils.browserLoaded(browser, { wantLoad: url }); 7 8 // Set a random value. 9 let r = `rand-${Math.random()}`; 10 ss.setCustomTabValue(tab, "foobar", r); 11 12 // Flush to ensure there are no scheduled messages. 13 await TabStateFlusher.flush(browser); 14 15 return { tab, r }; 16 } 17 18 function isValueInClosedData(rval) { 19 return JSON.stringify(ss.getClosedTabDataForWindow(window)).includes(rval); 20 } 21 22 function restoreClosedTabWithValue(rval) { 23 let closedTabData = ss.getClosedTabDataForWindow(window); 24 let index = closedTabData.findIndex(function (data) { 25 return (data.state.extData && data.state.extData.foobar) == rval; 26 }); 27 28 if (index == -1) { 29 throw new Error("no closed tab found for given rval"); 30 } 31 32 return ss.undoCloseTab(window, index); 33 } 34 35 add_task(async function dont_save_empty_tabs() { 36 let { tab, r } = await createTabWithRandomValue("about:blank"); 37 38 // Remove the tab before the update arrives. 39 let promise = promiseRemoveTabAndSessionState(tab); 40 41 // No tab state worth saving. 42 ok(!isValueInClosedData(r), "closed tab not saved"); 43 await promise; 44 45 // Still no tab state worth saving. 46 ok(!isValueInClosedData(r), "closed tab not saved"); 47 }); 48 49 add_task(async function save_worthy_tabs_remote() { 50 let { tab, r } = await createTabWithRandomValue("https://example.com/"); 51 ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote"); 52 53 // Remove the tab before the update arrives. 54 let promise = promiseRemoveTabAndSessionState(tab); 55 56 // Tab state deemed worth saving. 57 ok(isValueInClosedData(r), "closed tab saved"); 58 await promise; 59 60 // Tab state still deemed worth saving. 61 ok(isValueInClosedData(r), "closed tab saved"); 62 }); 63 64 add_task(async function save_worthy_tabs_nonremote() { 65 let { tab, r } = await createTabWithRandomValue("about:robots"); 66 ok(!tab.linkedBrowser.isRemoteBrowser, "browser is not remote"); 67 68 // Remove the tab before the update arrives. 69 let promise = promiseRemoveTabAndSessionState(tab); 70 71 // Tab state deemed worth saving. 72 ok(isValueInClosedData(r), "closed tab saved"); 73 await promise; 74 75 // Tab state still deemed worth saving. 76 ok(isValueInClosedData(r), "closed tab saved"); 77 }); 78 79 add_task(async function save_worthy_tabs_remote_final() { 80 let { tab, r } = await createTabWithRandomValue("about:blank"); 81 let browser = tab.linkedBrowser; 82 ok(browser.isRemoteBrowser, "browser is remote"); 83 84 // Replace about:blank with a new remote page. 85 let entryReplaced = promiseOnHistoryReplaceEntry(browser); 86 browser.loadURI(Services.io.newURI("https://example.com/"), { 87 triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), 88 }); 89 await entryReplaced; 90 91 // Remotness shouldn't have changed. 92 ok(browser.isRemoteBrowser, "browser is still remote"); 93 94 // Remove the tab before the update arrives. 95 await promiseRemoveTabAndSessionState(tab); 96 97 // Turns out there is a tab state worth saving. 98 ok(isValueInClosedData(r), "closed tab saved"); 99 }); 100 101 add_task(async function save_worthy_tabs_nonremote_final() { 102 let { tab, r } = await createTabWithRandomValue("about:blank"); 103 let browser = tab.linkedBrowser; 104 ok(browser.isRemoteBrowser, "browser is remote"); 105 106 // Replace about:blank with a non-remote entry. 107 BrowserTestUtils.startLoadingURIString(browser, "about:robots"); 108 await BrowserTestUtils.browserLoaded(browser); 109 ok(!browser.isRemoteBrowser, "browser is not remote anymore"); 110 111 // Remove the tab before the update arrives. 112 await promiseRemoveTabAndSessionState(tab); 113 114 // Turns out there is a tab state worth saving. 115 ok(isValueInClosedData(r), "closed tab saved"); 116 }); 117 118 add_task(async function dont_save_empty_tabs_final() { 119 let { tab, r } = await createTabWithRandomValue("https://example.com/"); 120 let browser = tab.linkedBrowser; 121 ok(browser.isRemoteBrowser, "browser is remote"); 122 123 // Replace the current page with an about:blank entry. 124 let entryReplaced = promiseOnHistoryReplaceEntry(browser); 125 126 // We're doing a cross origin navigation, so we can't reliably use a 127 // SpecialPowers task here. Instead we just emulate a location.replace() call. 128 browser.loadURI(Services.io.newURI("about:blank"), { 129 loadFlags: 130 Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT | 131 Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY, 132 triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), 133 }); 134 135 await entryReplaced; 136 137 // Remove the tab before the update arrives. 138 await promiseRemoveTabAndSessionState(tab); 139 140 // Turns out we don't want to save the tab state. 141 ok(!isValueInClosedData(r), "closed tab not saved"); 142 }); 143 144 add_task(async function undo_worthy_tabs() { 145 let { tab, r } = await createTabWithRandomValue("https://example.com/"); 146 ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote"); 147 148 // Remove the tab before the update arrives. 149 let promise = promiseRemoveTabAndSessionState(tab); 150 151 // Tab state deemed worth saving. 152 ok(isValueInClosedData(r), "closed tab saved"); 153 154 // Restore the closed tab before receiving its final message. 155 tab = restoreClosedTabWithValue(r); 156 157 // Wait for the final update message. 158 await promise; 159 160 // Check we didn't add the tab back to the closed list. 161 ok(!isValueInClosedData(r), "tab no longer closed"); 162 163 // Cleanup. 164 BrowserTestUtils.removeTab(tab); 165 }); 166 167 add_task(async function forget_worthy_tabs_remote() { 168 let { tab, r } = await createTabWithRandomValue("https://example.com/"); 169 ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote"); 170 171 // Remove the tab before the update arrives. 172 let promise = promiseRemoveTabAndSessionState(tab); 173 174 // Tab state deemed worth saving. 175 ok(isValueInClosedData(r), "closed tab saved"); 176 177 // Forget the closed tab. 178 ss.forgetClosedTab(window, 0); 179 180 // Wait for the final update message. 181 await promise; 182 183 // Check we didn't add the tab back to the closed list. 184 ok(!isValueInClosedData(r), "we forgot about the tab"); 185 });