browser_TabManager.js (7306B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { PromptTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/PromptTestUtils.sys.mjs" 8 ); 9 10 const { TabManager } = ChromeUtils.importESModule( 11 "chrome://remote/content/shared/TabManager.sys.mjs" 12 ); 13 14 const BUILDER_URL = "https://example.com/document-builder.sjs?html="; 15 16 const BEFOREUNLOAD_MARKUP = ` 17 <html> 18 <head> 19 <script> 20 window.onbeforeunload = function() { 21 return true; 22 }; 23 </script> 24 </head> 25 <body>TEST PAGE</body> 26 </html> 27 `; 28 const BEFOREUNLOAD_URL = BUILDER_URL + encodeURI(BEFOREUNLOAD_MARKUP); 29 30 const FRAME_URL = "https://example.com/document-builder.sjs?html=frame"; 31 const FRAME_MARKUP = `<iframe src="${encodeURI(FRAME_URL)}"></iframe>`; 32 const TEST_URL = BUILDER_URL + encodeURI(FRAME_MARKUP); 33 34 add_task(async function test_addTab_focus() { 35 let tabsCount = gBrowser.tabs.length; 36 37 let newTab1, newTab2, newTab3; 38 try { 39 newTab1 = await TabManager.addTab({ focus: true }); 40 41 ok(gBrowser.tabs.includes(newTab1), "A new tab was created"); 42 is(gBrowser.tabs.length, tabsCount + 1); 43 is(gBrowser.selectedTab, newTab1, "Tab added with focus: true is selected"); 44 45 newTab2 = await TabManager.addTab({ focus: false }); 46 47 ok(gBrowser.tabs.includes(newTab2), "A new tab was created"); 48 is(gBrowser.tabs.length, tabsCount + 2); 49 is( 50 gBrowser.selectedTab, 51 newTab1, 52 "Tab added with focus: false is not selected" 53 ); 54 55 newTab3 = await TabManager.addTab(); 56 57 ok(gBrowser.tabs.includes(newTab3), "A new tab was created"); 58 is(gBrowser.tabs.length, tabsCount + 3); 59 is( 60 gBrowser.selectedTab, 61 newTab1, 62 "Tab added with no focus parameter is not selected (defaults to false)" 63 ); 64 } finally { 65 gBrowser.removeTab(newTab1); 66 gBrowser.removeTab(newTab2); 67 gBrowser.removeTab(newTab3); 68 } 69 }); 70 71 add_task(async function test_addTab_referenceTab() { 72 let tab1, tab2, tab3, tab4; 73 try { 74 tab1 = await TabManager.addTab(); 75 // Add a second tab with no referenceTab, should be added at the end. 76 tab2 = await TabManager.addTab(); 77 // Add a third tab with tab1 as referenceTab, should be added right after tab1. 78 tab3 = await TabManager.addTab({ referenceTab: tab1 }); 79 // Add a fourth tab with tab2 as referenceTab, should be added right after tab2. 80 tab4 = await TabManager.addTab({ referenceTab: tab2 }); 81 82 // Check that the tab order is as expected: tab1 > tab3 > tab2 > tab4 83 const tab1Index = gBrowser.tabs.indexOf(tab1); 84 is(gBrowser.tabs[tab1Index + 1], tab3); 85 is(gBrowser.tabs[tab1Index + 2], tab2); 86 is(gBrowser.tabs[tab1Index + 3], tab4); 87 } finally { 88 gBrowser.removeTab(tab1); 89 gBrowser.removeTab(tab2); 90 gBrowser.removeTab(tab3); 91 gBrowser.removeTab(tab4); 92 } 93 }); 94 95 add_task(async function test_addTab_window() { 96 const win1 = await BrowserTestUtils.openNewBrowserWindow(); 97 const win2 = await BrowserTestUtils.openNewBrowserWindow(); 98 try { 99 // openNewBrowserWindow should ensure the new window is focused. 100 is(Services.wm.getMostRecentBrowserWindow(null), win2); 101 102 const newTab1 = await TabManager.addTab({ window: win1 }); 103 is( 104 newTab1.ownerGlobal, 105 win1, 106 "The new tab was opened in the specified window" 107 ); 108 109 const newTab2 = await TabManager.addTab({ window: win2 }); 110 is( 111 newTab2.ownerGlobal, 112 win2, 113 "The new tab was opened in the specified window" 114 ); 115 116 const newTab3 = await TabManager.addTab(); 117 is( 118 newTab3.ownerGlobal, 119 win2, 120 "The new tab was opened in the foreground window" 121 ); 122 } finally { 123 await BrowserTestUtils.closeWindow(win1); 124 await BrowserTestUtils.closeWindow(win2); 125 } 126 }); 127 128 add_task(async function test_getTabForBrowsingContext() { 129 const tab = await TabManager.addTab(); 130 try { 131 const browser = tab.linkedBrowser; 132 133 info(`Navigate to ${TEST_URL}`); 134 await loadURL(browser, TEST_URL); 135 136 const contexts = browser.browsingContext.getAllBrowsingContextsInSubtree(); 137 is(TabManager.getTabForBrowsingContext(contexts[0]), tab); 138 is(TabManager.getTabForBrowsingContext(contexts[1]), tab); 139 is(TabManager.getTabForBrowsingContext(null), null); 140 } finally { 141 gBrowser.removeTab(tab); 142 } 143 }); 144 145 add_task(async function test_getTabsForWindow() { 146 // Open a new window with 3 tabs in total. 147 const win1 = await BrowserTestUtils.openNewBrowserWindow(); 148 BrowserTestUtils.addTab(win1.gBrowser, TEST_URL); 149 BrowserTestUtils.addTab(win1.gBrowser, TEST_URL); 150 151 try { 152 is( 153 TabManager.getTabsForWindow(win1).length, 154 3, 155 "Got expected amount of open tabs" 156 ); 157 ok( 158 TabManager.getTabsForWindow(win1).every(tab => 159 win1.gBrowser.tabs.includes(tab) 160 ), 161 "Expected tabs were returned" 162 ); 163 } finally { 164 await BrowserTestUtils.closeWindow(win1); 165 } 166 }); 167 168 add_task(async function test_removeTab() { 169 // Tab not defined. 170 await TabManager.removeTab(null); 171 }); 172 173 add_task(async function test_removeTab_skipPermitUnload() { 174 await SpecialPowers.pushPrefEnv({ 175 set: [["dom.require_user_interaction_for_beforeunload", false]], 176 }); 177 178 let tab; 179 180 // Test that unload prompts are shown 181 for (const skipPermitUnload of [undefined, false]) { 182 info(`Test with skipPermitUnload as ${skipPermitUnload}`); 183 184 tab = await TabManager.addTab(); 185 try { 186 const browser = tab.linkedBrowser; 187 await loadURL(browser, BEFOREUNLOAD_URL); 188 189 const unloadDialogPromise = PromptTestUtils.handleNextPrompt( 190 browser, 191 { 192 modalType: Ci.nsIPrompt.MODAL_TYPE_CONTENT, 193 promptType: "confirmEx", 194 }, 195 // Click the ok button. 196 { buttonNumClick: 0 } 197 ); 198 199 const options = {}; 200 if (skipPermitUnload !== undefined) { 201 options.skipPermitUnload = skipPermitUnload; 202 } 203 204 await TabManager.removeTab(tab, options); 205 await unloadDialogPromise; 206 207 Assert.equal(gBrowser.tabs.length, 1, "Should have left one tab open"); 208 } finally { 209 gBrowser.removeTab(tab); 210 } 211 } 212 213 // Test that skipping the unload prompt works 214 tab = await TabManager.addTab(); 215 try { 216 const browser = tab.linkedBrowser; 217 await loadURL(browser, BEFOREUNLOAD_URL); 218 219 let closePromise = BrowserTestUtils.waitForTabClosing(tab); 220 await TabManager.removeTab(tab, { skipPermitUnload: true }); 221 await closePromise; 222 223 Assert.equal(gBrowser.tabs.length, 1, "Should have left one tab open"); 224 } finally { 225 gBrowser.removeTab(tab); 226 } 227 }); 228 229 add_task(async function test_selectTab() { 230 // Tab not defined. 231 await TabManager.selectTab(null); 232 }); 233 234 add_task(async function test_tabs() { 235 // Open two more tabs, one in the current and the other in a new window. 236 const tab = BrowserTestUtils.addTab(gBrowser, TEST_URL); 237 const win1 = await BrowserTestUtils.openNewBrowserWindow(); 238 239 const expectedTabs = [...gBrowser.tabs, ...win1.gBrowser.tabs]; 240 241 try { 242 is(TabManager.allTabs.length, 3, "Got expected amount of open tabs"); 243 ok( 244 expectedTabs.every(tab => TabManager.allTabs.includes(tab)), 245 "Expected tabs were returned" 246 ); 247 } finally { 248 await BrowserTestUtils.closeWindow(win1); 249 gBrowser.removeTab(tab); 250 } 251 });