seleniumbase 4.31.6a3__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.
Files changed (36) hide show
  1. seleniumbase/__version__.py +1 -1
  2. seleniumbase/behave/behave_sb.py +0 -2
  3. seleniumbase/common/decorators.py +8 -7
  4. seleniumbase/console_scripts/logo_helper.py +0 -2
  5. seleniumbase/console_scripts/run.py +4 -38
  6. seleniumbase/console_scripts/sb_behave_gui.py +0 -1
  7. seleniumbase/console_scripts/sb_caseplans.py +0 -1
  8. seleniumbase/console_scripts/sb_commander.py +0 -1
  9. seleniumbase/console_scripts/sb_install.py +4 -5
  10. seleniumbase/console_scripts/sb_mkchart.py +0 -2
  11. seleniumbase/console_scripts/sb_mkdir.py +0 -2
  12. seleniumbase/console_scripts/sb_mkfile.py +0 -2
  13. seleniumbase/console_scripts/sb_mkpres.py +0 -2
  14. seleniumbase/console_scripts/sb_mkrec.py +0 -2
  15. seleniumbase/console_scripts/sb_print.py +0 -2
  16. seleniumbase/console_scripts/sb_recorder.py +0 -1
  17. seleniumbase/core/browser_launcher.py +252 -44
  18. seleniumbase/core/sb_cdp.py +898 -0
  19. seleniumbase/core/sb_driver.py +44 -0
  20. seleniumbase/fixtures/base_case.py +208 -11
  21. seleniumbase/fixtures/constants.py +1 -0
  22. seleniumbase/fixtures/js_utils.py +4 -0
  23. seleniumbase/fixtures/page_actions.py +106 -0
  24. seleniumbase/fixtures/shared_utils.py +26 -0
  25. seleniumbase/plugins/driver_manager.py +136 -47
  26. seleniumbase/plugins/pytest_plugin.py +0 -2
  27. seleniumbase/plugins/sb_manager.py +40 -2
  28. seleniumbase/translate/translator.py +0 -2
  29. seleniumbase/undetected/__init__.py +2 -0
  30. seleniumbase/undetected/patcher.py +5 -5
  31. {seleniumbase-4.31.6a3.dist-info → seleniumbase-4.32.0.dist-info}/METADATA +26 -20
  32. {seleniumbase-4.31.6a3.dist-info → seleniumbase-4.32.0.dist-info}/RECORD +36 -35
  33. {seleniumbase-4.31.6a3.dist-info → seleniumbase-4.32.0.dist-info}/WHEEL +1 -1
  34. {seleniumbase-4.31.6a3.dist-info → seleniumbase-4.32.0.dist-info}/LICENSE +0 -0
  35. {seleniumbase-4.31.6a3.dist-info → seleniumbase-4.32.0.dist-info}/entry_points.txt +0 -0
  36. {seleniumbase-4.31.6a3.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