browser_promisefocus.js (8279B)
1 // Opens another window and switches focus between them. 2 add_task(async function test_window_focus() { 3 let window2 = await BrowserTestUtils.openNewBrowserWindow(); 4 ok(!document.hasFocus(), "hasFocus after open second window"); 5 ok(window2.document.hasFocus(), "hasFocus after open second window"); 6 is( 7 Services.focus.activeWindow, 8 window2, 9 "activeWindow after open second window" 10 ); 11 is( 12 Services.focus.focusedWindow, 13 window2, 14 "focusedWindow after open second window" 15 ); 16 17 await SimpleTest.promiseFocus(window); 18 ok(document.hasFocus(), "hasFocus after promiseFocus on window"); 19 ok(!window2.document.hasFocus(), "hasFocus after promiseFocus on window"); 20 is( 21 Services.focus.activeWindow, 22 window, 23 "activeWindow after promiseFocus on window" 24 ); 25 is( 26 Services.focus.focusedWindow, 27 window, 28 "focusedWindow after promiseFocus on window" 29 ); 30 31 await SimpleTest.promiseFocus(window2); 32 ok(!document.hasFocus(), "hasFocus after promiseFocus on second window"); 33 ok( 34 window2.document.hasFocus(), 35 "hasFocus after promiseFocus on second window" 36 ); 37 is( 38 Services.focus.activeWindow, 39 window2, 40 "activeWindow after promiseFocus on second window" 41 ); 42 is( 43 Services.focus.focusedWindow, 44 window2, 45 "focusedWindow after promiseFocus on second window" 46 ); 47 48 await BrowserTestUtils.closeWindow(window2); 49 50 // If the window is already focused, this should just return. 51 await SimpleTest.promiseFocus(window); 52 await SimpleTest.promiseFocus(window); 53 }); 54 55 // Opens two tabs and ensures that focus can be switched to the browser. 56 add_task(async function test_tab_focus() { 57 let tab1 = await BrowserTestUtils.openNewForegroundTab( 58 gBrowser, 59 "data:text/html,<input>" 60 ); 61 62 let tab2 = await BrowserTestUtils.openNewForegroundTab( 63 gBrowser, 64 "data:text/html,<input>" 65 ); 66 67 gURLBar.focus(); 68 69 await SimpleTest.promiseFocus(tab2.linkedBrowser); 70 is( 71 document.activeElement, 72 tab2.linkedBrowser, 73 "Browser is focused after promiseFocus" 74 ); 75 76 await SpecialPowers.spawn(tab1.linkedBrowser, [], () => { 77 Assert.equal( 78 Services.focus.activeBrowsingContext, 79 null, 80 "activeBrowsingContext in child process in hidden tab" 81 ); 82 Assert.equal( 83 Services.focus.focusedWindow, 84 null, 85 "focusedWindow in child process in hidden tab" 86 ); 87 Assert.ok( 88 !content.document.hasFocus(), 89 "hasFocus in child process in hidden tab" 90 ); 91 }); 92 93 await SpecialPowers.spawn(tab2.linkedBrowser, [], () => { 94 Assert.equal( 95 Services.focus.activeBrowsingContext, 96 content.browsingContext, 97 "activeBrowsingContext in child process in visible tab" 98 ); 99 Assert.equal( 100 Services.focus.focusedWindow, 101 content.window, 102 "focusedWindow in child process in visible tab" 103 ); 104 Assert.ok( 105 content.document.hasFocus(), 106 "hasFocus in child process in visible tab" 107 ); 108 }); 109 110 BrowserTestUtils.removeTab(tab1); 111 BrowserTestUtils.removeTab(tab2); 112 }); 113 114 // Opens a document with a nested hierarchy of frames using initChildFrames and 115 // focuses each child iframe in turn. 116 add_task(async function test_subframes_focus() { 117 let tab = await BrowserTestUtils.openNewForegroundTab( 118 gBrowser, 119 OOP_BASE_PAGE_URI 120 ); 121 122 const markup = "<input>"; 123 124 let browser = tab.linkedBrowser; 125 let browsingContexts = await initChildFrames(browser, markup); 126 127 for (let blurSubframe of [true, false]) { 128 for (let index = browsingContexts.length - 1; index >= 0; index--) { 129 let bc = browsingContexts[index]; 130 131 // Focus each browsing context in turn. Do this twice, once when the window 132 // is not already focused, and once when it is already focused. 133 for (let step = 0; step < 2; step++) { 134 let desc = 135 "within child frame " + 136 index + 137 " step " + 138 step + 139 " blur subframe " + 140 blurSubframe + 141 " "; 142 143 info(desc + "start"); 144 await SimpleTest.promiseFocus(bc, false, blurSubframe); 145 146 let expectedFocusedBC = bc; 147 // Becuase we are iterating backwards through the iframes, when we get to a frame 148 // that contains the iframe we just tested, focusing it will keep the child 149 // iframe focused as well, so we need to account for this when verifying which 150 // child iframe is focused. For the root frame (index 0), the iframe nested 151 // two items down will actually be focused. 152 // If blurSubframe is true however, the iframe focus in the parent will be cleared, 153 // so the focused window should be the parent instead. 154 if (!blurSubframe) { 155 if (index == 0) { 156 expectedFocusedBC = browsingContexts[index + 2]; 157 } else if (index == 3 || index == 1) { 158 expectedFocusedBC = browsingContexts[index + 1]; 159 } 160 } 161 is( 162 Services.focus.focusedContentBrowsingContext, 163 expectedFocusedBC, 164 desc + 165 " focusedContentBrowsingContext" + 166 ":: " + 167 Services.focus.focusedContentBrowsingContext?.id + 168 "," + 169 expectedFocusedBC?.id 170 ); 171 172 // If the processes don't match, then the child iframe is an out-of-process iframe. 173 let oop = 174 expectedFocusedBC.currentWindowGlobal.osPid != 175 bc.currentWindowGlobal.osPid; 176 await SpecialPowers.spawn( 177 bc, 178 [ 179 index, 180 desc, 181 expectedFocusedBC != bc ? expectedFocusedBC : null, 182 oop, 183 ], 184 (num, descChild, childBC, isOop) => { 185 Assert.equal( 186 Services.focus.activeBrowsingContext, 187 content.browsingContext.top, 188 descChild + "activeBrowsingContext" 189 ); 190 Assert.ok( 191 content.document.hasFocus(), 192 descChild + "hasFocus: " + content.browsingContext.id 193 ); 194 195 // If a child browsing context is expected to be focused, the focusedWindow 196 // should be set to that instead and the active element should be an iframe. 197 // Otherwise, the focused window should be this window, and the active 198 // element should be the document's body element. 199 if (childBC) { 200 // The frame structure is: 201 // A1 202 // -> B 203 // -> A2 204 // where A and B are two processes. The frame A2 starts out focused. When B is 205 // focused, A1's focus is updated correctly. 206 207 // In Fission mode, childBC.window returns a non-null proxy even if OOP 208 if (isOop) { 209 Assert.equal( 210 Services.focus.focusedWindow, 211 null, 212 descChild + "focusedWindow" 213 ); 214 Assert.ok(!childBC.docShell, descChild + "childBC.docShell"); 215 } else { 216 Assert.equal( 217 Services.focus.focusedWindow, 218 childBC.window, 219 descChild + "focusedWindow" 220 ); 221 } 222 Assert.equal( 223 content.document.activeElement.localName, 224 "iframe", 225 descChild + "activeElement" 226 ); 227 } else { 228 Assert.equal( 229 Services.focus.focusedWindow, 230 content.window, 231 descChild + "focusedWindow" 232 ); 233 Assert.equal( 234 content.document.activeElement, 235 content.document.body, 236 descChild + "activeElement" 237 ); 238 } 239 } 240 ); 241 } 242 } 243 } 244 245 // Focus the top window without blurring the browser. 246 await SimpleTest.promiseFocus(window, false, false); 247 is( 248 document.activeElement.localName, 249 "browser", 250 "focus after blurring browser blur subframe false" 251 ); 252 253 // Now, focus the top window, blurring the browser. 254 await SimpleTest.promiseFocus(window, false, true); 255 is( 256 document.activeElement, 257 document.body, 258 "focus after blurring browser blur subframe true" 259 ); 260 261 BrowserTestUtils.removeTab(tab); 262 });