1
- import os
2
1
from unittest .mock import patch
3
2
4
3
import swapper
5
- from django .conf import settings
6
4
from django .contrib .staticfiles .testing import StaticLiveServerTestCase
7
5
from django .core .management import call_command
8
6
from django .test import tag
9
7
from django .urls .base import reverse
10
8
from reversion .models import Version
11
- from selenium import webdriver
12
9
from selenium .common .exceptions import TimeoutException , UnexpectedAlertPresentException
13
10
from selenium .webdriver .common .by import By
14
- from selenium .webdriver .firefox .options import Options as FirefoxOptions
15
11
from selenium .webdriver .support import expected_conditions as EC
16
12
from selenium .webdriver .support .ui import Select , WebDriverWait
17
13
14
+ from openwisp_controller .config .tests .test_selenium import DeviceAdminSeleniumTextMixin
18
15
from openwisp_firmware_upgrader .hardware import REVERSE_FIRMWARE_IMAGE_MAP
19
16
from openwisp_firmware_upgrader .tests .base import TestUpgraderMixin
20
17
from openwisp_utils .test_selenium_mixins import SeleniumTestMixin
31
28
32
29
33
30
@tag ('selenium_tests' )
34
- class TestDeviceAdmin (TestUpgraderMixin , SeleniumTestMixin , StaticLiveServerTestCase ):
31
+ class TestDeviceAdmin (
32
+ TestUpgraderMixin , SeleniumTestMixin , StaticLiveServerTestCase
33
+ ):
35
34
config_app_label = 'config'
36
35
firmware_app_label = 'firmware_upgrader'
37
36
os = 'OpenWrt 19.07-SNAPSHOT r11061-6ffd4d8a4d'
38
37
image_type = REVERSE_FIRMWARE_IMAGE_MAP ['YunCore XD3200' ]
39
38
40
- @classmethod
41
- def setUpClass (cls ):
42
- StaticLiveServerTestCase .setUpClass ()
43
-
44
- firefox_options = FirefoxOptions ()
45
- firefox_options .page_load_strategy = 'eager'
46
- if getattr (settings , 'SELENIUM_HEADLESS' , True ):
47
- firefox_options .add_argument ('--headless' )
48
-
49
- FIREFOX_BIN = os .environ .get ('FIREFOX_BIN' , None )
50
- if FIREFOX_BIN :
51
- firefox_options .binary_location = FIREFOX_BIN
52
-
53
- # Set window size
54
- firefox_options .add_argument ('--width=1366' )
55
- firefox_options .add_argument ('--height=768' )
56
-
57
- # Ignore certificate errors
58
- firefox_options .accept_insecure_certs = True
59
-
60
- cls .web_driver = webdriver .Firefox (options = firefox_options )
61
-
62
39
def _set_up_env (self ):
63
40
org = self ._get_org ()
64
41
category = self ._get_category (organization = org )
@@ -100,22 +77,15 @@ def tearDown(self):
100
77
)
101
78
102
79
def _get_device_firmware_dropdown_select (self ):
103
- select_element = WebDriverWait (self .web_driver , 5 ).until (
104
- EC .element_to_be_clickable ((By .ID , 'id_devicefirmware-0-image' ))
105
- )
80
+ select_element = self .find_element (By .ID , 'id_devicefirmware-0-image' )
106
81
return Select (select_element )
107
82
108
83
def _assert_loading_overlay_hidden (self ):
109
- WebDriverWait (self .web_driver , 2 ).until (
110
- EC .invisibility_of_element ((By .CSS_SELECTOR , '#loading-overlay' ))
111
- )
84
+ self .wait_for_invisibility (By .CSS_SELECTOR , '#loading-overlay' )
112
85
113
86
def open (self , url , driver = None ):
114
87
super ().open (url , driver )
115
88
driver = driver or self .web_driver
116
- WebDriverWait (driver , 5 ).until (
117
- lambda d : d .execute_script ('return document.readyState' ) == 'complete'
118
- )
119
89
self ._assert_loading_overlay_hidden ()
120
90
121
91
@capture_any_output ()
@@ -142,9 +112,7 @@ def test_restoring_deleted_device(self):
142
112
self .open (
143
113
reverse (f'admin:{ self .config_app_label } _device_delete' , args = [device .id ])
144
114
)
145
- self .web_driver .find_element (
146
- by = By .CSS_SELECTOR , value = '#content form input[type="submit"]'
147
- ).click ()
115
+ self .find_element (By .CSS_SELECTOR , '#content form input[type="submit"]' ).click ()
148
116
self .assertEqual (Device .objects .count (), 0 )
149
117
self .assertEqual (DeviceConnection .objects .count (), 0 )
150
118
self .assertEqual (DeviceFirmware .objects .count (), 0 )
@@ -157,13 +125,9 @@ def test_restoring_deleted_device(self):
157
125
f'admin:{ self .config_app_label } _device_recover' , args = [version_obj .id ]
158
126
)
159
127
)
160
- WebDriverWait (self .web_driver , 5 ).until (
161
- EC .invisibility_of_element ((By .ID , "command_set-group" ))
162
- )
163
- WebDriverWait (self .web_driver , 5 ).until (
164
- EC .element_to_be_clickable (
165
- (By .XPATH , '//*[@id="device_form"]/div/div[1]/input[1]' )
166
- )
128
+ self .wait_for_invisibility (By .ID , "command_set-group" )
129
+ self .wait_for_visibility (
130
+ By .XPATH , '//*[@id="device_form"]/div/div[1]/input[1]'
167
131
).click ()
168
132
try :
169
133
WebDriverWait (self .web_driver , 5 ).until (
@@ -187,14 +151,10 @@ def test_restoring_deleted_device(self):
187
151
)
188
152
def test_device_firmware_upgrade_options (self , * args ):
189
153
def save_device ():
190
- self .web_driver . find_element (
154
+ self .find_element (
191
155
by = By .XPATH , value = '//*[@id="device_form"]/div/div[1]/input[3]'
192
156
).click ()
193
- WebDriverWait (self .web_driver , 2 ).until (
194
- EC .visibility_of_all_elements_located (
195
- (By .CSS_SELECTOR , '#devicefirmware-group' )
196
- )
197
- )
157
+ self .wait_for_visibility (By .CSS_SELECTOR , '#devicefirmware-group' )
198
158
self ._assert_loading_overlay_hidden ()
199
159
200
160
_ , _ , _ , _ , _ , image , device = self ._set_up_env ()
@@ -207,74 +167,57 @@ def save_device():
207
167
)
208
168
)
209
169
# JSONSchema Editor should not be rendered without a change in the image field
210
- WebDriverWait (self .web_driver , 1 ).until (
211
- EC .invisibility_of_element_located (
212
- (By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper' )
213
- )
170
+ self .wait_for_invisibility (
171
+ By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper'
214
172
)
215
173
image_select = self ._get_device_firmware_dropdown_select ()
216
174
image_select .select_by_value (str (image .pk ))
217
175
# JSONSchema configuration editor should not be rendered
218
- WebDriverWait (self .web_driver , 1 ).until (
219
- EC .invisibility_of_element_located (
220
- (
221
- By .XPATH ,
222
- '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]/div/h3/span[4]/input' ,
223
- )
224
- )
176
+ self .wait_for_invisibility (
177
+ By .XPATH ,
178
+ '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]/div/h3/span[4]/input' ,
225
179
)
226
180
# Select "None" image should hide JSONSchema Editor
227
181
image_select .select_by_value ('' )
228
- WebDriverWait (self .web_driver , 1 ).until (
229
- EC .invisibility_of_element_located (
230
- (By .CSS_SELECTOR , '#id_devicefirmware-0-upgrade_options_jsoneditor' )
231
- )
182
+ self .wait_for_invisibility (
183
+ By .CSS_SELECTOR , '#id_devicefirmware-0-upgrade_options_jsoneditor'
232
184
)
233
185
234
186
# Select "build2" image
235
187
image_select .select_by_value (str (image .pk ))
236
188
# Enable '-c' option
237
- self .web_driver . find_element (
189
+ self .find_element (
238
190
by = By .XPATH ,
239
191
value = '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]'
240
192
'/div/div[2]/div/div/div[1]/div/div[1]/label/input' ,
241
193
).click ()
242
194
# Enable '-F' option
243
- self .web_driver . find_element (
195
+ self .find_element (
244
196
by = By .XPATH ,
245
197
value = '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]'
246
198
'/div/div[2]/div/div/div[7]/div/div[1]/label/input' ,
247
199
).click ()
248
200
save_device ()
249
201
250
202
# Delete DeviceFirmware
251
- WebDriverWait (self .web_driver , 2 ).until (
252
- EC .element_to_be_clickable ((By .CSS_SELECTOR , '#id_devicefirmware-0-DELETE' ))
253
- ).click ()
203
+ self .find_element (By .CSS_SELECTOR , '#id_devicefirmware-0-DELETE' ).click ()
254
204
save_device ()
255
205
256
206
# When adding firmware to the device for the first time,
257
207
# JSONSchema editor should be rendered only when the image
258
208
# is selected
259
- self .web_driver . find_element (
209
+ self .find_element (
260
210
by = By .XPATH , value = '//*[@id="devicefirmware-group"]/fieldset/div[2]/a'
261
211
).click ()
262
212
# JSONSchema Editor should not be rendered without a change in the image field
263
- WebDriverWait (self .web_driver , 1 ).until (
264
- EC .invisibility_of_element_located (
265
- (By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper' )
266
- )
213
+ self .wait_for_invisibility (
214
+ By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper'
267
215
)
268
216
image_select = self ._get_device_firmware_dropdown_select ()
269
217
image_select .select_by_index (1 )
270
- try :
271
- WebDriverWait (self .web_driver , 1 ).until (
272
- EC .visibility_of_element_located (
273
- (By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper' )
274
- )
275
- )
276
- except TimeoutError :
277
- self .fail ('JSONSchema editor not shown after changing firmware image' )
218
+ self .wait_for_visibility (
219
+ By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper'
220
+ )
278
221
save_device ()
279
222
280
223
@capture_any_output ()
@@ -293,43 +236,30 @@ def test_batch_upgrade_upgrade_options(self, *args):
293
236
reverse (f'admin:{ self .firmware_app_label } _build_change' , args = [build2 .id ])
294
237
)
295
238
# Launch mass upgrade operation
296
- self .web_driver . find_element (
239
+ self .find_element (
297
240
by = By .CSS_SELECTOR ,
298
241
value = '.title-wrapper .object-tools form button[type="submit"]' ,
299
242
).click ()
300
243
301
244
# Ensure JSONSchema form is rendered
302
- try :
303
- WebDriverWait (self .web_driver , 1 ).until (
304
- EC .visibility_of_element_located (
305
- (By .CSS_SELECTOR , '.jsoneditor-wrapper' )
306
- )
307
- )
308
- except TimeoutError :
309
- self .fail ('JSONSchema editor not shown after changing firmware image' )
245
+ self .wait_for_visibility (By .CSS_SELECTOR , '.jsoneditor-wrapper' )
310
246
# JSONSchema configuration editor should not be rendered
311
- WebDriverWait (self .web_driver , 1 ).until (
312
- EC .invisibility_of_element_located (
313
- (
314
- By .XPATH ,
315
- '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]/div/h3/span[4]/input' ,
316
- )
317
- )
247
+ self .wait_for_invisibility (
248
+ By .XPATH ,
249
+ '//*[@id="id_devicefirmware-0-upgrade_options_jsoneditor"]/div/h3/span[4]/input' ,
318
250
)
319
251
# Disable -c flag
320
- self .web_driver . find_element (
252
+ self .find_element (
321
253
by = By .XPATH ,
322
254
value = '//*[@id="id_upgrade_options_jsoneditor"]/div/div[2]/div/div/div[1]/div/div[1]/label/input' ,
323
255
).click ()
324
256
# Enable -n flag
325
- self .web_driver . find_element (
257
+ self .find_element (
326
258
by = By .XPATH ,
327
259
value = '//*[@id="id_upgrade_options_jsoneditor"]/div/div[2]/div/div/div[3]/div/div[1]/label/input' ,
328
260
).click ()
329
261
# Upgrade all devices
330
- self .web_driver .find_element (
331
- by = By .CSS_SELECTOR , value = 'input[name="upgrade_all"]'
332
- ).click ()
262
+ self .find_element (by = By .CSS_SELECTOR , value = 'input[name="upgrade_all"]' ).click ()
333
263
try :
334
264
WebDriverWait (self .web_driver , 5 ).until (
335
265
EC .url_contains ('batchupgradeoperation' )
@@ -391,12 +321,10 @@ def test_upgrader_with_unsupported_upgrade_options(self, *args):
391
321
image_select .select_by_value (str (image2 .pk ))
392
322
# Ensure JSONSchema editor is not rendered because
393
323
# the upgrader does not define a schema
394
- WebDriverWait (self .web_driver , 1 ).until (
395
- EC .invisibility_of_element_located (
396
- (By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper' )
397
- )
324
+ self .wait_for_invisibility (
325
+ By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper'
398
326
)
399
- self .web_driver . find_element (
327
+ self .find_element (
400
328
by = By .XPATH , value = '//*[@id="device_form"]/div/div[1]/input[3]'
401
329
).click ()
402
330
self .assertEqual (
@@ -412,19 +340,17 @@ def test_upgrader_with_unsupported_upgrade_options(self, *args):
412
340
)
413
341
)
414
342
# Launch mass upgrade operation
415
- self .web_driver . find_element (
343
+ self .find_element (
416
344
by = By .CSS_SELECTOR ,
417
345
value = '.title-wrapper .object-tools form button[type="submit"]' ,
418
346
).click ()
419
347
# Ensure JSONSchema editor is not rendered because
420
348
# the upgrader does not define a schema
421
- WebDriverWait (self .web_driver , 1 ).until (
422
- EC .invisibility_of_element_located (
423
- (By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper' )
424
- )
349
+ self .wait_for_invisibility (
350
+ By .CSS_SELECTOR , '#devicefirmware-group .jsoneditor-wrapper'
425
351
)
426
352
# Upgrade all devices
427
- self .web_driver . find_element (
353
+ self .find_element (
428
354
by = By .CSS_SELECTOR , value = 'input[name="upgrade_all"]'
429
355
).click ()
430
356
self .assertEqual (
0 commit comments