seleniumbase 4.24.10__py3-none-any.whl → 4.33.15__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- sbase/__init__.py +1 -0
- sbase/steps.py +7 -0
- seleniumbase/__init__.py +16 -7
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +97 -32
- seleniumbase/common/decorators.py +16 -7
- seleniumbase/config/proxy_list.py +3 -3
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/logo_helper.py +47 -8
- seleniumbase/console_scripts/run.py +345 -335
- seleniumbase/console_scripts/sb_behave_gui.py +5 -12
- seleniumbase/console_scripts/sb_caseplans.py +6 -13
- seleniumbase/console_scripts/sb_commander.py +5 -12
- seleniumbase/console_scripts/sb_install.py +62 -54
- seleniumbase/console_scripts/sb_mkchart.py +13 -20
- seleniumbase/console_scripts/sb_mkdir.py +11 -17
- seleniumbase/console_scripts/sb_mkfile.py +69 -43
- seleniumbase/console_scripts/sb_mkpres.py +13 -20
- seleniumbase/console_scripts/sb_mkrec.py +88 -21
- seleniumbase/console_scripts/sb_objectify.py +30 -30
- seleniumbase/console_scripts/sb_print.py +5 -12
- seleniumbase/console_scripts/sb_recorder.py +16 -11
- seleniumbase/core/browser_launcher.py +1658 -221
- seleniumbase/core/detect_b_ver.py +7 -8
- seleniumbase/core/log_helper.py +42 -27
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_cdp.py +1951 -0
- seleniumbase/core/sb_driver.py +162 -8
- seleniumbase/core/settings_parser.py +6 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +1234 -632
- seleniumbase/fixtures/constants.py +10 -1
- seleniumbase/fixtures/js_utils.py +171 -144
- seleniumbase/fixtures/page_actions.py +177 -13
- seleniumbase/fixtures/page_utils.py +25 -53
- seleniumbase/fixtures/shared_utils.py +97 -11
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +340 -65
- seleniumbase/plugins/pytest_plugin.py +276 -47
- seleniumbase/plugins/sb_manager.py +412 -99
- seleniumbase/plugins/selenium_plugin.py +122 -17
- seleniumbase/translate/translator.py +0 -7
- seleniumbase/undetected/__init__.py +59 -52
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +829 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
- seleniumbase/undetected/cdp_driver/config.py +334 -0
- seleniumbase/undetected/cdp_driver/connection.py +639 -0
- seleniumbase/undetected/cdp_driver/element.py +1168 -0
- seleniumbase/undetected/cdp_driver/tab.py +1323 -0
- seleniumbase/undetected/dprocess.py +4 -7
- seleniumbase/undetected/options.py +6 -8
- seleniumbase/undetected/patcher.py +11 -13
- seleniumbase/undetected/reactor.py +0 -1
- seleniumbase/undetected/webelement.py +16 -3
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
- sbase/ReadMe.txt +0 -2
- seleniumbase/ReadMe.md +0 -25
- seleniumbase/common/ReadMe.md +0 -71
- seleniumbase/console_scripts/ReadMe.md +0 -731
- seleniumbase/drivers/ReadMe.md +0 -27
- seleniumbase/extensions/ReadMe.md +0 -12
- seleniumbase/masterqa/ReadMe.md +0 -61
- seleniumbase/resources/ReadMe.md +0 -31
- seleniumbase/resources/favicon.ico +0 -0
- seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
- seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
@@ -18,8 +18,10 @@ By.TAG_NAME # "tag name"
|
|
18
18
|
By.PARTIAL_LINK_TEXT # "partial link text"
|
19
19
|
"""
|
20
20
|
import codecs
|
21
|
+
import fasteners
|
21
22
|
import os
|
22
23
|
import time
|
24
|
+
from contextlib import suppress
|
23
25
|
from selenium.common.exceptions import ElementNotInteractableException
|
24
26
|
from selenium.common.exceptions import ElementNotVisibleException
|
25
27
|
from selenium.common.exceptions import NoAlertPresentException
|
@@ -32,6 +34,7 @@ from selenium.webdriver.common.keys import Keys
|
|
32
34
|
from seleniumbase.common.exceptions import LinkTextNotFoundException
|
33
35
|
from seleniumbase.common.exceptions import TextNotVisibleException
|
34
36
|
from seleniumbase.config import settings
|
37
|
+
from seleniumbase.fixtures import constants
|
35
38
|
from seleniumbase.fixtures import page_utils
|
36
39
|
from seleniumbase.fixtures import shared_utils
|
37
40
|
|
@@ -46,6 +49,8 @@ def is_element_present(driver, selector, by="css selector"):
|
|
46
49
|
@Returns
|
47
50
|
Boolean (is element present)
|
48
51
|
"""
|
52
|
+
if __is_cdp_swap_needed(driver):
|
53
|
+
return driver.cdp.is_element_present(selector)
|
49
54
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
50
55
|
try:
|
51
56
|
driver.find_element(by=by, value=selector)
|
@@ -64,6 +69,8 @@ def is_element_visible(driver, selector, by="css selector"):
|
|
64
69
|
@Returns
|
65
70
|
Boolean (is element visible)
|
66
71
|
"""
|
72
|
+
if __is_cdp_swap_needed(driver):
|
73
|
+
return driver.cdp.is_element_visible(selector)
|
67
74
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
68
75
|
try:
|
69
76
|
element = driver.find_element(by=by, value=selector)
|
@@ -82,6 +89,7 @@ def is_element_clickable(driver, selector, by="css selector"):
|
|
82
89
|
@Returns
|
83
90
|
Boolean (is element clickable)
|
84
91
|
"""
|
92
|
+
_reconnect_if_disconnected(driver)
|
85
93
|
try:
|
86
94
|
element = driver.find_element(by=by, value=selector)
|
87
95
|
if element.is_displayed() and element.is_enabled():
|
@@ -101,6 +109,7 @@ def is_element_enabled(driver, selector, by="css selector"):
|
|
101
109
|
@Returns
|
102
110
|
Boolean (is element enabled)
|
103
111
|
"""
|
112
|
+
_reconnect_if_disconnected(driver)
|
104
113
|
try:
|
105
114
|
element = driver.find_element(by=by, value=selector)
|
106
115
|
return element.is_enabled()
|
@@ -119,6 +128,7 @@ def is_text_visible(driver, text, selector="html", by="css selector"):
|
|
119
128
|
@Returns
|
120
129
|
Boolean (is text visible)
|
121
130
|
"""
|
131
|
+
_reconnect_if_disconnected(driver)
|
122
132
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
123
133
|
text = str(text)
|
124
134
|
try:
|
@@ -148,6 +158,7 @@ def is_exact_text_visible(driver, text, selector, by="css selector"):
|
|
148
158
|
@Returns
|
149
159
|
Boolean (is text visible)
|
150
160
|
"""
|
161
|
+
_reconnect_if_disconnected(driver)
|
151
162
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
152
163
|
text = str(text)
|
153
164
|
try:
|
@@ -182,6 +193,7 @@ def is_attribute_present(
|
|
182
193
|
@Returns
|
183
194
|
Boolean (is attribute present)
|
184
195
|
"""
|
196
|
+
_reconnect_if_disconnected(driver)
|
185
197
|
try:
|
186
198
|
element = driver.find_element(by=by, value=selector)
|
187
199
|
found_value = element.get_attribute(attribute)
|
@@ -208,6 +220,7 @@ def is_non_empty_text_visible(driver, selector, by="css selector"):
|
|
208
220
|
@Returns
|
209
221
|
Boolean (is any text visible in the element with the selector)
|
210
222
|
"""
|
223
|
+
_reconnect_if_disconnected(driver)
|
211
224
|
try:
|
212
225
|
element = driver.find_element(by=by, value=selector)
|
213
226
|
element_text = element.text
|
@@ -232,6 +245,7 @@ def hover_on_element(driver, selector, by="css selector"):
|
|
232
245
|
selector - the locator for identifying the page element (required)
|
233
246
|
by - the type of selector being used (Default: "css selector")
|
234
247
|
"""
|
248
|
+
_reconnect_if_disconnected(driver)
|
235
249
|
element = driver.find_element(by=by, value=selector)
|
236
250
|
hover = ActionChains(driver).move_to_element(element)
|
237
251
|
hover.perform()
|
@@ -242,6 +256,7 @@ def hover_element(driver, element):
|
|
242
256
|
"""
|
243
257
|
Similar to hover_on_element(), but uses found element, not a selector.
|
244
258
|
"""
|
259
|
+
_reconnect_if_disconnected(driver)
|
245
260
|
hover = ActionChains(driver).move_to_element(element)
|
246
261
|
hover.perform()
|
247
262
|
return element
|
@@ -273,6 +288,7 @@ def hover_and_click(
|
|
273
288
|
timeout - number of seconds to wait for click element to appear after hover
|
274
289
|
js_click - the option to use js_click() instead of click() on the last part
|
275
290
|
"""
|
291
|
+
_reconnect_if_disconnected(driver)
|
276
292
|
start_ms = time.time() * 1000.0
|
277
293
|
stop_ms = start_ms + (timeout * 1000.0)
|
278
294
|
element = driver.find_element(by=hover_by, value=hover_selector)
|
@@ -312,6 +328,7 @@ def hover_element_and_click(
|
|
312
328
|
"""
|
313
329
|
Similar to hover_and_click(), but assumes top element is already found.
|
314
330
|
"""
|
331
|
+
_reconnect_if_disconnected(driver)
|
315
332
|
start_ms = time.time() * 1000.0
|
316
333
|
stop_ms = start_ms + (timeout * 1000.0)
|
317
334
|
hover = ActionChains(driver).move_to_element(element)
|
@@ -344,6 +361,7 @@ def hover_element_and_double_click(
|
|
344
361
|
click_by="css selector",
|
345
362
|
timeout=settings.SMALL_TIMEOUT,
|
346
363
|
):
|
364
|
+
_reconnect_if_disconnected(driver)
|
347
365
|
start_ms = time.time() * 1000.0
|
348
366
|
stop_ms = start_ms + (timeout * 1000.0)
|
349
367
|
hover = ActionChains(driver).move_to_element(element)
|
@@ -395,6 +413,7 @@ def wait_for_element_present(
|
|
395
413
|
@Returns
|
396
414
|
A web element object
|
397
415
|
"""
|
416
|
+
_reconnect_if_disconnected(driver)
|
398
417
|
element = None
|
399
418
|
start_ms = time.time() * 1000.0
|
400
419
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -454,6 +473,7 @@ def wait_for_element_visible(
|
|
454
473
|
@Returns
|
455
474
|
A web element object
|
456
475
|
"""
|
476
|
+
_reconnect_if_disconnected(driver)
|
457
477
|
element = None
|
458
478
|
is_present = False
|
459
479
|
start_ms = time.time() * 1000.0
|
@@ -535,6 +555,7 @@ def wait_for_text_visible(
|
|
535
555
|
@Returns
|
536
556
|
A web element object that contains the text searched for
|
537
557
|
"""
|
558
|
+
_reconnect_if_disconnected(driver)
|
538
559
|
element = None
|
539
560
|
is_present = False
|
540
561
|
full_text = None
|
@@ -645,6 +666,7 @@ def wait_for_exact_text_visible(
|
|
645
666
|
@Returns
|
646
667
|
A web element object that contains the text searched for
|
647
668
|
"""
|
669
|
+
_reconnect_if_disconnected(driver)
|
648
670
|
element = None
|
649
671
|
is_present = False
|
650
672
|
actual_text = None
|
@@ -755,6 +777,7 @@ def wait_for_attribute(
|
|
755
777
|
@Returns
|
756
778
|
A web element object that contains the expected attribute/value
|
757
779
|
"""
|
780
|
+
_reconnect_if_disconnected(driver)
|
758
781
|
element = None
|
759
782
|
element_present = False
|
760
783
|
attribute_present = False
|
@@ -841,6 +864,7 @@ def wait_for_element_clickable(
|
|
841
864
|
@Returns
|
842
865
|
A web element object
|
843
866
|
"""
|
867
|
+
_reconnect_if_disconnected(driver)
|
844
868
|
element = None
|
845
869
|
is_present = False
|
846
870
|
is_visible = False
|
@@ -935,6 +959,7 @@ def wait_for_element_absent(
|
|
935
959
|
timeout - the time to wait for elements in seconds
|
936
960
|
original_selector - handle pre-converted ":contains(TEXT)" selector
|
937
961
|
"""
|
962
|
+
_reconnect_if_disconnected(driver)
|
938
963
|
start_ms = time.time() * 1000.0
|
939
964
|
stop_ms = start_ms + (timeout * 1000.0)
|
940
965
|
for x in range(int(timeout * 10)):
|
@@ -982,6 +1007,7 @@ def wait_for_element_not_visible(
|
|
982
1007
|
timeout - the time to wait for the element in seconds
|
983
1008
|
original_selector - handle pre-converted ":contains(TEXT)" selector
|
984
1009
|
"""
|
1010
|
+
_reconnect_if_disconnected(driver)
|
985
1011
|
start_ms = time.time() * 1000.0
|
986
1012
|
stop_ms = start_ms + (timeout * 1000.0)
|
987
1013
|
for x in range(int(timeout * 10)):
|
@@ -1017,7 +1043,7 @@ def wait_for_element_not_visible(
|
|
1017
1043
|
def wait_for_text_not_visible(
|
1018
1044
|
driver,
|
1019
1045
|
text,
|
1020
|
-
selector,
|
1046
|
+
selector="html",
|
1021
1047
|
by="css selector",
|
1022
1048
|
timeout=settings.LARGE_TIMEOUT,
|
1023
1049
|
):
|
@@ -1034,6 +1060,7 @@ def wait_for_text_not_visible(
|
|
1034
1060
|
@Returns
|
1035
1061
|
A web element object that contains the text searched for
|
1036
1062
|
"""
|
1063
|
+
_reconnect_if_disconnected(driver)
|
1037
1064
|
text = str(text)
|
1038
1065
|
start_ms = time.time() * 1000.0
|
1039
1066
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -1060,7 +1087,7 @@ def wait_for_text_not_visible(
|
|
1060
1087
|
def wait_for_exact_text_not_visible(
|
1061
1088
|
driver,
|
1062
1089
|
text,
|
1063
|
-
selector,
|
1090
|
+
selector="html",
|
1064
1091
|
by="css selector",
|
1065
1092
|
timeout=settings.LARGE_TIMEOUT,
|
1066
1093
|
):
|
@@ -1077,6 +1104,7 @@ def wait_for_exact_text_not_visible(
|
|
1077
1104
|
@Returns
|
1078
1105
|
A web element object that contains the text searched for
|
1079
1106
|
"""
|
1107
|
+
_reconnect_if_disconnected(driver)
|
1080
1108
|
text = str(text)
|
1081
1109
|
start_ms = time.time() * 1000.0
|
1082
1110
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -1119,6 +1147,7 @@ def wait_for_non_empty_text_visible(
|
|
1119
1147
|
@Returns
|
1120
1148
|
The web element object that has text
|
1121
1149
|
"""
|
1150
|
+
_reconnect_if_disconnected(driver)
|
1122
1151
|
start_ms = time.time() * 1000.0
|
1123
1152
|
stop_ms = start_ms + (timeout * 1000.0)
|
1124
1153
|
element = None
|
@@ -1236,6 +1265,7 @@ def find_visible_elements(driver, selector, by="css selector", limit=0):
|
|
1236
1265
|
by - the type of selector being used (Default: "css selector")
|
1237
1266
|
limit - the maximum number of elements to return if > 0.
|
1238
1267
|
"""
|
1268
|
+
_reconnect_if_disconnected(driver)
|
1239
1269
|
elements = driver.find_elements(by=by, value=selector)
|
1240
1270
|
if limit and limit > 0 and len(elements) > limit:
|
1241
1271
|
elements = elements[:limit]
|
@@ -1273,6 +1303,7 @@ def save_screenshot(
|
|
1273
1303
|
If the folder provided doesn't exist, it will get created.
|
1274
1304
|
The screenshot will be in PNG format: (*.png)
|
1275
1305
|
"""
|
1306
|
+
_reconnect_if_disconnected(driver)
|
1276
1307
|
if not name.endswith(".png"):
|
1277
1308
|
name = name + ".png"
|
1278
1309
|
if folder:
|
@@ -1311,6 +1342,8 @@ def save_page_source(driver, name, folder=None):
|
|
1311
1342
|
"""
|
1312
1343
|
from seleniumbase.core import log_helper
|
1313
1344
|
|
1345
|
+
if not __is_cdp_swap_needed(driver):
|
1346
|
+
_reconnect_if_disconnected(driver) # If disconnected without CDP
|
1314
1347
|
if not name.endswith(".html"):
|
1315
1348
|
name = name + ".html"
|
1316
1349
|
if folder:
|
@@ -1321,7 +1354,11 @@ def save_page_source(driver, name, folder=None):
|
|
1321
1354
|
html_file_path = os.path.join(file_path, name)
|
1322
1355
|
else:
|
1323
1356
|
html_file_path = name
|
1324
|
-
page_source =
|
1357
|
+
page_source = None
|
1358
|
+
if __is_cdp_swap_needed(driver):
|
1359
|
+
page_source = driver.cdp.get_page_source()
|
1360
|
+
else:
|
1361
|
+
page_source = driver.page_source
|
1325
1362
|
html_file = codecs.open(html_file_path, "w+", "utf-8")
|
1326
1363
|
rendered_source = log_helper.get_html_source_with_base_href(
|
1327
1364
|
driver, page_source
|
@@ -1337,6 +1374,7 @@ def wait_for_and_accept_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1337
1374
|
driver - the webdriver object (required)
|
1338
1375
|
timeout - the time to wait for the alert in seconds
|
1339
1376
|
"""
|
1377
|
+
_reconnect_if_disconnected(driver)
|
1340
1378
|
alert = wait_for_and_switch_to_alert(driver, timeout)
|
1341
1379
|
alert_text = alert.text
|
1342
1380
|
alert.accept()
|
@@ -1350,6 +1388,7 @@ def wait_for_and_dismiss_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1350
1388
|
driver - the webdriver object (required)
|
1351
1389
|
timeout - the time to wait for the alert in seconds
|
1352
1390
|
"""
|
1391
|
+
_reconnect_if_disconnected(driver)
|
1353
1392
|
alert = wait_for_and_switch_to_alert(driver, timeout)
|
1354
1393
|
alert_text = alert.text
|
1355
1394
|
alert.dismiss()
|
@@ -1365,6 +1404,7 @@ def wait_for_and_switch_to_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1365
1404
|
driver - the webdriver object (required)
|
1366
1405
|
timeout - the time to wait for the alert in seconds
|
1367
1406
|
"""
|
1407
|
+
_reconnect_if_disconnected(driver)
|
1368
1408
|
start_ms = time.time() * 1000.0
|
1369
1409
|
stop_ms = start_ms + (timeout * 1000.0)
|
1370
1410
|
for x in range(int(timeout * 10)):
|
@@ -1392,6 +1432,7 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|
1392
1432
|
frame - the frame element, name, id, index, or selector
|
1393
1433
|
timeout - the time to wait for the alert in seconds
|
1394
1434
|
"""
|
1435
|
+
_reconnect_if_disconnected(driver)
|
1395
1436
|
start_ms = time.time() * 1000.0
|
1396
1437
|
stop_ms = start_ms + (timeout * 1000.0)
|
1397
1438
|
for x in range(int(timeout * 10)):
|
@@ -1407,12 +1448,10 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|
1407
1448
|
else:
|
1408
1449
|
by = "css selector"
|
1409
1450
|
if is_element_visible(driver, frame, by=by):
|
1410
|
-
|
1451
|
+
with suppress(Exception):
|
1411
1452
|
element = driver.find_element(by=by, value=frame)
|
1412
1453
|
driver.switch_to.frame(element)
|
1413
1454
|
return True
|
1414
|
-
except Exception:
|
1415
|
-
pass
|
1416
1455
|
now_ms = time.time() * 1000.0
|
1417
1456
|
if now_ms >= stop_ms:
|
1418
1457
|
break
|
@@ -1428,7 +1467,28 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|
1428
1467
|
timeout_exception(Exception, message)
|
1429
1468
|
|
1430
1469
|
|
1431
|
-
def
|
1470
|
+
def __switch_to_window(driver, window_handle, uc_lock=True):
|
1471
|
+
if (
|
1472
|
+
hasattr(driver, "_is_using_uc")
|
1473
|
+
and driver._is_using_uc
|
1474
|
+
and uc_lock
|
1475
|
+
):
|
1476
|
+
gui_lock = fasteners.InterProcessLock(
|
1477
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
1478
|
+
)
|
1479
|
+
with gui_lock:
|
1480
|
+
driver.switch_to.window(window_handle)
|
1481
|
+
else:
|
1482
|
+
driver.switch_to.window(window_handle)
|
1483
|
+
return True
|
1484
|
+
|
1485
|
+
|
1486
|
+
def switch_to_window(
|
1487
|
+
driver,
|
1488
|
+
window,
|
1489
|
+
timeout=settings.SMALL_TIMEOUT,
|
1490
|
+
uc_lock=True,
|
1491
|
+
):
|
1432
1492
|
"""
|
1433
1493
|
Wait for a window to appear, and switch to it. This should be usable
|
1434
1494
|
as a drop-in replacement for driver.switch_to.window().
|
@@ -1436,7 +1496,9 @@ def switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT):
|
|
1436
1496
|
driver - the webdriver object (required)
|
1437
1497
|
window - the window index or window handle
|
1438
1498
|
timeout - the time to wait for the window in seconds
|
1499
|
+
uc_lock - if UC Mode and True, switch_to_window() uses thread-locking
|
1439
1500
|
"""
|
1501
|
+
_reconnect_if_disconnected(driver)
|
1440
1502
|
if window == -1:
|
1441
1503
|
window = len(driver.window_handles) - 1
|
1442
1504
|
start_ms = time.time() * 1000.0
|
@@ -1451,7 +1513,7 @@ def switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT):
|
|
1451
1513
|
shared_utils.check_if_time_limit_exceeded()
|
1452
1514
|
try:
|
1453
1515
|
window_handle = driver.window_handles[window]
|
1454
|
-
driver
|
1516
|
+
__switch_to_window(driver, window_handle, uc_lock=uc_lock)
|
1455
1517
|
return True
|
1456
1518
|
except IndexError:
|
1457
1519
|
now_ms = time.time() * 1000.0
|
@@ -1472,7 +1534,7 @@ def switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT):
|
|
1472
1534
|
for x in range(int(timeout * 10)):
|
1473
1535
|
shared_utils.check_if_time_limit_exceeded()
|
1474
1536
|
try:
|
1475
|
-
driver
|
1537
|
+
__switch_to_window(driver, window_handle, uc_lock=uc_lock)
|
1476
1538
|
return True
|
1477
1539
|
except NoSuchWindowException:
|
1478
1540
|
now_ms = time.time() * 1000.0
|
@@ -1490,11 +1552,34 @@ def switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT):
|
|
1490
1552
|
timeout_exception(Exception, message)
|
1491
1553
|
|
1492
1554
|
|
1555
|
+
############
|
1556
|
+
|
1557
|
+
# Special methods for use with UC Mode
|
1558
|
+
|
1559
|
+
def _reconnect_if_disconnected(driver):
|
1560
|
+
if (
|
1561
|
+
hasattr(driver, "_is_using_uc")
|
1562
|
+
and driver._is_using_uc
|
1563
|
+
and hasattr(driver, "is_connected")
|
1564
|
+
and not driver.is_connected()
|
1565
|
+
):
|
1566
|
+
with suppress(Exception):
|
1567
|
+
driver.connect()
|
1568
|
+
|
1569
|
+
|
1570
|
+
def __is_cdp_swap_needed(driver):
|
1571
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
1572
|
+
return shared_utils.is_cdp_swap_needed(driver)
|
1573
|
+
|
1574
|
+
|
1493
1575
|
############
|
1494
1576
|
|
1495
1577
|
# Support methods for direct use from driver
|
1496
1578
|
|
1497
1579
|
def open_url(driver, url):
|
1580
|
+
if __is_cdp_swap_needed(driver):
|
1581
|
+
driver.cdp.open(url)
|
1582
|
+
return
|
1498
1583
|
url = str(url).strip() # Remove leading and trailing whitespace
|
1499
1584
|
if not page_utils.looks_like_a_page_url(url):
|
1500
1585
|
if page_utils.is_valid_url("https://" + url):
|
@@ -1504,6 +1589,9 @@ def open_url(driver, url):
|
|
1504
1589
|
|
1505
1590
|
def click(driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT):
|
1506
1591
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1592
|
+
if __is_cdp_swap_needed(driver):
|
1593
|
+
driver.cdp.click(selector)
|
1594
|
+
return
|
1507
1595
|
element = wait_for_element_clickable(
|
1508
1596
|
driver, selector, by=by, timeout=timeout
|
1509
1597
|
)
|
@@ -1511,6 +1599,9 @@ def click(driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT):
|
|
1511
1599
|
|
1512
1600
|
|
1513
1601
|
def click_link(driver, link_text, timeout=settings.SMALL_TIMEOUT):
|
1602
|
+
if __is_cdp_swap_needed(driver):
|
1603
|
+
driver.cdp.click_link(link_text)
|
1604
|
+
return
|
1514
1605
|
element = wait_for_element_clickable(
|
1515
1606
|
driver, link_text, by="link text", timeout=timeout
|
1516
1607
|
)
|
@@ -1521,20 +1612,24 @@ def click_if_visible(
|
|
1521
1612
|
driver, selector, by="css selector", timeout=0
|
1522
1613
|
):
|
1523
1614
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1615
|
+
if __is_cdp_swap_needed(driver):
|
1616
|
+
driver.cdp.click_if_visible(selector)
|
1617
|
+
return
|
1524
1618
|
if is_element_visible(driver, selector, by=by):
|
1525
1619
|
click(driver, selector, by=by, timeout=1)
|
1526
1620
|
elif timeout > 0:
|
1527
|
-
|
1621
|
+
with suppress(Exception):
|
1528
1622
|
wait_for_element_visible(
|
1529
1623
|
driver, selector, by=by, timeout=timeout
|
1530
1624
|
)
|
1531
|
-
except Exception:
|
1532
|
-
pass
|
1533
1625
|
if is_element_visible(driver, selector, by=by):
|
1534
1626
|
click(driver, selector, by=by, timeout=1)
|
1535
1627
|
|
1536
1628
|
|
1537
1629
|
def click_active_element(driver):
|
1630
|
+
if __is_cdp_swap_needed(driver):
|
1631
|
+
driver.cdp.click_active_element()
|
1632
|
+
return
|
1538
1633
|
driver.execute_script("document.activeElement.click();")
|
1539
1634
|
|
1540
1635
|
|
@@ -1542,6 +1637,9 @@ def js_click(
|
|
1542
1637
|
driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
|
1543
1638
|
):
|
1544
1639
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1640
|
+
if __is_cdp_swap_needed(driver):
|
1641
|
+
driver.cdp.click(selector)
|
1642
|
+
return
|
1545
1643
|
element = wait_for_element_present(
|
1546
1644
|
driver, selector, by=by, timeout=timeout
|
1547
1645
|
)
|
@@ -1567,6 +1665,9 @@ def send_keys(
|
|
1567
1665
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1568
1666
|
):
|
1569
1667
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1668
|
+
if __is_cdp_swap_needed(driver):
|
1669
|
+
driver.cdp.send_keys(selector, text)
|
1670
|
+
return
|
1570
1671
|
element = wait_for_element_present(
|
1571
1672
|
driver, selector, by=by, timeout=timeout
|
1572
1673
|
)
|
@@ -1581,6 +1682,9 @@ def press_keys(
|
|
1581
1682
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1582
1683
|
):
|
1583
1684
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1685
|
+
if __is_cdp_swap_needed(driver):
|
1686
|
+
driver.cdp.press_keys(selector, text)
|
1687
|
+
return
|
1584
1688
|
element = wait_for_element_present(
|
1585
1689
|
driver, selector, by=by, timeout=timeout
|
1586
1690
|
)
|
@@ -1597,6 +1701,9 @@ def update_text(
|
|
1597
1701
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1598
1702
|
):
|
1599
1703
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1704
|
+
if __is_cdp_swap_needed(driver):
|
1705
|
+
driver.cdp.type(selector, text)
|
1706
|
+
return
|
1600
1707
|
element = wait_for_element_clickable(
|
1601
1708
|
driver, selector, by=by, timeout=timeout
|
1602
1709
|
)
|
@@ -1610,6 +1717,9 @@ def update_text(
|
|
1610
1717
|
|
1611
1718
|
def submit(driver, selector, by="css selector"):
|
1612
1719
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1720
|
+
if __is_cdp_swap_needed(driver):
|
1721
|
+
driver.cdp.send_keys(selector, "\r\n")
|
1722
|
+
return
|
1613
1723
|
element = wait_for_element_clickable(
|
1614
1724
|
driver, selector, by=by, timeout=settings.SMALL_TIMEOUT
|
1615
1725
|
)
|
@@ -1634,6 +1744,9 @@ def assert_element_visible(
|
|
1634
1744
|
elif page_utils.is_valid_by(selector):
|
1635
1745
|
original_selector = by
|
1636
1746
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1747
|
+
if __is_cdp_swap_needed(driver):
|
1748
|
+
driver.cdp.assert_element(selector)
|
1749
|
+
return True
|
1637
1750
|
wait_for_element_visible(
|
1638
1751
|
driver,
|
1639
1752
|
selector,
|
@@ -1652,6 +1765,9 @@ def assert_element_present(
|
|
1652
1765
|
elif page_utils.is_valid_by(selector):
|
1653
1766
|
original_selector = by
|
1654
1767
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1768
|
+
if __is_cdp_swap_needed(driver):
|
1769
|
+
driver.cdp.assert_element_present(selector)
|
1770
|
+
return True
|
1655
1771
|
wait_for_element_present(
|
1656
1772
|
driver,
|
1657
1773
|
selector,
|
@@ -1686,19 +1802,56 @@ def assert_text(
|
|
1686
1802
|
by="css selector",
|
1687
1803
|
timeout=settings.SMALL_TIMEOUT,
|
1688
1804
|
):
|
1805
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1806
|
+
if __is_cdp_swap_needed(driver):
|
1807
|
+
driver.cdp.assert_text(text, selector)
|
1808
|
+
return True
|
1689
1809
|
wait_for_text_visible(
|
1690
1810
|
driver, text.strip(), selector, by=by, timeout=timeout
|
1691
1811
|
)
|
1692
1812
|
|
1693
1813
|
|
1694
1814
|
def assert_exact_text(
|
1695
|
-
driver,
|
1815
|
+
driver,
|
1816
|
+
text,
|
1817
|
+
selector="html",
|
1818
|
+
by="css selector",
|
1819
|
+
timeout=settings.SMALL_TIMEOUT,
|
1696
1820
|
):
|
1821
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1822
|
+
if __is_cdp_swap_needed(driver):
|
1823
|
+
driver.cdp.assert_exact_text(text, selector)
|
1824
|
+
return True
|
1697
1825
|
wait_for_exact_text_visible(
|
1698
1826
|
driver, text.strip(), selector, by=by, timeout=timeout
|
1699
1827
|
)
|
1700
1828
|
|
1701
1829
|
|
1830
|
+
def assert_non_empty_text(
|
1831
|
+
driver,
|
1832
|
+
selector,
|
1833
|
+
by="css selector",
|
1834
|
+
timeout=settings.SMALL_TIMEOUT,
|
1835
|
+
):
|
1836
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1837
|
+
wait_for_non_empty_text_visible(
|
1838
|
+
driver, selector, by=by, timeout=timeout
|
1839
|
+
)
|
1840
|
+
|
1841
|
+
|
1842
|
+
def assert_text_not_visible(
|
1843
|
+
driver,
|
1844
|
+
text,
|
1845
|
+
selector="html",
|
1846
|
+
by="css selector",
|
1847
|
+
timeout=settings.SMALL_TIMEOUT,
|
1848
|
+
):
|
1849
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1850
|
+
wait_for_text_not_visible(
|
1851
|
+
driver, text.strip(), selector, by=by, timeout=timeout
|
1852
|
+
)
|
1853
|
+
|
1854
|
+
|
1702
1855
|
def wait_for_element(
|
1703
1856
|
driver,
|
1704
1857
|
selector,
|
@@ -1711,6 +1864,8 @@ def wait_for_element(
|
|
1711
1864
|
elif page_utils.is_valid_by(selector):
|
1712
1865
|
original_selector = by
|
1713
1866
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1867
|
+
if __is_cdp_swap_needed(driver):
|
1868
|
+
return driver.cdp.select(selector)
|
1714
1869
|
return wait_for_element_visible(
|
1715
1870
|
driver=driver,
|
1716
1871
|
selector=selector,
|
@@ -1732,6 +1887,8 @@ def wait_for_selector(
|
|
1732
1887
|
elif page_utils.is_valid_by(selector):
|
1733
1888
|
original_selector = by
|
1734
1889
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1890
|
+
if __is_cdp_swap_needed(driver):
|
1891
|
+
return driver.cdp.select(selector)
|
1735
1892
|
return wait_for_element_present(
|
1736
1893
|
driver=driver,
|
1737
1894
|
selector=selector,
|
@@ -1748,6 +1905,9 @@ def wait_for_text(
|
|
1748
1905
|
by="css selector",
|
1749
1906
|
timeout=settings.LARGE_TIMEOUT,
|
1750
1907
|
):
|
1908
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1909
|
+
if __is_cdp_swap_needed(driver):
|
1910
|
+
return driver.cdp.find_element(selector)
|
1751
1911
|
return wait_for_text_visible(
|
1752
1912
|
driver=driver,
|
1753
1913
|
text=text,
|
@@ -1764,6 +1924,7 @@ def wait_for_exact_text(
|
|
1764
1924
|
by="css selector",
|
1765
1925
|
timeout=settings.LARGE_TIMEOUT,
|
1766
1926
|
):
|
1927
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1767
1928
|
return wait_for_exact_text_visible(
|
1768
1929
|
driver=driver,
|
1769
1930
|
text=text,
|
@@ -1779,6 +1940,7 @@ def wait_for_non_empty_text(
|
|
1779
1940
|
by="css selector",
|
1780
1941
|
timeout=settings.LARGE_TIMEOUT,
|
1781
1942
|
):
|
1943
|
+
selector, by = page_utils.recalculate_selector(selector, by)
|
1782
1944
|
return wait_for_non_empty_text_visible(
|
1783
1945
|
driver=driver,
|
1784
1946
|
selector=selector,
|
@@ -1793,6 +1955,8 @@ def get_text(
|
|
1793
1955
|
by="css selector",
|
1794
1956
|
timeout=settings.LARGE_TIMEOUT
|
1795
1957
|
):
|
1958
|
+
if __is_cdp_swap_needed(driver):
|
1959
|
+
return driver.cdp.get_text(selector)
|
1796
1960
|
element = wait_for_element(
|
1797
1961
|
driver=driver,
|
1798
1962
|
selector=selector,
|