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.
Files changed (79) 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/detect_b_ver.py +7 -8
  25. seleniumbase/core/log_helper.py +42 -27
  26. seleniumbase/core/mysql.py +1 -4
  27. seleniumbase/core/proxy_helper.py +35 -30
  28. seleniumbase/core/recorder_helper.py +24 -5
  29. seleniumbase/core/sb_cdp.py +1951 -0
  30. seleniumbase/core/sb_driver.py +162 -8
  31. seleniumbase/core/settings_parser.py +6 -0
  32. seleniumbase/core/style_sheet.py +10 -0
  33. seleniumbase/extensions/recorder.zip +0 -0
  34. seleniumbase/fixtures/base_case.py +1234 -632
  35. seleniumbase/fixtures/constants.py +10 -1
  36. seleniumbase/fixtures/js_utils.py +171 -144
  37. seleniumbase/fixtures/page_actions.py +177 -13
  38. seleniumbase/fixtures/page_utils.py +25 -53
  39. seleniumbase/fixtures/shared_utils.py +97 -11
  40. seleniumbase/js_code/active_css_js.py +1 -1
  41. seleniumbase/js_code/recorder_js.py +1 -1
  42. seleniumbase/plugins/base_plugin.py +2 -3
  43. seleniumbase/plugins/driver_manager.py +340 -65
  44. seleniumbase/plugins/pytest_plugin.py +276 -47
  45. seleniumbase/plugins/sb_manager.py +412 -99
  46. seleniumbase/plugins/selenium_plugin.py +122 -17
  47. seleniumbase/translate/translator.py +0 -7
  48. seleniumbase/undetected/__init__.py +59 -52
  49. seleniumbase/undetected/cdp.py +0 -1
  50. seleniumbase/undetected/cdp_driver/__init__.py +1 -0
  51. seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
  52. seleniumbase/undetected/cdp_driver/browser.py +829 -0
  53. seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
  54. seleniumbase/undetected/cdp_driver/config.py +334 -0
  55. seleniumbase/undetected/cdp_driver/connection.py +639 -0
  56. seleniumbase/undetected/cdp_driver/element.py +1168 -0
  57. seleniumbase/undetected/cdp_driver/tab.py +1323 -0
  58. seleniumbase/undetected/dprocess.py +4 -7
  59. seleniumbase/undetected/options.py +6 -8
  60. seleniumbase/undetected/patcher.py +11 -13
  61. seleniumbase/undetected/reactor.py +0 -1
  62. seleniumbase/undetected/webelement.py +16 -3
  63. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
  64. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
  65. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
  66. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
  67. sbase/ReadMe.txt +0 -2
  68. seleniumbase/ReadMe.md +0 -25
  69. seleniumbase/common/ReadMe.md +0 -71
  70. seleniumbase/console_scripts/ReadMe.md +0 -731
  71. seleniumbase/drivers/ReadMe.md +0 -27
  72. seleniumbase/extensions/ReadMe.md +0 -12
  73. seleniumbase/masterqa/ReadMe.md +0 -61
  74. seleniumbase/resources/ReadMe.md +0 -31
  75. seleniumbase/resources/favicon.ico +0 -0
  76. seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
  77. seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
  78. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
  79. {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 = 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,