seleniumbase 4.31.6a4__py3-none-any.whl → 4.32.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- seleniumbase/__version__.py +1 -1
- seleniumbase/common/decorators.py +8 -7
- seleniumbase/console_scripts/sb_install.py +4 -4
- seleniumbase/core/browser_launcher.py +252 -44
- seleniumbase/core/sb_cdp.py +898 -0
- seleniumbase/core/sb_driver.py +44 -0
- seleniumbase/fixtures/base_case.py +208 -6
- seleniumbase/fixtures/constants.py +1 -0
- seleniumbase/fixtures/js_utils.py +4 -0
- seleniumbase/fixtures/page_actions.py +106 -0
- seleniumbase/fixtures/shared_utils.py +26 -0
- seleniumbase/plugins/driver_manager.py +136 -47
- seleniumbase/plugins/sb_manager.py +40 -1
- seleniumbase/undetected/__init__.py +2 -0
- seleniumbase/undetected/patcher.py +5 -5
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/METADATA +26 -20
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/RECORD +21 -20
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/WHEEL +1 -1
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/LICENSE +0 -0
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.31.6a4.dist-info → seleniumbase-4.32.0.dist-info}/top_level.txt +0 -0
@@ -49,6 +49,8 @@ def is_element_present(driver, selector, by="css selector"):
|
|
49
49
|
@Returns
|
50
50
|
Boolean (is element present)
|
51
51
|
"""
|
52
|
+
if __is_cdp_swap_needed(driver):
|
53
|
+
return driver.cdp.is_element_present(selector)
|
52
54
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
53
55
|
try:
|
54
56
|
driver.find_element(by=by, value=selector)
|
@@ -67,6 +69,8 @@ def is_element_visible(driver, selector, by="css selector"):
|
|
67
69
|
@Returns
|
68
70
|
Boolean (is element visible)
|
69
71
|
"""
|
72
|
+
if __is_cdp_swap_needed(driver):
|
73
|
+
return driver.cdp.is_element_visible(selector)
|
70
74
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
71
75
|
try:
|
72
76
|
element = driver.find_element(by=by, value=selector)
|
@@ -85,6 +89,7 @@ def is_element_clickable(driver, selector, by="css selector"):
|
|
85
89
|
@Returns
|
86
90
|
Boolean (is element clickable)
|
87
91
|
"""
|
92
|
+
_reconnect_if_disconnected(driver)
|
88
93
|
try:
|
89
94
|
element = driver.find_element(by=by, value=selector)
|
90
95
|
if element.is_displayed() and element.is_enabled():
|
@@ -104,6 +109,7 @@ def is_element_enabled(driver, selector, by="css selector"):
|
|
104
109
|
@Returns
|
105
110
|
Boolean (is element enabled)
|
106
111
|
"""
|
112
|
+
_reconnect_if_disconnected(driver)
|
107
113
|
try:
|
108
114
|
element = driver.find_element(by=by, value=selector)
|
109
115
|
return element.is_enabled()
|
@@ -122,6 +128,7 @@ def is_text_visible(driver, text, selector="html", by="css selector"):
|
|
122
128
|
@Returns
|
123
129
|
Boolean (is text visible)
|
124
130
|
"""
|
131
|
+
_reconnect_if_disconnected(driver)
|
125
132
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
126
133
|
text = str(text)
|
127
134
|
try:
|
@@ -151,6 +158,7 @@ def is_exact_text_visible(driver, text, selector, by="css selector"):
|
|
151
158
|
@Returns
|
152
159
|
Boolean (is text visible)
|
153
160
|
"""
|
161
|
+
_reconnect_if_disconnected(driver)
|
154
162
|
selector, by = page_utils.swap_selector_and_by_if_reversed(selector, by)
|
155
163
|
text = str(text)
|
156
164
|
try:
|
@@ -185,6 +193,7 @@ def is_attribute_present(
|
|
185
193
|
@Returns
|
186
194
|
Boolean (is attribute present)
|
187
195
|
"""
|
196
|
+
_reconnect_if_disconnected(driver)
|
188
197
|
try:
|
189
198
|
element = driver.find_element(by=by, value=selector)
|
190
199
|
found_value = element.get_attribute(attribute)
|
@@ -211,6 +220,7 @@ def is_non_empty_text_visible(driver, selector, by="css selector"):
|
|
211
220
|
@Returns
|
212
221
|
Boolean (is any text visible in the element with the selector)
|
213
222
|
"""
|
223
|
+
_reconnect_if_disconnected(driver)
|
214
224
|
try:
|
215
225
|
element = driver.find_element(by=by, value=selector)
|
216
226
|
element_text = element.text
|
@@ -235,6 +245,7 @@ def hover_on_element(driver, selector, by="css selector"):
|
|
235
245
|
selector - the locator for identifying the page element (required)
|
236
246
|
by - the type of selector being used (Default: "css selector")
|
237
247
|
"""
|
248
|
+
_reconnect_if_disconnected(driver)
|
238
249
|
element = driver.find_element(by=by, value=selector)
|
239
250
|
hover = ActionChains(driver).move_to_element(element)
|
240
251
|
hover.perform()
|
@@ -245,6 +256,7 @@ def hover_element(driver, element):
|
|
245
256
|
"""
|
246
257
|
Similar to hover_on_element(), but uses found element, not a selector.
|
247
258
|
"""
|
259
|
+
_reconnect_if_disconnected(driver)
|
248
260
|
hover = ActionChains(driver).move_to_element(element)
|
249
261
|
hover.perform()
|
250
262
|
return element
|
@@ -276,6 +288,7 @@ def hover_and_click(
|
|
276
288
|
timeout - number of seconds to wait for click element to appear after hover
|
277
289
|
js_click - the option to use js_click() instead of click() on the last part
|
278
290
|
"""
|
291
|
+
_reconnect_if_disconnected(driver)
|
279
292
|
start_ms = time.time() * 1000.0
|
280
293
|
stop_ms = start_ms + (timeout * 1000.0)
|
281
294
|
element = driver.find_element(by=hover_by, value=hover_selector)
|
@@ -315,6 +328,7 @@ def hover_element_and_click(
|
|
315
328
|
"""
|
316
329
|
Similar to hover_and_click(), but assumes top element is already found.
|
317
330
|
"""
|
331
|
+
_reconnect_if_disconnected(driver)
|
318
332
|
start_ms = time.time() * 1000.0
|
319
333
|
stop_ms = start_ms + (timeout * 1000.0)
|
320
334
|
hover = ActionChains(driver).move_to_element(element)
|
@@ -347,6 +361,7 @@ def hover_element_and_double_click(
|
|
347
361
|
click_by="css selector",
|
348
362
|
timeout=settings.SMALL_TIMEOUT,
|
349
363
|
):
|
364
|
+
_reconnect_if_disconnected(driver)
|
350
365
|
start_ms = time.time() * 1000.0
|
351
366
|
stop_ms = start_ms + (timeout * 1000.0)
|
352
367
|
hover = ActionChains(driver).move_to_element(element)
|
@@ -398,6 +413,7 @@ def wait_for_element_present(
|
|
398
413
|
@Returns
|
399
414
|
A web element object
|
400
415
|
"""
|
416
|
+
_reconnect_if_disconnected(driver)
|
401
417
|
element = None
|
402
418
|
start_ms = time.time() * 1000.0
|
403
419
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -457,6 +473,7 @@ def wait_for_element_visible(
|
|
457
473
|
@Returns
|
458
474
|
A web element object
|
459
475
|
"""
|
476
|
+
_reconnect_if_disconnected(driver)
|
460
477
|
element = None
|
461
478
|
is_present = False
|
462
479
|
start_ms = time.time() * 1000.0
|
@@ -538,6 +555,7 @@ def wait_for_text_visible(
|
|
538
555
|
@Returns
|
539
556
|
A web element object that contains the text searched for
|
540
557
|
"""
|
558
|
+
_reconnect_if_disconnected(driver)
|
541
559
|
element = None
|
542
560
|
is_present = False
|
543
561
|
full_text = None
|
@@ -648,6 +666,7 @@ def wait_for_exact_text_visible(
|
|
648
666
|
@Returns
|
649
667
|
A web element object that contains the text searched for
|
650
668
|
"""
|
669
|
+
_reconnect_if_disconnected(driver)
|
651
670
|
element = None
|
652
671
|
is_present = False
|
653
672
|
actual_text = None
|
@@ -758,6 +777,7 @@ def wait_for_attribute(
|
|
758
777
|
@Returns
|
759
778
|
A web element object that contains the expected attribute/value
|
760
779
|
"""
|
780
|
+
_reconnect_if_disconnected(driver)
|
761
781
|
element = None
|
762
782
|
element_present = False
|
763
783
|
attribute_present = False
|
@@ -844,6 +864,7 @@ def wait_for_element_clickable(
|
|
844
864
|
@Returns
|
845
865
|
A web element object
|
846
866
|
"""
|
867
|
+
_reconnect_if_disconnected(driver)
|
847
868
|
element = None
|
848
869
|
is_present = False
|
849
870
|
is_visible = False
|
@@ -938,6 +959,7 @@ def wait_for_element_absent(
|
|
938
959
|
timeout - the time to wait for elements in seconds
|
939
960
|
original_selector - handle pre-converted ":contains(TEXT)" selector
|
940
961
|
"""
|
962
|
+
_reconnect_if_disconnected(driver)
|
941
963
|
start_ms = time.time() * 1000.0
|
942
964
|
stop_ms = start_ms + (timeout * 1000.0)
|
943
965
|
for x in range(int(timeout * 10)):
|
@@ -985,6 +1007,7 @@ def wait_for_element_not_visible(
|
|
985
1007
|
timeout - the time to wait for the element in seconds
|
986
1008
|
original_selector - handle pre-converted ":contains(TEXT)" selector
|
987
1009
|
"""
|
1010
|
+
_reconnect_if_disconnected(driver)
|
988
1011
|
start_ms = time.time() * 1000.0
|
989
1012
|
stop_ms = start_ms + (timeout * 1000.0)
|
990
1013
|
for x in range(int(timeout * 10)):
|
@@ -1037,6 +1060,7 @@ def wait_for_text_not_visible(
|
|
1037
1060
|
@Returns
|
1038
1061
|
A web element object that contains the text searched for
|
1039
1062
|
"""
|
1063
|
+
_reconnect_if_disconnected(driver)
|
1040
1064
|
text = str(text)
|
1041
1065
|
start_ms = time.time() * 1000.0
|
1042
1066
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -1080,6 +1104,7 @@ def wait_for_exact_text_not_visible(
|
|
1080
1104
|
@Returns
|
1081
1105
|
A web element object that contains the text searched for
|
1082
1106
|
"""
|
1107
|
+
_reconnect_if_disconnected(driver)
|
1083
1108
|
text = str(text)
|
1084
1109
|
start_ms = time.time() * 1000.0
|
1085
1110
|
stop_ms = start_ms + (timeout * 1000.0)
|
@@ -1122,6 +1147,7 @@ def wait_for_non_empty_text_visible(
|
|
1122
1147
|
@Returns
|
1123
1148
|
The web element object that has text
|
1124
1149
|
"""
|
1150
|
+
_reconnect_if_disconnected(driver)
|
1125
1151
|
start_ms = time.time() * 1000.0
|
1126
1152
|
stop_ms = start_ms + (timeout * 1000.0)
|
1127
1153
|
element = None
|
@@ -1239,6 +1265,7 @@ def find_visible_elements(driver, selector, by="css selector", limit=0):
|
|
1239
1265
|
by - the type of selector being used (Default: "css selector")
|
1240
1266
|
limit - the maximum number of elements to return if > 0.
|
1241
1267
|
"""
|
1268
|
+
_reconnect_if_disconnected(driver)
|
1242
1269
|
elements = driver.find_elements(by=by, value=selector)
|
1243
1270
|
if limit and limit > 0 and len(elements) > limit:
|
1244
1271
|
elements = elements[:limit]
|
@@ -1276,6 +1303,7 @@ def save_screenshot(
|
|
1276
1303
|
If the folder provided doesn't exist, it will get created.
|
1277
1304
|
The screenshot will be in PNG format: (*.png)
|
1278
1305
|
"""
|
1306
|
+
_reconnect_if_disconnected(driver)
|
1279
1307
|
if not name.endswith(".png"):
|
1280
1308
|
name = name + ".png"
|
1281
1309
|
if folder:
|
@@ -1314,6 +1342,7 @@ def save_page_source(driver, name, folder=None):
|
|
1314
1342
|
"""
|
1315
1343
|
from seleniumbase.core import log_helper
|
1316
1344
|
|
1345
|
+
_reconnect_if_disconnected(driver)
|
1317
1346
|
if not name.endswith(".html"):
|
1318
1347
|
name = name + ".html"
|
1319
1348
|
if folder:
|
@@ -1340,6 +1369,7 @@ def wait_for_and_accept_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1340
1369
|
driver - the webdriver object (required)
|
1341
1370
|
timeout - the time to wait for the alert in seconds
|
1342
1371
|
"""
|
1372
|
+
_reconnect_if_disconnected(driver)
|
1343
1373
|
alert = wait_for_and_switch_to_alert(driver, timeout)
|
1344
1374
|
alert_text = alert.text
|
1345
1375
|
alert.accept()
|
@@ -1353,6 +1383,7 @@ def wait_for_and_dismiss_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1353
1383
|
driver - the webdriver object (required)
|
1354
1384
|
timeout - the time to wait for the alert in seconds
|
1355
1385
|
"""
|
1386
|
+
_reconnect_if_disconnected(driver)
|
1356
1387
|
alert = wait_for_and_switch_to_alert(driver, timeout)
|
1357
1388
|
alert_text = alert.text
|
1358
1389
|
alert.dismiss()
|
@@ -1368,6 +1399,7 @@ def wait_for_and_switch_to_alert(driver, timeout=settings.LARGE_TIMEOUT):
|
|
1368
1399
|
driver - the webdriver object (required)
|
1369
1400
|
timeout - the time to wait for the alert in seconds
|
1370
1401
|
"""
|
1402
|
+
_reconnect_if_disconnected(driver)
|
1371
1403
|
start_ms = time.time() * 1000.0
|
1372
1404
|
stop_ms = start_ms + (timeout * 1000.0)
|
1373
1405
|
for x in range(int(timeout * 10)):
|
@@ -1395,6 +1427,7 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|
1395
1427
|
frame - the frame element, name, id, index, or selector
|
1396
1428
|
timeout - the time to wait for the alert in seconds
|
1397
1429
|
"""
|
1430
|
+
_reconnect_if_disconnected(driver)
|
1398
1431
|
start_ms = time.time() * 1000.0
|
1399
1432
|
stop_ms = start_ms + (timeout * 1000.0)
|
1400
1433
|
for x in range(int(timeout * 10)):
|
@@ -1460,6 +1493,7 @@ def switch_to_window(
|
|
1460
1493
|
timeout - the time to wait for the window in seconds
|
1461
1494
|
uc_lock - if UC Mode and True, switch_to_window() uses thread-locking
|
1462
1495
|
"""
|
1496
|
+
_reconnect_if_disconnected(driver)
|
1463
1497
|
if window == -1:
|
1464
1498
|
window = len(driver.window_handles) - 1
|
1465
1499
|
start_ms = time.time() * 1000.0
|
@@ -1513,11 +1547,36 @@ def switch_to_window(
|
|
1513
1547
|
timeout_exception(Exception, message)
|
1514
1548
|
|
1515
1549
|
|
1550
|
+
############
|
1551
|
+
|
1552
|
+
# Special methods for use with UC Mode
|
1553
|
+
|
1554
|
+
def _reconnect_if_disconnected(driver):
|
1555
|
+
if (
|
1556
|
+
hasattr(driver, "_is_using_uc")
|
1557
|
+
and driver._is_using_uc
|
1558
|
+
and hasattr(driver, "_is_connected")
|
1559
|
+
and not driver._is_connected
|
1560
|
+
and hasattr(driver, "is_connected")
|
1561
|
+
and not driver.is_connected()
|
1562
|
+
):
|
1563
|
+
with suppress(Exception):
|
1564
|
+
driver.connect()
|
1565
|
+
|
1566
|
+
|
1567
|
+
def __is_cdp_swap_needed(driver):
|
1568
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
1569
|
+
return shared_utils.is_cdp_swap_needed(driver)
|
1570
|
+
|
1571
|
+
|
1516
1572
|
############
|
1517
1573
|
|
1518
1574
|
# Support methods for direct use from driver
|
1519
1575
|
|
1520
1576
|
def open_url(driver, url):
|
1577
|
+
if __is_cdp_swap_needed(driver):
|
1578
|
+
driver.cdp.open(url)
|
1579
|
+
return
|
1521
1580
|
url = str(url).strip() # Remove leading and trailing whitespace
|
1522
1581
|
if not page_utils.looks_like_a_page_url(url):
|
1523
1582
|
if page_utils.is_valid_url("https://" + url):
|
@@ -1527,6 +1586,9 @@ def open_url(driver, url):
|
|
1527
1586
|
|
1528
1587
|
def click(driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT):
|
1529
1588
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1589
|
+
if __is_cdp_swap_needed(driver):
|
1590
|
+
driver.cdp.click(selector)
|
1591
|
+
return
|
1530
1592
|
element = wait_for_element_clickable(
|
1531
1593
|
driver, selector, by=by, timeout=timeout
|
1532
1594
|
)
|
@@ -1534,6 +1596,9 @@ def click(driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT):
|
|
1534
1596
|
|
1535
1597
|
|
1536
1598
|
def click_link(driver, link_text, timeout=settings.SMALL_TIMEOUT):
|
1599
|
+
if __is_cdp_swap_needed(driver):
|
1600
|
+
driver.cdp.click_link(link_text)
|
1601
|
+
return
|
1537
1602
|
element = wait_for_element_clickable(
|
1538
1603
|
driver, link_text, by="link text", timeout=timeout
|
1539
1604
|
)
|
@@ -1544,6 +1609,9 @@ def click_if_visible(
|
|
1544
1609
|
driver, selector, by="css selector", timeout=0
|
1545
1610
|
):
|
1546
1611
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1612
|
+
if __is_cdp_swap_needed(driver):
|
1613
|
+
driver.cdp.click_if_visible(selector)
|
1614
|
+
return
|
1547
1615
|
if is_element_visible(driver, selector, by=by):
|
1548
1616
|
click(driver, selector, by=by, timeout=1)
|
1549
1617
|
elif timeout > 0:
|
@@ -1556,6 +1624,9 @@ def click_if_visible(
|
|
1556
1624
|
|
1557
1625
|
|
1558
1626
|
def click_active_element(driver):
|
1627
|
+
if __is_cdp_swap_needed(driver):
|
1628
|
+
driver.cdp.click_active_element()
|
1629
|
+
return
|
1559
1630
|
driver.execute_script("document.activeElement.click();")
|
1560
1631
|
|
1561
1632
|
|
@@ -1563,6 +1634,9 @@ def js_click(
|
|
1563
1634
|
driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
|
1564
1635
|
):
|
1565
1636
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1637
|
+
if __is_cdp_swap_needed(driver):
|
1638
|
+
driver.cdp.click(selector)
|
1639
|
+
return
|
1566
1640
|
element = wait_for_element_present(
|
1567
1641
|
driver, selector, by=by, timeout=timeout
|
1568
1642
|
)
|
@@ -1588,6 +1662,9 @@ def send_keys(
|
|
1588
1662
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1589
1663
|
):
|
1590
1664
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1665
|
+
if __is_cdp_swap_needed(driver):
|
1666
|
+
driver.cdp.send_keys(selector, text)
|
1667
|
+
return
|
1591
1668
|
element = wait_for_element_present(
|
1592
1669
|
driver, selector, by=by, timeout=timeout
|
1593
1670
|
)
|
@@ -1602,6 +1679,9 @@ def press_keys(
|
|
1602
1679
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1603
1680
|
):
|
1604
1681
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1682
|
+
if __is_cdp_swap_needed(driver):
|
1683
|
+
driver.cdp.press_keys(selector, text)
|
1684
|
+
return
|
1605
1685
|
element = wait_for_element_present(
|
1606
1686
|
driver, selector, by=by, timeout=timeout
|
1607
1687
|
)
|
@@ -1618,6 +1698,9 @@ def update_text(
|
|
1618
1698
|
driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT
|
1619
1699
|
):
|
1620
1700
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1701
|
+
if __is_cdp_swap_needed(driver):
|
1702
|
+
driver.cdp.type(selector, text)
|
1703
|
+
return
|
1621
1704
|
element = wait_for_element_clickable(
|
1622
1705
|
driver, selector, by=by, timeout=timeout
|
1623
1706
|
)
|
@@ -1631,6 +1714,9 @@ def update_text(
|
|
1631
1714
|
|
1632
1715
|
def submit(driver, selector, by="css selector"):
|
1633
1716
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1717
|
+
if __is_cdp_swap_needed(driver):
|
1718
|
+
driver.cdp.send_keys(selector, "\r\n")
|
1719
|
+
return
|
1634
1720
|
element = wait_for_element_clickable(
|
1635
1721
|
driver, selector, by=by, timeout=settings.SMALL_TIMEOUT
|
1636
1722
|
)
|
@@ -1655,6 +1741,9 @@ def assert_element_visible(
|
|
1655
1741
|
elif page_utils.is_valid_by(selector):
|
1656
1742
|
original_selector = by
|
1657
1743
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1744
|
+
if __is_cdp_swap_needed(driver):
|
1745
|
+
driver.cdp.assert_element(selector)
|
1746
|
+
return True
|
1658
1747
|
wait_for_element_visible(
|
1659
1748
|
driver,
|
1660
1749
|
selector,
|
@@ -1673,6 +1762,9 @@ def assert_element_present(
|
|
1673
1762
|
elif page_utils.is_valid_by(selector):
|
1674
1763
|
original_selector = by
|
1675
1764
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1765
|
+
if __is_cdp_swap_needed(driver):
|
1766
|
+
driver.cdp.assert_element_present(selector)
|
1767
|
+
return True
|
1676
1768
|
wait_for_element_present(
|
1677
1769
|
driver,
|
1678
1770
|
selector,
|
@@ -1708,6 +1800,9 @@ def assert_text(
|
|
1708
1800
|
timeout=settings.SMALL_TIMEOUT,
|
1709
1801
|
):
|
1710
1802
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1803
|
+
if __is_cdp_swap_needed(driver):
|
1804
|
+
driver.cdp.assert_text(text, selector)
|
1805
|
+
return True
|
1711
1806
|
wait_for_text_visible(
|
1712
1807
|
driver, text.strip(), selector, by=by, timeout=timeout
|
1713
1808
|
)
|
@@ -1721,6 +1816,9 @@ def assert_exact_text(
|
|
1721
1816
|
timeout=settings.SMALL_TIMEOUT,
|
1722
1817
|
):
|
1723
1818
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1819
|
+
if __is_cdp_swap_needed(driver):
|
1820
|
+
driver.cdp.assert_exact_text(text, selector)
|
1821
|
+
return True
|
1724
1822
|
wait_for_exact_text_visible(
|
1725
1823
|
driver, text.strip(), selector, by=by, timeout=timeout
|
1726
1824
|
)
|
@@ -1763,6 +1861,8 @@ def wait_for_element(
|
|
1763
1861
|
elif page_utils.is_valid_by(selector):
|
1764
1862
|
original_selector = by
|
1765
1863
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1864
|
+
if __is_cdp_swap_needed(driver):
|
1865
|
+
return driver.cdp.select(selector)
|
1766
1866
|
return wait_for_element_visible(
|
1767
1867
|
driver=driver,
|
1768
1868
|
selector=selector,
|
@@ -1784,6 +1884,8 @@ def wait_for_selector(
|
|
1784
1884
|
elif page_utils.is_valid_by(selector):
|
1785
1885
|
original_selector = by
|
1786
1886
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1887
|
+
if __is_cdp_swap_needed(driver):
|
1888
|
+
return driver.cdp.select(selector)
|
1787
1889
|
return wait_for_element_present(
|
1788
1890
|
driver=driver,
|
1789
1891
|
selector=selector,
|
@@ -1801,6 +1903,8 @@ def wait_for_text(
|
|
1801
1903
|
timeout=settings.LARGE_TIMEOUT,
|
1802
1904
|
):
|
1803
1905
|
selector, by = page_utils.recalculate_selector(selector, by)
|
1906
|
+
if __is_cdp_swap_needed(driver):
|
1907
|
+
return driver.cdp.find_element(selector)
|
1804
1908
|
return wait_for_text_visible(
|
1805
1909
|
driver=driver,
|
1806
1910
|
text=text,
|
@@ -1848,6 +1952,8 @@ def get_text(
|
|
1848
1952
|
by="css selector",
|
1849
1953
|
timeout=settings.LARGE_TIMEOUT
|
1850
1954
|
):
|
1955
|
+
if __is_cdp_swap_needed(driver):
|
1956
|
+
return driver.cdp.get_text(selector)
|
1851
1957
|
element = wait_for_element(
|
1852
1958
|
driver=driver,
|
1853
1959
|
selector=selector,
|
@@ -73,6 +73,32 @@ def fix_colorama_if_windows():
|
|
73
73
|
colorama.just_fix_windows_console()
|
74
74
|
|
75
75
|
|
76
|
+
def fix_url_as_needed(url):
|
77
|
+
if not url:
|
78
|
+
url = "data:,"
|
79
|
+
elif url.startswith("//"):
|
80
|
+
url = "https:" + url
|
81
|
+
elif ":" not in url:
|
82
|
+
url = "https://" + url
|
83
|
+
return url
|
84
|
+
|
85
|
+
|
86
|
+
def is_cdp_swap_needed(driver):
|
87
|
+
"""
|
88
|
+
When someone is using CDP Mode with a disconnected webdriver,
|
89
|
+
but they forget to reconnect before calling a webdriver method,
|
90
|
+
this method is used to substitute the webdriver method for a
|
91
|
+
CDP Mode method instead, which keeps CDP Stealth Mode enabled.
|
92
|
+
For other webdriver methods, SeleniumBase will reconnect first.
|
93
|
+
"""
|
94
|
+
return (
|
95
|
+
driver.is_cdp_mode_active()
|
96
|
+
# and hasattr(driver, "_is_connected")
|
97
|
+
# and not driver._is_connected
|
98
|
+
and not driver.is_connected()
|
99
|
+
)
|
100
|
+
|
101
|
+
|
76
102
|
def format_exc(exception, message):
|
77
103
|
"""Formats an exception message to make the output cleaner."""
|
78
104
|
from selenium.common.exceptions import ElementNotVisibleException
|