seleniumbase 4.31.6a4__py3-none-any.whl → 4.32.0__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.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.31.6a4"
2
+ __version__ = "4.32.0"
@@ -43,23 +43,24 @@ def print_runtime(description=None, limit=None):
43
43
  finally:
44
44
  end_time = time.time()
45
45
  run_time = end_time - start_time
46
+ name = description
46
47
  # Print times with a statistically significant number of decimal places
47
48
  if run_time < 0.0001:
48
- print(" {%s} ran for %.7f seconds." % (description, run_time))
49
+ print("<info> - {%s} ran for %.7f seconds." % (name, run_time))
49
50
  elif run_time < 0.001:
50
- print(" {%s} ran for %.6f seconds." % (description, run_time))
51
+ print("<info> - {%s} ran for %.6f seconds." % (name, run_time))
51
52
  elif run_time < 0.01:
52
- print(" {%s} ran for %.5f seconds." % (description, run_time))
53
+ print("<info> - {%s} ran for %.5f seconds." % (name, run_time))
53
54
  elif run_time < 0.1:
54
- print(" {%s} ran for %.4f seconds." % (description, run_time))
55
+ print("<info> - {%s} ran for %.4f seconds." % (name, run_time))
55
56
  elif run_time < 1:
56
- print(" {%s} ran for %.3f seconds." % (description, run_time))
57
+ print("<info> - {%s} ran for %.3f seconds." % (name, run_time))
57
58
  else:
58
- print(" {%s} ran for %.2f seconds." % (description, run_time))
59
+ print("<info> - {%s} ran for %.2f seconds." % (name, run_time))
59
60
  if limit and limit > 0 and run_time > limit:
60
61
  message = (
61
62
  "\n {%s} duration of %.2fs exceeded the time limit of %.2fs!"
62
- % (description, run_time, limit)
63
+ % (name, run_time, limit)
63
64
  )
64
65
  if exception:
65
66
  message = exception.msg + "\nAND " + message
@@ -811,7 +811,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
811
811
  zip_ref.extractall(downloads_folder)
812
812
  zip_ref.close()
813
813
  os.remove(zip_file_path)
814
- shutil.copyfile(driver_path, os.path.join(downloads_folder, filename))
814
+ shutil.copy3(driver_path, os.path.join(downloads_folder, filename))
815
815
  log_d("%sUnzip Complete!%s\n" % (c2, cr))
816
816
  to_remove = [
817
817
  "%s/%s/ruby_example/Gemfile" % (downloads_folder, h_ie_fn),
@@ -953,7 +953,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
953
953
  )
954
954
  if copy_to_path and os.path.exists(LOCAL_PATH):
955
955
  path_file = LOCAL_PATH + f_name
956
- shutil.copyfile(new_file, path_file)
956
+ shutil.copy2(new_file, path_file)
957
957
  make_executable(path_file)
958
958
  log_d("Also copied to: %s%s%s" % (c3, path_file, cr))
959
959
  log_d("")
@@ -1042,7 +1042,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1042
1042
  )
1043
1043
  if copy_to_path and os.path.exists(LOCAL_PATH):
1044
1044
  path_file = LOCAL_PATH + f_name
1045
- shutil.copyfile(new_file, path_file)
1045
+ shutil.copy2(new_file, path_file)
1046
1046
  make_executable(path_file)
1047
1047
  log_d("Also copied to: %s%s%s" % (c3, path_file, cr))
1048
1048
  log_d("")
@@ -1078,7 +1078,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1078
1078
  )
1079
1079
  if copy_to_path and os.path.exists(LOCAL_PATH):
1080
1080
  path_file = LOCAL_PATH + f_name
1081
- shutil.copyfile(new_file, path_file)
1081
+ shutil.copy2(new_file, path_file)
1082
1082
  make_executable(path_file)
1083
1083
  log_d("Also copied to: %s%s%s" % (c3, path_file, cr))
1084
1084
  log_d("")
@@ -29,6 +29,7 @@ from seleniumbase.core import detect_b_ver
29
29
  from seleniumbase.core import download_helper
30
30
  from seleniumbase.core import proxy_helper
