seleniumbase 4.24.11__py3-none-any.whl → 4.33.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. sbase/__init__.py +1 -0
  2. sbase/steps.py +7 -0
  3. seleniumbase/__init__.py +16 -7
  4. seleniumbase/__version__.py +1 -1
  5. seleniumbase/behave/behave_sb.py +97 -32
  6. seleniumbase/common/decorators.py +16 -7
  7. seleniumbase/config/proxy_list.py +3 -3
  8. seleniumbase/config/settings.py +4 -0
  9. seleniumbase/console_scripts/logo_helper.py +47 -8
  10. seleniumbase/console_scripts/run.py +345 -335
  11. seleniumbase/console_scripts/sb_behave_gui.py +5 -12
  12. seleniumbase/console_scripts/sb_caseplans.py +6 -13
  13. seleniumbase/console_scripts/sb_commander.py +5 -12
  14. seleniumbase/console_scripts/sb_install.py +62 -54
  15. seleniumbase/console_scripts/sb_mkchart.py +13 -20
  16. seleniumbase/console_scripts/sb_mkdir.py +11 -17
  17. seleniumbase/console_scripts/sb_mkfile.py +69 -43
  18. seleniumbase/console_scripts/sb_mkpres.py +13 -20
  19. seleniumbase/console_scripts/sb_mkrec.py +88 -21
  20. seleniumbase/console_scripts/sb_objectify.py +30 -30
  21. seleniumbase/console_scripts/sb_print.py +5 -12
  22. seleniumbase/console_scripts/sb_recorder.py +16 -11
  23. seleniumbase/core/browser_launcher.py +1658 -221
  24. seleniumbase/core/log_helper.py +42 -27
  25. seleniumbase/core/mysql.py +1 -4
  26. seleniumbase/core/proxy_helper.py +35 -30
  27. seleniumbase/core/recorder_helper.py +24 -5
  28. seleniumbase/core/sb_cdp.py +1951 -0
  29. seleniumbase/core/sb_driver.py +162 -8
  30. seleniumbase/core/settings_parser.py +6 -0
  31. seleniumbase/core/style_sheet.py +10 -0
  32. seleniumbase/extensions/recorder.zip +0 -0
  33. seleniumbase/fixtures/base_case.py +1225 -614
  34. seleniumbase/fixtures/constants.py +10 -1
  35. seleniumbase/fixtures/js_utils.py +171 -144
  36. seleniumbase/fixtures/page_actions.py +177 -13
  37. seleniumbase/fixtures/page_utils.py +25 -53
  38. seleniumbase/fixtures/shared_utils.py +97 -11
  39. seleniumbase/js_code/active_css_js.py +1 -1
  40. seleniumbase/js_code/recorder_js.py +1 -1
  41. seleniumbase/plugins/base_plugin.py +2 -3
  42. seleniumbase/plugins/driver_manager.py +340 -65
  43. seleniumbase/plugins/pytest_plugin.py +276 -47
  44. seleniumbase/plugins/sb_manager.py +412 -99
  45. seleniumbase/plugins/selenium_plugin.py +122 -17
  46. seleniumbase/translate/translator.py +0 -7
  47. seleniumbase/undetected/__init__.py +59 -52
  48. seleniumbase/undetected/cdp.py +0 -1
  49. seleniumbase/undetected/cdp_driver/__init__.py +1 -0
  50. seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
  51. seleniumbase/undetected/cdp_driver/browser.py +829 -0
  52. seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
  53. seleniumbase/undetected/cdp_driver/config.py +334 -0
  54. seleniumbase/undetected/cdp_driver/connection.py +639 -0
  55. seleniumbase/undetected/cdp_driver/element.py +1168 -0
  56. seleniumbase/undetected/cdp_driver/tab.py +1323 -0
  57. seleniumbase/undetected/dprocess.py +4 -7
  58. seleniumbase/undetected/options.py +6 -8
  59. seleniumbase/undetected/patcher.py +11 -13
  60. seleniumbase/undetected/reactor.py +0 -1
  61. seleniumbase/undetected/webelement.py +16 -3
  62. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
  63. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
  64. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +67 -69
  65. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
  66. sbase/ReadMe.txt +0 -2
  67. seleniumbase/ReadMe.md +0 -25
  68. seleniumbase/common/ReadMe.md +0 -71
  69. seleniumbase/console_scripts/ReadMe.md +0 -731
  70. seleniumbase/drivers/ReadMe.md +0 -27
  71. seleniumbase/extensions/ReadMe.md +0 -12
  72. seleniumbase/masterqa/ReadMe.md +0 -61
  73. seleniumbase/resources/ReadMe.md +0 -31
  74. seleniumbase/resources/favicon.ico +0 -0
  75. seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
  76. seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
  77. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
  78. {seleniumbase-4.24.11.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 = driver.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
- try:
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 switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT):
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.switch_to.window(window_handle)
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.switch_to.window(window_handle)
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
- try:
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, text, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
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,