1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import firefox_puppeteer.errors as errors
from firefox_puppeteer import PuppeteerMixin
from firefox_puppeteer.ui.windows import BaseWindow
from marionette_driver import By, Wait
from marionette_driver.errors import NoSuchWindowException
from marionette_harness import MarionetteTestCase
class BaseWindowTestCase(PuppeteerMixin, MarionetteTestCase):
def setUp(self):
"""
These tests open and close windows pretty rapidly, which
(since bug 1261842) can cause content processes to be
spawned and discarded in large numbers. By default, Firefox
has a 5 second timeout for shutting down content processes,
but we can get into cases where the content process just
doesn't have enough time to get itself all sorted before
the timeout gets hit, which results in the parent killing
the content process manually, which generates a crash report,
which causes these tests to orange. We side-step this by
setting dom.ipc.tabs.shutdownTimeoutSecs to 0, which disables
the shutdown timer.
"""
super(BaseWindowTestCase, self).setUp()
self.marionette.set_pref('dom.ipc.tabs.shutdownTimeoutSecs', 0)
def tearDown(self):
try:
self.marionette.clear_pref('dom.ipc.tabs.shutdownTimeoutSecs')
finally:
super(BaseWindowTestCase, self).tearDown()
class TestWindows(BaseWindowTestCase):
def tearDown(self):
try:
self.puppeteer.windows.close_all([self.browser])
finally:
super(TestWindows, self).tearDown()
def test_switch_to(self):
url = self.marionette.absolute_url('layout/mozilla.html')
# Open two more windows
for index in range(0, 2):
self.marionette.execute_script(""" window.open(); """)
windows = self.puppeteer.windows.all
self.assertEquals(len(windows), 3)
# Switch to the 2nd window
self.puppeteer.windows.switch_to(windows[1].handle)
self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle)
# TODO: Needs updated tabs module for improved navigation
with self.marionette.using_context('content'):
self.marionette.navigate(url)
# Switch to the last window and find 2nd window by URL
self.puppeteer.windows.switch_to(windows[2].handle)
# TODO: A window can have multiple tabs, so this may need an update
# when the tabs module gets implemented
def find_by_url(win):
with win.marionette.using_context('content'):
return win.marionette.get_url() == url
self.puppeteer.windows.switch_to(find_by_url)
self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle)
self.puppeteer.windows.switch_to(find_by_url)
# Switching to an unknown handles has to fail
self.assertRaises(NoSuchWindowException,
self.puppeteer.windows.switch_to, "humbug")
self.assertRaises(NoSuchWindowException,
self.puppeteer.windows.switch_to, lambda win: False)
self.puppeteer.windows.close_all([self.browser])
self.browser.switch_to()
self.assertEqual(len(self.puppeteer.windows.all), 1)
def test_switch_to_unknown_window_type(self):
def open_by_js(_):
with self.marionette.using_context('chrome'):
self.marionette.execute_script("""
window.open('chrome://browser/content/safeMode.xul', '_blank',
'chrome,centerscreen,resizable=no');
""")
win = self.browser.open_window(callback=open_by_js, expected_window_class=BaseWindow)
win.close()
self.browser.switch_to()
class TestBaseWindow(BaseWindowTestCase):
def tearDown(self):
try:
self.puppeteer.windows.close_all([self.browser])
finally:
BaseWindowTestCase.tearDown(self)
def test_basics(self):
# force BaseWindow instance
win1 = BaseWindow(self.marionette, self.browser.handle)
self.assertEquals(win1.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win1.window_element,
self.marionette.find_element(By.CSS_SELECTOR, ':root'))
self.assertEquals(win1.window_element.get_attribute('windowtype'),
self.marionette.get_window_type())
self.assertFalse(win1.closed)
# Test invalid parameters for BaseWindow constructor
self.assertRaises(errors.UnknownWindowError,
BaseWindow, self.marionette, 10)
# Test invalid shortcuts
self.assertRaises(KeyError,
win1.send_shortcut, 'l', acel=True)
def test_open_close(self):
# force BaseWindow instance
win1 = BaseWindow(self.marionette, self.browser.handle)
# Open a new window (will be focused), and check states
win2 = win1.open_window()
# force BaseWindow instance
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(len(self.marionette.chrome_window_handles), 2)
self.assertNotEquals(win1.handle, win2.handle)
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
win2.close()
self.assertTrue(win2.closed)
self.assertEquals(len(self.marionette.chrome_window_handles), 1)
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
Wait(self.marionette).until(lambda _: win1.focused) # catch the no focused window
win1.focus()
# Open and close a new window by a custom callback
def opener(window):
window.marionette.execute_script(""" window.open(); """)
def closer(window):
window.marionette.execute_script(""" window.close(); """)
win2 = win1.open_window(callback=opener)
# force BaseWindow instance
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(len(self.marionette.chrome_window_handles), 2)
win2.close(callback=closer)
win1.focus()
# Check for an unexpected window class
self.assertRaises(errors.UnexpectedWindowTypeError,
win1.open_window, expected_window_class=BaseWindow)
self.puppeteer.windows.close_all([win1])
def test_switch_to_and_focus(self):
# force BaseWindow instance
win1 = BaseWindow(self.marionette, self.browser.handle)
# Open a new window (will be focused), and check states
win2 = win1.open_window()
# force BaseWindow instance
win2 = BaseWindow(self.marionette, win2.handle)
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle)
self.assertFalse(win1.focused)
self.assertTrue(win2.focused)
# Switch back to win1 without moving the focus, but focus separately
win1.switch_to()
self.assertEquals(win1.handle, self.marionette.current_chrome_window_handle)
self.assertTrue(win2.focused)
win1.focus()
self.assertTrue(win1.focused)
# Switch back to win2 by focusing it directly
win2.focus()
self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle)
self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle)
self.assertTrue(win2.focused)
# Close win2, and check that it keeps active but looses focus
win2.switch_to()
win2.close()
win1.switch_to()
class TestBrowserWindow(BaseWindowTestCase):
def tearDown(self):
try:
self.puppeteer.windows.close_all([self.browser])
finally:
BaseWindowTestCase.tearDown(self)
def test_basic(self):
self.assertNotEqual(self.browser.dtds, [])
self.assertNotEqual(self.browser.properties, [])
self.assertFalse(self.browser.is_private)
self.assertIsNotNone(self.browser.menubar)
self.assertIsNotNone(self.browser.navbar)
self.assertIsNotNone(self.browser.tabbar)
def test_open_close(self):
# open and close a new browser windows by menu
win2 = self.browser.open_browser(trigger='menu')
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertFalse(self.browser.is_private)
win2.close(trigger='menu')
# open and close a new browser window by shortcut
win2 = self.browser.open_browser(trigger='shortcut')
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertFalse(self.browser.is_private)
win2.close(trigger='shortcut')
# open and close a new private browsing window
win2 = self.browser.open_browser(is_private=True)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertTrue(win2.is_private)
win2.close()
# open and close a new private browsing window
win2 = self.browser.open_browser(trigger='shortcut', is_private=True)
self.assertEquals(win2, self.puppeteer.windows.current)
self.assertTrue(win2.is_private)
win2.close()
# force closing a window
win2 = self.browser.open_browser()
self.assertEquals(win2, self.puppeteer.windows.current)
win2.close(force=True)
|