31
31
  from seleniumbase.core import sb_driver
32
+ from seleniumbase.core import sb_cdp
32
33
  from seleniumbase.fixtures import constants
33
34
  from seleniumbase.fixtures import js_utils
34
35
  from seleniumbase.fixtures import page_actions
@@ -153,8 +154,10 @@ def extend_driver(driver):
153
154
  page.find_element = DM.find_element
154
155
  page.find_elements = DM.find_elements
155
156
  page.locator = DM.locator
157
+ page.get_current_url = DM.get_current_url
156
158
  page.get_page_source = DM.get_page_source
157
159
  page.get_title = DM.get_title
160
+ page.get_page_title = DM.get_title
158
161
  page.switch_to_default_window = DM.switch_to_default_window
159
162
  page.switch_to_newest_window = DM.switch_to_newest_window
160
163
  page.open_new_window = DM.open_new_window
@@ -206,6 +209,9 @@ def extend_driver(driver):
206
209
  driver.is_valid_url = DM.is_valid_url
207
210
  driver.is_alert_present = DM.is_alert_present
208
211
  driver.is_online = DM.is_online
212
+ driver.is_connected = DM.is_connected
213
+ driver.is_uc_mode_active = DM.is_uc_mode_active
214
+ driver.is_cdp_mode_active = DM.is_cdp_mode_active
209
215
  driver.js_click = DM.js_click
210
216
  driver.get_text = DM.get_text
211
217
  driver.get_active_element_css = DM.get_active_element_css
@@ -217,8 +223,10 @@ def extend_driver(driver):
217
223
  driver.highlight_if_visible = DM.highlight_if_visible
218
224
  driver.sleep = time.sleep
219
225
  driver.get_attribute = DM.get_attribute
226
+ driver.get_current_url = DM.get_current_url
220
227
  driver.get_page_source = DM.get_page_source
221
228
  driver.get_title = DM.get_title
229
+ driver.get_page_title = DM.get_title
222
230
  driver.switch_to_default_window = DM.switch_to_default_window
223
231
  driver.switch_to_newest_window = DM.switch_to_newest_window
224
232
  driver.open_new_window = DM.open_new_window
@@ -362,6 +370,11 @@ def has_captcha(text):
362
370
  return False
363
371
 
364
372
 
