test_switch_window.py (10608B)
1 # This Source Code Form is subject to the terms of the Mozilla ublic 2 # License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 # You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import sys 6 7 from urllib.parse import quote 8 9 from marionette_driver import By, Wait 10 from marionette_driver.keys import Keys 11 12 from marionette_harness import ( 13 MarionetteTestCase, 14 WindowManagerMixin, 15 ) 16 17 18 def inline(doc): 19 return "data:text/html;charset=utf-8,{}".format(quote(doc)) 20 21 22 class TestSwitchToWindowContent(WindowManagerMixin, MarionetteTestCase): 23 def setUp(self): 24 super(TestSwitchToWindowContent, self).setUp() 25 26 if self.marionette.session_capabilities["platformName"] == "mac": 27 self.mod_key = Keys.META 28 else: 29 self.mod_key = Keys.CONTROL 30 31 self.selected_tab_index = self.get_selected_tab_index() 32 33 def tearDown(self): 34 self.close_all_tabs() 35 36 super(TestSwitchToWindowContent, self).tearDown() 37 38 def get_selected_tab_index(self): 39 with self.marionette.using_context("chrome"): 40 return self.marionette.execute_script( 41 """ 42 const { AppConstants } = ChromeUtils.importESModule( 43 "resource://gre/modules/AppConstants.sys.mjs" 44 ); 45 46 let win = null; 47 48 if (AppConstants.MOZ_APP_NAME == "fennec") { 49 win = Services.wm.getMostRecentWindow("navigator:browser"); 50 } else { 51 const { BrowserWindowTracker } = ChromeUtils.importESModule( 52 "resource:///modules/BrowserWindowTracker.sys.mjs" 53 ); 54 win = BrowserWindowTracker.getTopWindow(); 55 } 56 57 let tabBrowser = null; 58 59 // Fennec 60 if (win.BrowserApp) { 61 tabBrowser = win.BrowserApp; 62 63 // Firefox 64 } else if (win.gBrowser) { 65 tabBrowser = win.gBrowser; 66 67 } else { 68 return null; 69 } 70 71 for (let i = 0; i < tabBrowser.tabs.length; i++) { 72 if (tabBrowser.tabs[i] == tabBrowser.selectedTab) { 73 return i; 74 } 75 } 76 """ 77 ) 78 79 def test_switch_tabs_with_focus_change(self): 80 new_tab = self.open_tab(focus=True) 81 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 82 self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index) 83 84 # Switch to new tab first because it is already selected 85 self.marionette.switch_to_window(new_tab) 86 self.assertEqual(self.marionette.current_window_handle, new_tab) 87 self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index) 88 89 # Switch to original tab by explicitely setting the focus 90 self.marionette.switch_to_window(self.start_tab, focus=True) 91 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 92 self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index) 93 94 self.marionette.switch_to_window(new_tab) 95 self.marionette.close() 96 97 self.marionette.switch_to_window(self.start_tab) 98 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 99 self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index) 100 101 def test_switch_tabs_in_different_windows_with_focus_change(self): 102 new_tab1 = self.open_tab(focus=True) 103 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 104 self.assertEqual(self.get_selected_tab_index(), 1) 105 106 # Switch to new tab first which is already selected 107 self.marionette.switch_to_window(new_tab1) 108 self.assertEqual(self.marionette.current_window_handle, new_tab1) 109 self.assertEqual(self.get_selected_tab_index(), 1) 110 111 # Open a new browser window with a single focused tab already focused 112 with self.marionette.using_context("content"): 113 new_tab2 = self.open_window(focus=True) 114 self.assertEqual(self.marionette.current_window_handle, new_tab1) 115 self.assertEqual(self.get_selected_tab_index(), 0) 116 117 # Switch to that tab 118 self.marionette.switch_to_window(new_tab2) 119 self.assertEqual(self.marionette.current_window_handle, new_tab2) 120 self.assertEqual(self.get_selected_tab_index(), 0) 121 122 # Switch back to the 2nd tab of the original window and setting the focus 123 self.marionette.switch_to_window(new_tab1, focus=True) 124 self.assertEqual(self.marionette.current_window_handle, new_tab1) 125 self.assertEqual(self.get_selected_tab_index(), 1) 126 127 self.marionette.switch_to_window(new_tab2) 128 self.marionette.close() 129 130 self.marionette.switch_to_window(new_tab1) 131 self.marionette.close() 132 133 self.marionette.switch_to_window(self.start_tab) 134 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 135 self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index) 136 137 def test_switch_tabs_without_focus_change(self): 138 new_tab = self.open_tab(focus=True) 139 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 140 self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index) 141 142 # Switch to new tab first because it is already selected 143 self.marionette.switch_to_window(new_tab) 144 self.assertEqual(self.marionette.current_window_handle, new_tab) 145 146 # Switch to original tab by explicitely not setting the focus 147 self.marionette.switch_to_window(self.start_tab, focus=False) 148 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 149 self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index) 150 151 self.marionette.switch_to_window(new_tab) 152 self.marionette.close() 153 154 self.marionette.switch_to_window(self.start_tab) 155 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 156 self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index) 157 158 def test_switch_to_unloaded_tab(self): 159 first_page = inline("<p>foo") 160 second_page = inline("<p>bar") 161 162 self.assertEqual(len(self.marionette.window_handles), 1) 163 self.marionette.navigate(first_page) 164 165 new_tab = self.open_tab() 166 self.assertEqual(self.marionette.current_window_handle, self.start_tab) 167 self.assertEqual(self.get_selected_tab_index(), self.selected_tab_index) 168 169 self.marionette.switch_to_window(new_tab) 170 self.assertEqual(self.marionette.current_window_handle, new_tab) 171 self.assertNotEqual(self.get_selected_tab_index(), self.selected_tab_index) 172 self.marionette.navigate(second_page) 173 174 # The restart will cause the background tab to stay unloaded 175 self.marionette.restart(in_app=True) 176 self.assertEqual(len(self.marionette.window_handles), 2) 177 178 # Refresh window handles 179 window_handles = self.marionette.window_handles 180 self.assertEqual(len(window_handles), 2) 181 182 current_tab = self.marionette.current_window_handle 183 [other_tab] = filter(lambda handle: handle != current_tab, window_handles) 184 185 Wait(self.marionette, timeout=5).until( 186 lambda _: self.marionette.get_url() == second_page, 187 message="Expected URL in the second tab has been loaded", 188 ) 189 190 self.marionette.switch_to_window(other_tab) 191 Wait(self.marionette, timeout=5).until( 192 lambda _: self.marionette.get_url() == first_page, 193 message="Expected URL in the first tab has been loaded", 194 ) 195 196 def test_switch_from_content_to_chrome_window_should_not_change_selected_tab(self): 197 new_tab = self.open_tab(focus=True) 198 199 self.marionette.switch_to_window(new_tab) 200 self.assertEqual(self.marionette.current_window_handle, new_tab) 201 new_tab_index = self.get_selected_tab_index() 202 203 self.marionette.switch_to_window(self.start_window) 204 self.assertEqual(self.marionette.current_window_handle, new_tab) 205 self.assertEqual(self.get_selected_tab_index(), new_tab_index) 206 207 def test_switch_to_new_private_browsing_tab(self): 208 # Test that tabs (browsers) are correctly registered for a newly opened 209 # private browsing window/tab. This has to also happen without explicitely 210 # switching to the tab itself before using any commands in content scope. 211 # 212 # Note: Not sure why this only affects private browsing windows only. 213 new_tab = self.open_tab(focus=True) 214 self.marionette.switch_to_window(new_tab) 215 216 def open_private_browsing_window_firefox(): 217 with self.marionette.using_context("content"): 218 self.marionette.find_element(By.ID, "startPrivateBrowsing").click() 219 220 def open_private_browsing_tab_fennec(): 221 with self.marionette.using_context("content"): 222 self.marionette.find_element(By.ID, "newPrivateTabLink").click() 223 224 with self.marionette.using_context("content"): 225 self.marionette.navigate("about:privatebrowsing") 226 if self.marionette.session_capabilities["browserName"] == "fennec": 227 new_pb_tab = self.open_tab(open_private_browsing_tab_fennec) 228 else: 229 new_pb_tab = self.open_tab(open_private_browsing_window_firefox) 230 231 self.marionette.switch_to_window(new_pb_tab) 232 self.assertEqual(self.marionette.current_window_handle, new_pb_tab) 233 234 self.marionette.execute_script(" return true; ") 235 236 def test_switch_to_window_after_remoteness_change(self): 237 # Test that after a remoteness change (and a browsing context swap) 238 # marionette can still switch to tabs correctly. 239 with self.marionette.using_context("content"): 240 # about:robots runs in a different process and will trigger a 241 # remoteness change with or without fission. 242 self.marionette.navigate("about:robots") 243 244 about_robots_tab = self.marionette.current_window_handle 245 246 # Open a new tab and switch to it before trying to switch back to the 247 # initial tab. 248 tab2 = self.open_tab(focus=True) 249 self.marionette.switch_to_window(tab2) 250 self.marionette.close() 251 252 self.marionette.switch_to_window(about_robots_tab) 253 self.assertEqual(self.marionette.current_window_handle, about_robots_tab)