373
+ def __is_cdp_swap_needed(driver):
374
+ """If the driver is disconnected, use a CDP method when available."""
375
+ return shared_utils.is_cdp_swap_needed(driver)
376
+
377
+
365
378
  def uc_special_open_if_cf(
366
379
  driver,
367
380
  url,
@@ -432,10 +445,11 @@ def uc_special_open_if_cf(
432
445
 
433
446
 
434
447
  def uc_open(driver, url):
435
- if url.startswith("//"):
436
- url = "https:" + url
437
- elif ":" not in url:
438
- url = "https://" + url
448
+ url = shared_utils.fix_url_as_needed(url)
449
+ if __is_cdp_swap_needed(driver):
450
+ driver.cdp.get(url)
451
+ time.sleep(0.3)
452
+ return
439
453
  if (url.startswith("http:") or url.startswith("https:")):
440
454
  with driver:
441
455
  script = 'window.location.href = "%s";' % url
@@ -446,10 +460,11 @@ def uc_open(driver, url):
446
460
 
447
461
 
448
462
  def uc_open_with_tab(driver, url):
449
- if url.startswith("//"):
450
- url = "https:" + url
451
- elif ":" not in url:
452
- url = "https://" + url
463
+ url = shared_utils.fix_url_as_needed(url)
464
+ if __is_cdp_swap_needed(driver):
465
+ driver.cdp.get(url)
466
+ time.sleep(0.3)
467
+ return
453
468
  if (url.startswith("http:") or url.startswith("https:")):
454
469
  with driver:
455
470
  driver.execute_script('window.open("%s","_blank");' % url)
@@ -462,12 +477,13 @@ def uc_open_with_tab(driver, url):
462
477
 
463
478
  def uc_open_with_reconnect(driver, url, reconnect_time=None):
464
479
  """Open a url, disconnect chromedriver, wait, and reconnect."""
480
+ url = shared_utils.fix_url_as_needed(url)
481
+ if __is_cdp_swap_needed(driver):
482
+ driver.cdp.get(url)
483
+ time.sleep(0.3)
484
+ return
465
485
  if not reconnect_time:
466
486
  reconnect_time = constants.UC.RECONNECT_TIME
467
- if url.startswith("//"):
468
- url = "https:" + url
469
- elif ":" not in url:
470
- url = "https://" + url
471
487
  if (url.startswith("http:") or url.startswith("https:")):
472
488
  script = 'window.open("%s","_blank");' % url
473
489
  driver.execute_script(script)
@@ -493,15 +509,157 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None):
493
509
  return None
494
510
 
495
511
 
512
+ def uc_open_with_cdp_mode(driver, url=None):
513
+ import asyncio
514
+ from seleniumbase.undetected.cdp_driver import cdp_util
515
+
516
+ current_url = None
517
+ try:
518
+ current_url = driver.current_url
519
+ except Exception:
520
+ driver.connect()
521
+ current_url = driver.current_url
522
+ url_protocol = current_url.split(":")[0]
523
+ if url_protocol not in ["about", "data", "chrome"]:
524
+ script = 'window.open("data:,","_blank");'
525
+ js_utils.call_me_later(driver, script, 3)
526
+ time.sleep(0.012)
527
+ driver.close()
528
+ driver.clear_cdp_listeners()
529
+ driver.delete_all_cookies()
530
+ driver.delete_network_conditions()
531
+ driver.disconnect()
532
+
533
+ cdp_details = driver._get_cdp_details()
534
+ cdp_host = cdp_details[1].split("://")[1].split(":")[0]
535
+ cdp_port = int(cdp_details[1].split("://")[1].split(":")[1].split("/")[0])
536
+
537
+ url = shared_utils.fix_url_as_needed(url)
538
+ url_protocol = url.split(":")[0]
539
+ safe_url = True
540
+ if url_protocol not in ["about", "data", "chrome"]:
541
+ safe_url = False
542
+
543
+ loop = asyncio.new_event_loop()
544
+ asyncio.set_event_loop(loop)
545
+ driver.cdp_base = loop.run_until_complete(
546
+ cdp_util.start(host=cdp_host, port=cdp_port)
547
+ )
548
+ page = loop.run_until_complete(driver.cdp_base.get(url))
549
+ if not safe_url:
550
+ time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
551
+ cdp = types.SimpleNamespace()
552
+ CDPM = sb_cdp.CDPMethods(loop, page, driver)
553
+ cdp.get = CDPM.get
554
+ cdp.open = CDPM.get
555
+ cdp.reload = CDPM.reload
556
+ cdp.refresh = CDPM.refresh
557
+ cdp.add_handler = CDPM.add_handler
558
+ cdp.get_event_loop = CDPM.get_event_loop
559
+ cdp.find_element = CDPM.find_element
560
+ cdp.find = CDPM.find_element
561
+ cdp.locator = CDPM.find_element
562
+ cdp.find_all = CDPM.find_all
563
+ cdp.find_elements_by_text = CDPM.find_elements_by_text
564
+ cdp.select = CDPM.select
565
+ cdp.select_all = CDPM.select_all
566
+ cdp.click_link = CDPM.click_link
567
+ cdp.tile_windows = CDPM.tile_windows
568
+ cdp.get_all_cookies = CDPM.get_all_cookies
569
+ cdp.set_all_cookies = CDPM.set_all_cookies
570
+ cdp.save_cookies = CDPM.save_cookies
571
+ cdp.load_cookies = CDPM.load_cookies
572
+ cdp.clear_cookies = CDPM.clear_cookies
573
+ cdp.bring_active_window_to_front = CDPM.bring_active_window_to_front
574
+ cdp.bring_to_front = CDPM.bring_active_window_to_front
575
+ cdp.get_active_element = CDPM.get_active_element
576
+ cdp.get_active_element_css = CDPM.get_active_element_css
577
+ cdp.click = CDPM.click
578
+ cdp.click_active_element = CDPM.click_active_element
579
+ cdp.click_if_visible = CDPM.click_if_visible
580
+ cdp.mouse_click = CDPM.mouse_click
581
+ cdp.remove_element = CDPM.remove_element
582
+ cdp.remove_from_dom = CDPM.remove_from_dom
583
+ cdp.remove_elements = CDPM.remove_elements
584
+ cdp.scroll_into_view = CDPM.scroll_into_view
585
+ cdp.send_keys = CDPM.send_keys
586
+ cdp.press_keys = CDPM.press_keys
587
+ cdp.type = CDPM.type
588
+ cdp.evaluate = CDPM.evaluate
589
+ cdp.js_dumps = CDPM.js_dumps
590
+ cdp.maximize = CDPM.maximize
591
+ cdp.minimize = CDPM.minimize
592
+ cdp.medimize = CDPM.medimize
593
+ cdp.set_window_rect = CDPM.set_window_rect
594
+ cdp.reset_window_size = CDPM.reset_window_size
595
+ cdp.set_attributes = CDPM.set_attributes
596
+ cdp.internalize_links = CDPM.internalize_links
597
+ cdp.get_window = CDPM.get_window
598
+ cdp.get_element_attributes = CDPM.get_element_attributes
599
+ cdp.get_element_html = CDPM.get_element_html
600
+ cdp.get_element_rect = CDPM.get_element_rect
601
+ cdp.get_element_size = CDPM.get_element_size
602
+ cdp.get_element_position = CDPM.get_element_position
603
+ cdp.get_gui_element_rect = CDPM.get_gui_element_rect
604
+ cdp.get_gui_element_center = CDPM.get_gui_element_center
605
+ cdp.get_page_source = CDPM.get_page_source
606
+ cdp.get_user_agent = CDPM.get_user_agent
607
+ cdp.get_cookie_string = CDPM.get_cookie_string
608
+ cdp.get_locale_code = CDPM.get_locale_code
609
+ cdp.get_text = CDPM.get_text
610
+ cdp.get_title = CDPM.get_title
611
+ cdp.get_page_title = CDPM.get_title
612
+ cdp.get_current_url = CDPM.get_current_url
613
+ cdp.get_origin = CDPM.get_origin
614
+ cdp.get_nested_element = CDPM.get_nested_element
615
+ cdp.get_document = CDPM.get_document
616
+ cdp.get_flattened_document = CDPM.get_flattened_document
617
+ cdp.get_screen_rect = CDPM.get_screen_rect
618
+ cdp.get_window_rect = CDPM.get_window_rect
619
+ cdp.get_window_size = CDPM.get_window_size
620
+ cdp.nested_click = CDPM.nested_click
621
+ cdp.flash = CDPM.flash
622
+ cdp.focus = CDPM.focus
623
+ cdp.highlight_overlay = CDPM.highlight_overlay
624
+ cdp.get_window_position = CDPM.get_window_position
625
+ cdp.is_element_present = CDPM.is_element_present
626
+ cdp.is_element_visible = CDPM.is_element_visible
627
+ cdp.assert_element_present = CDPM.assert_element_present
628
+ cdp.assert_element = CDPM.assert_element
629
+ cdp.assert_element_visible = CDPM.assert_element
630
+ cdp.assert_text = CDPM.assert_text
631
+ cdp.assert_exact_text = CDPM.assert_exact_text
632
+ cdp.save_screenshot = CDPM.save_screenshot
633
+ cdp.page = page # async world
634
+ cdp.driver = driver.cdp_base # async world
635
+ cdp.tab = cdp.page # shortcut (original)
636
+ cdp.browser = driver.cdp_base # shortcut (original)
637
+ cdp.util = cdp_util # shortcut (original)
638
+ core_items = types.SimpleNamespace()
639
+ core_items.browser = cdp.browser
640
+ core_items.tab = cdp.tab
641
+ core_items.util = cdp.util
642
+ cdp.core = core_items
643
+ driver.cdp = cdp
644
+ driver._is_using_cdp = True
645
+
646
+
647
+ def uc_activate_cdp_mode(driver, url=None):
648
+ uc_open_with_cdp_mode(driver, url=url)
649
+
650
+
496
651
  def uc_open_with_disconnect(driver, url, timeout=None):
497
652
  """Open a url and disconnect chromedriver.
498
653
  Then waits for the duration of the timeout.
499
654
  Note: You can't perform Selenium actions again
500
655
  until after you've called driver.connect()."""
501
- if url.startswith("//"):
502
- url = "https:" + url
503
- elif ":" not in url:
504
- url = "https://" + url
656
+ url = shared_utils.fix_url_as_needed(url)
657
+ if __is_cdp_swap_needed(driver):
658
+ driver.cdp.get(url)
659
+ time.sleep(0.3)
660
+ return
661
+ if not driver.is_connected():
662
+ driver.connect()
505
663
  if (url.startswith("http:") or url.startswith("https:")):
506
664
  script = 'window.open("%s","_blank");' % url
507
665
  driver.execute_script(script)
@@ -685,6 +843,9 @@ def uc_gui_write(driver, text):
685
843
 
686
844
 
687
845
  def get_gui_element_position(driver, selector):
846
+ if __is_cdp_swap_needed(driver):
847
+ element_rect = driver.cdp.get_gui_element_rect(selector)
848
+ return (element_rect["x"], element_rect["y"])
688
849
  element = driver.wait_for_element_present(selector, timeout=3)
689
850
  element_rect = element.rect
690
851
  window_rect = driver.get_window_rect()
@@ -823,6 +984,7 @@ def _uc_gui_click_captcha(
823
984
  blind=False,
824
985
  ctype=None,
825
986
  ):
987
+ cdp_mode_on_at_start = __is_cdp_swap_needed(driver)
826
988
  _on_a_captcha_page = None
827
989
  if ctype == "cf_t":
828
990
  if not _on_a_cf_turnstile_page(driver):
@@ -864,10 +1026,13 @@ def _uc_gui_click_captcha(
864
1026
  is_in_frame = js_utils.is_in_frame(driver)
865
1027
  if not is_in_frame:
866
1028
  # Make sure the window is on top
867
- page_actions.switch_to_window(
868
- driver, driver.current_window_handle, 2, uc_lock=False
869
- )
870
- if IS_WINDOWS:
1029
+ if __is_cdp_swap_needed(driver):
1030
+ driver.cdp.bring_active_window_to_front()
1031
+ else:
1032
+ page_actions.switch_to_window(
1033
+ driver, driver.current_window_handle, 2, uc_lock=False
1034
+ )
1035
+ if IS_WINDOWS and not __is_cdp_swap_needed(driver):
871
1036
  window_rect = driver.get_window_rect()
872
1037
  width = window_rect["width"]
873
1038
  height = window_rect["height"]
@@ -950,7 +1115,10 @@ def _uc_gui_click_captcha(
950
1115
  new_class = the_class.replaceAll('center', 'left');
951
1116
  $elements[index].setAttribute('class', new_class);}"""
952
1117
  )
953
- driver.execute_script(script)
1118
+ if __is_cdp_swap_needed(driver):
1119
+ driver.cdp.evaluate(script)
1120
+ else:
1121
+ driver.execute_script(script)
954
1122
  if not is_in_frame or needs_switch:
955
1123
  # Currently not in frame (or nested frame outside CF one)
956
1124
  try:
@@ -961,16 +1129,22 @@ def _uc_gui_click_captcha(
961
1129
  if visible_iframe:
962
1130
  if driver.is_element_present("iframe"):
963
1131
  i_x, i_y = get_gui_element_position(driver, "iframe")
964
- driver.switch_to_frame("iframe")
1132
+ if driver.is_connected():
1133
+ driver.switch_to_frame("iframe")
965
1134
  else:
966
1135
  return
967
1136
  if not i_x or not i_y:
968
1137
  return
969
1138
  try:
970
- if visible_iframe:
1139
+ if ctype == "g_rc" and not driver.is_connected():
1140
+ x = (i_x + 32) * width_ratio
1141
+ y = (i_y + 34) * width_ratio
1142
+ elif visible_iframe:
971
1143
  selector = "span"
972
1144
  if ctype == "g_rc":
973
1145
  selector = "span.recaptcha-checkbox"
1146
+ if not driver.is_connected():
1147
+ selector = "iframe"
974
1148
  element = driver.wait_for_element_present(
975
1149
  selector, timeout=2.5
976
1150
  )
@@ -981,16 +1155,18 @@ def _uc_gui_click_captcha(
981
1155
  else:
982
1156
  x = (i_x + 34) * width_ratio
983
1157
  y = (i_y + 34) * width_ratio
984
- driver.switch_to.default_content()
985
- except Exception:
986
- try:
1158
+ if driver.is_connected():
987
1159
  driver.switch_to.default_content()
988
- except Exception:
989
- return
1160
+ except Exception:
1161
+ if driver.is_connected():
1162
+ try:
1163
+ driver.switch_to.default_content()
1164
+ except Exception:
1165
+ return
990
1166
  if x and y:
991
1167
  sb_config._saved_cf_x_y = (x, y)
992
1168
  if driver.is_element_present(".footer .clearfix .ray-id"):
993
- driver.uc_open_with_disconnect(driver.current_url, 3.8)
1169
+ driver.uc_open_with_disconnect(driver.get_current_url(), 3.8)
994
1170
  else:
995
1171
  driver.disconnect()
996
1172
  with suppress(Exception):
@@ -1013,9 +1189,12 @@ def _uc_gui_click_captcha(
1013
1189
  if retry and x and y and (caught or _on_a_captcha_page(driver)):
1014
1190
  with gui_lock: # Prevent issues with multiple processes
1015
1191
  # Make sure the window is on top
1016
- page_actions.switch_to_window(
1017
- driver, driver.current_window_handle, 2, uc_lock=False
1018
- )
1192
+ if __is_cdp_swap_needed(driver):
1193
+ driver.cdp.bring_active_window_to_front()
1194
+ else:
1195
+ page_actions.switch_to_window(
1196
+ driver, driver.current_window_handle, 2, uc_lock=False
1197
+ )
1019
1198
  if driver.is_element_present("iframe"):
1020
1199
  try:
1021
1200
  driver.switch_to_frame(frame)
@@ -1035,14 +1214,18 @@ def _uc_gui_click_captcha(
1035
1214
  driver.switch_to.parent_frame(checkbox_success)
1036
1215
  return
1037
1216
  if blind:
1038
- driver.uc_open_with_disconnect(driver.current_url, 3.8)
1039
- _uc_gui_click_x_y(driver, x, y, timeframe=0.32)
1217
+ driver.uc_open_with_disconnect(driver.get_current_url(), 3.8)
1218
+ if __is_cdp_swap_needed(driver) and _on_a_captcha_page(driver):
1219
+ _uc_gui_click_x_y(driver, x, y, timeframe=0.32)
1220
+ else:
1221
+ time.sleep(0.1)
1040
1222
  else:
1041
- driver.uc_open_with_reconnect(driver.current_url, 3.8)
1223
+ driver.uc_open_with_reconnect(driver.get_current_url(), 3.8)
1042
1224
  if _on_a_captcha_page(driver):
1043
1225
  driver.disconnect()
1044
1226
  _uc_gui_click_x_y(driver, x, y, timeframe=0.32)
1045
- driver.reconnect(reconnect_time)
1227
+ if not cdp_mode_on_at_start:
1228
+ driver.reconnect(reconnect_time)
1046
1229
 
1047
1230
 
1048
1231
  def uc_gui_click_captcha(driver, frame="iframe", retry=False, blind=False):
@@ -1089,6 +1272,9 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1089
1272
  ctype = "cf_t"
1090
1273
  else:
1091
1274
  return
1275
+ if not driver.is_connected():
1276
+ driver.connect()
1277
+ time.sleep(2)
1092
1278
  install_pyautogui_if_missing(driver)
1093
1279
  import pyautogui
1094
1280
  pyautogui = get_configured_pyautogui(pyautogui)
@@ -1111,9 +1297,12 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1111
1297
  page_actions.switch_to_window(
1112
1298
  driver, driver.current_window_handle, 2, uc_lock=False
1113
1299
  )
1114
- if IS_WINDOWS and hasattr(pyautogui, "getActiveWindowTitle"):
1300
+ if (
1301
+ IS_WINDOWS
1302
+ and hasattr(pyautogui, "getActiveWindowTitle")
1303
+ ):
1115
1304
  py_a_g_title = pyautogui.getActiveWindowTitle()
1116
- window_title = driver.title
1305
+ window_title = driver.get_title()
1117
1306
  if not py_a_g_title.startswith(window_title):
1118
1307
  window_rect = driver.get_window_rect()
1119
1308
  width = window_rect["width"]
@@ -1614,6 +1803,7 @@ def _set_chrome_options(
1614
1803
  prefs["default_content_settings.popups"] = 0
1615
1804
  prefs["managed_default_content_settings.popups"] = 0
1616
1805
  prefs["profile.password_manager_enabled"] = False
1806
+ prefs["profile.password_manager_leak_detection"] = False
1617
1807
  prefs["profile.default_content_setting_values.notifications"] = 2
1618
1808
  prefs["profile.default_content_settings.popups"] = 0
1619
1809
  prefs["profile.managed_default_content_settings.popups"] = 0
@@ -3271,6 +3461,7 @@ def get_local_driver(
3271
3461
  "default_content_settings.popups": 0,
3272
3462
  "managed_default_content_settings.popups": 0,
3273
3463
  "profile.password_manager_enabled": False,
3464
+ "profile.password_manager_leak_detection": False,
3274
3465
  "profile.default_content_setting_values.notifications": 2,
3275
3466
  "profile.default_content_settings.popups": 0,
3276
3467
  "profile.managed_default_content_settings.popups": 0,
@@ -4244,13 +4435,17 @@ def get_local_driver(
4244
4435
  with uc_lock: # Avoid multithreaded issues
4245
4436
  if make_uc_driver_from_chromedriver:
4246
4437
  if os.path.exists(LOCAL_CHROMEDRIVER):
4247
- shutil.copyfile(
4248
- LOCAL_CHROMEDRIVER, LOCAL_UC_DRIVER
4249
- )
4438
+ with suppress(Exception):
4439
+ make_driver_executable_if_not(
4440
+ LOCAL_CHROMEDRIVER
4441
+ )
4442
+ shutil.copy2(LOCAL_CHROMEDRIVER, LOCAL_UC_DRIVER)
4250
4443
  elif os.path.exists(path_chromedriver):
4251
- shutil.copyfile(
4252
- path_chromedriver, LOCAL_UC_DRIVER
4253
- )
4444
+ with suppress(Exception):
4445
+ make_driver_executable_if_not(
4446
+ path_chromedriver
4447
+ )
4448
+ shutil.copy2(path_chromedriver, LOCAL_UC_DRIVER)
4254
4449
  try:
4255
4450
  make_driver_executable_if_not(LOCAL_UC_DRIVER)
4256
4451
  except Exception as e:
@@ -4670,6 +4865,9 @@ def get_local_driver(
4670
4865
  options=chrome_options,
4671
4866
  )
4672
4867
  driver.default_get = driver.get # Save copy of original
4868
+ driver.cdp = None # Set a placeholder
4869
+ driver._is_using_cdp = False
4870
+ driver._is_connected = True
4673
4871
  if uc_activated:
4674
4872
  driver.get = lambda url: uc_special_open_if_cf(
4675
4873
  driver,
@@ -4697,6 +4895,16 @@ def get_local_driver(
4697
4895
  driver.uc_click = lambda *args, **kwargs: uc_click(
4698
4896
  driver, *args, **kwargs
4699
4897
  )
4898
+ driver.uc_activate_cdp_mode = (
4899
+ lambda *args, **kwargs: uc_activate_cdp_mode(
4900
+ driver, *args, **kwargs
4901
+ )
4902
+ )
4903
+ driver.uc_open_with_cdp_mode = (
4904
+ lambda *args, **kwargs: uc_open_with_cdp_mode(
4905
+ driver, *args, **kwargs
4906
+ )
4907
+ )
4700
4908
  driver.uc_gui_press_key = (
4701
4909
  lambda *args, **kwargs: uc_gui_press_key(
4702
4910
  driver, *args, **kwargs