seleniumbase 4.34.7__py3-none-any.whl → 4.36.2__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 (32) hide show
  1. seleniumbase/__init__.py +2 -0
  2. seleniumbase/__version__.py +1 -1
  3. seleniumbase/config/proxy_list.py +2 -2
  4. seleniumbase/console_scripts/sb_mkdir.py +3 -0
  5. seleniumbase/core/browser_launcher.py +160 -38
  6. seleniumbase/core/detect_b_ver.py +12 -13
  7. seleniumbase/core/proxy_helper.py +7 -5
  8. seleniumbase/core/sb_cdp.py +335 -93
  9. seleniumbase/core/sb_driver.py +7 -0
  10. seleniumbase/extensions/ad_block.zip +0 -0
  11. seleniumbase/extensions/disable_csp.zip +0 -0
  12. seleniumbase/fixtures/base_case.py +104 -19
  13. seleniumbase/fixtures/js_utils.py +33 -9
  14. seleniumbase/plugins/base_plugin.py +12 -15
  15. seleniumbase/plugins/driver_manager.py +19 -2
  16. seleniumbase/plugins/pytest_plugin.py +3 -0
  17. seleniumbase/plugins/sb_manager.py +18 -1
  18. seleniumbase/plugins/selenium_plugin.py +1 -0
  19. seleniumbase/undetected/__init__.py +38 -17
  20. seleniumbase/undetected/cdp_driver/__init__.py +2 -0
  21. seleniumbase/undetected/cdp_driver/browser.py +16 -10
  22. seleniumbase/undetected/cdp_driver/cdp_util.py +143 -8
  23. seleniumbase/undetected/cdp_driver/config.py +10 -0
  24. seleniumbase/undetected/cdp_driver/connection.py +1 -1
  25. seleniumbase/undetected/cdp_driver/tab.py +41 -4
  26. seleniumbase/undetected/webelement.py +3 -2
  27. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info}/METADATA +30 -28
  28. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info}/RECORD +32 -32
  29. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info}/WHEEL +1 -1
  30. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info}/entry_points.txt +0 -0
  31. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info/licenses}/LICENSE +0 -0
  32. {seleniumbase-4.34.7.dist-info → seleniumbase-4.36.2.dist-info}/top_level.txt +0 -0
seleniumbase/__init__.py CHANGED
@@ -8,6 +8,7 @@ from seleniumbase.__version__ import __version__
8
8
  from seleniumbase.common import decorators # noqa
9
9
  from seleniumbase.common import encryption # noqa
10
10
  from seleniumbase.core import colored_traceback
11
+ from seleniumbase.core import sb_cdp # noqa
11
12
  from seleniumbase.core.browser_launcher import get_driver # noqa
12
13
  from seleniumbase.fixtures import js_utils # noqa
13
14
  from seleniumbase.fixtures import page_actions # noqa
@@ -18,6 +19,7 @@ from seleniumbase.masterqa.master_qa import MasterQA # noqa
18
19
  from seleniumbase.plugins.sb_manager import SB # noqa
19
20
  from seleniumbase.plugins.driver_manager import Driver # noqa
20
21
  from seleniumbase.plugins.driver_manager import DriverContext # noqa
22
+ from seleniumbase.undetected import cdp_driver # noqa
21
23
  from seleniumbase import translate # noqa
22
24
 
23
25
  with suppress(Exception):
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.34.7"
2
+ __version__ = "4.36.2"
@@ -23,8 +23,8 @@ you can try finding one from one of following sites:
23
23
  """
24
24
 
25
25
  PROXY_LIST = {
26
- "example1": "35.185.196.38:3128", # (Example) - set your own proxy here
27
- "example2": "129.80.134.71:3128", # (Example)
26
+ "example1": "98.8.195.160:443", # (Example) - set your own proxy here
27
+ "example2": "200.174.198.86:8888", # (Example)
28
28
  "example3": "socks5://184.178.172.5:15303", # (Example)
29
29
  "proxy1": None,
30
30
  "proxy2": None,
@@ -631,10 +631,13 @@ def main():
631
631
  data = []
632
632
  data.append("from seleniumbase import BaseCase")
633
633
  data.append("from .google_objects import HomePage, ResultsPage")
634
+ data.append('BaseCase.main(__name__, __file__, "--uc")')
634
635
  data.append("")
635
636
  data.append("")
636
637
  data.append("class GoogleTests(BaseCase):")
637
638
  data.append(" def test_google_dot_com(self):")
639
+ data.append(" if not self.undetectable:")
640
+ data.append(" self.get_new_driver(undetectable=True)")
638
641
  data.append(' self.open("https://google.com/ncr")')
639
642
  data.append(' self.assert_title_contains("Google")')
640
643
  data.append(" self.sleep(0.05)")
@@ -1,4 +1,5 @@
1
1
  import fasteners
2
+ import json
2
3
  import logging
3
4
  import os
4
5
  import platform
@@ -107,7 +108,7 @@ def make_driver_executable_if_not(driver_path):
107
108
  shared_utils.make_executable(driver_path)
108
109
 
109
110
 
110
- def extend_driver(driver):
111
+ def extend_driver(driver, proxy_auth=False, use_uc=True):
111
112
  # Extend the driver with new methods
112
113
  driver.default_find_element = driver.find_element
113
114
  driver.default_find_elements = driver.find_elements
@@ -220,6 +221,7 @@ def extend_driver(driver):
220
221
  driver.highlight_if_visible = DM.highlight_if_visible
221
222
  driver.sleep = time.sleep
222
223
  driver.get_attribute = DM.get_attribute
224
+ driver.get_parent = DM.get_parent
223
225
  driver.get_current_url = DM.get_current_url
224
226
  driver.get_page_source = DM.get_page_source
225
227
  driver.get_title = DM.get_title
@@ -234,6 +236,12 @@ def extend_driver(driver):
234
236
  driver.reset_window_size = DM.reset_window_size
235
237
  if hasattr(driver, "proxy"):
236
238
  driver.set_wire_proxy = DM.set_wire_proxy
239
+ if proxy_auth:
240
+ # Proxy needs a moment to load in Manifest V3
241
+ if use_uc:
242
+ time.sleep(0.12)
243
+ else:
244
+ time.sleep(0.22)
237
245
  return driver
238
246
 
239
247
 
@@ -647,6 +655,7 @@ def uc_open_with_cdp_mode(driver, url=None):
647
655
  cdp.click_if_visible = CDPM.click_if_visible
648
656
  cdp.click_visible_elements = CDPM.click_visible_elements
649
657
  cdp.mouse_click = CDPM.mouse_click
658
+ cdp.get_parent = CDPM.get_parent
650
659
  cdp.remove_element = CDPM.remove_element
651
660
  cdp.remove_from_dom = CDPM.remove_from_dom
652
661
  cdp.remove_elements = CDPM.remove_elements
@@ -654,6 +663,7 @@ def uc_open_with_cdp_mode(driver, url=None):
654
663
  cdp.press_keys = CDPM.press_keys
655
664
  cdp.type = CDPM.type
656
665
  cdp.set_value = CDPM.set_value
666
+ cdp.submit = CDPM.submit
657
667
  cdp.evaluate = CDPM.evaluate
658
668
  cdp.js_dumps = CDPM.js_dumps
659
669
  cdp.maximize = CDPM.maximize
@@ -662,6 +672,8 @@ def uc_open_with_cdp_mode(driver, url=None):
662
672
  cdp.set_window_rect = CDPM.set_window_rect
663
673
  cdp.reset_window_size = CDPM.reset_window_size
664
674
  cdp.set_locale = CDPM.set_locale
675
+ cdp.set_local_storage_item = CDPM.set_local_storage_item
676
+ cdp.set_session_storage_item = CDPM.set_session_storage_item
665
677
  cdp.set_attributes = CDPM.set_attributes
666
678
  cdp.gui_press_key = CDPM.gui_press_key
667
679
  cdp.gui_press_keys = CDPM.gui_press_keys
@@ -674,6 +686,15 @@ def uc_open_with_cdp_mode(driver, url=None):
674
686
  cdp.gui_hover_element = CDPM.gui_hover_element
675
687
  cdp.gui_hover_and_click = CDPM.gui_hover_and_click
676
688
  cdp.internalize_links = CDPM.internalize_links
689
+ cdp.open_new_window = CDPM.open_new_window
690
+ cdp.switch_to_window = CDPM.switch_to_window
691
+ cdp.switch_to_newest_window = CDPM.switch_to_newest_window
692
+ cdp.open_new_tab = CDPM.open_new_tab
693
+ cdp.switch_to_tab = CDPM.switch_to_tab
694
+ cdp.switch_to_newest_tab = CDPM.switch_to_newest_tab
695
+ cdp.close_active_tab = CDPM.close_active_tab
696
+ cdp.get_active_tab = CDPM.get_active_tab
697
+ cdp.get_tabs = CDPM.get_tabs
677
698
  cdp.get_window = CDPM.get_window
678
699
  cdp.get_element_attributes = CDPM.get_element_attributes
679
700
  cdp.get_element_attribute = CDPM.get_element_attribute
@@ -688,6 +709,8 @@ def uc_open_with_cdp_mode(driver, url=None):
688
709
  cdp.get_user_agent = CDPM.get_user_agent
689
710
  cdp.get_cookie_string = CDPM.get_cookie_string
690
711
  cdp.get_locale_code = CDPM.get_locale_code
712
+ cdp.get_local_storage_item = CDPM.get_local_storage_item
713
+ cdp.get_session_storage_item = CDPM.get_session_storage_item
691
714
  cdp.get_text = CDPM.get_text
692
715
  cdp.get_title = CDPM.get_title
693
716
  cdp.get_page_title = CDPM.get_title
@@ -714,7 +737,13 @@ def uc_open_with_cdp_mode(driver, url=None):
714
737
  cdp.is_selected = CDPM.is_selected
715
738
  cdp.is_element_present = CDPM.is_element_present
716
739
  cdp.is_element_visible = CDPM.is_element_visible
740
+ cdp.is_text_visible = CDPM.is_text_visible
741
+ cdp.is_exact_text_visible = CDPM.is_exact_text_visible
742
+ cdp.wait_for_text = CDPM.wait_for_text
743
+ cdp.wait_for_text_not_visible = CDPM.wait_for_text_not_visible
717
744
  cdp.wait_for_element_visible = CDPM.wait_for_element_visible
745
+ cdp.wait_for_element_not_visible = CDPM.wait_for_element_not_visible
746
+ cdp.wait_for_element_absent = CDPM.wait_for_element_absent
718
747
  cdp.assert_element = CDPM.assert_element
719
748
  cdp.assert_element_visible = CDPM.assert_element_visible
720
749
  cdp.assert_element_present = CDPM.assert_element_present
@@ -727,6 +756,7 @@ def uc_open_with_cdp_mode(driver, url=None):
727
756
  cdp.assert_url_contains = CDPM.assert_url_contains
728
757
  cdp.assert_text = CDPM.assert_text
729
758
  cdp.assert_exact_text = CDPM.assert_exact_text
759
+ cdp.assert_text_not_visible = CDPM.assert_text_not_visible
730
760
  cdp.assert_true = CDPM.assert_true
731
761
  cdp.assert_false = CDPM.assert_false
732
762
  cdp.assert_equal = CDPM.assert_equal
@@ -740,6 +770,7 @@ def uc_open_with_cdp_mode(driver, url=None):
740
770
  cdp.scroll_up = CDPM.scroll_up
741
771
  cdp.scroll_down = CDPM.scroll_down
742
772
  cdp.save_screenshot = CDPM.save_screenshot
773
+ cdp.print_to_pdf = CDPM.print_to_pdf
743
774
  cdp.page = page # async world
744
775
  cdp.driver = driver.cdp_base # async world
745
776
  cdp.tab = cdp.page # shortcut (original)
@@ -1251,6 +1282,10 @@ def _uc_gui_click_captcha(
1251
1282
  )
1252
1283
  ):
1253
1284
  frame = '[data-testid*="challenge-"] div'
1285
+ elif driver.is_element_present(
1286
+ "form.turnstile div#turnstile-widget div:not([class])"
1287
+ ):
1288
+ frame = "form.turnstile #turnstile-widget div:not([class])"
1254
1289
  elif driver.is_element_present(
1255
1290
  'form div:not([class]):has(input[name*="cf-turn"])'
1256
1291
  ):
@@ -1260,8 +1295,17 @@ def _uc_gui_click_captcha(
1260
1295
  and driver.is_element_present("form div:not(:has(*))")
1261
1296
  ):
1262
1297
  frame = "form div:not(:has(*))"
1298
+ elif (
1299
+ driver.is_element_present('[src*="/turnstile/"]')
1300
+ and driver.is_element_present(
1301
+ "body > div#check > div:not([class])"
1302
+ )
1303
+ ):
1304
+ frame = "body > div#check > div:not([class])"
1263
1305
  elif driver.is_element_present(".cf-turnstile-wrapper"):
1264
1306
  frame = ".cf-turnstile-wrapper"
1307
+ elif driver.is_element_present('[class="cf-turnstile"]'):
1308
+ frame = '[class="cf-turnstile"]'
1265
1309
  elif driver.is_element_present(
1266
1310
  '[data-callback="onCaptchaSuccess"]'
1267
1311
  ):
@@ -1291,6 +1335,44 @@ def _uc_gui_click_captcha(
1291
1335
  driver.cdp.evaluate(script)
1292
1336
  else:
1293
1337
  driver.execute_script(script)
1338
+ elif (
1339
+ driver.is_element_present("form")
1340
+ and (
1341
+ driver.is_element_present('form div[style*="center"]')
1342
+ or driver.is_element_present('form div[style*="right"]')
1343
+ )
1344
+ ):
1345
+ script = (
1346
+ """var $elements = document.querySelectorAll(
1347
+ 'form[style], form div[style]');
1348
+ var index = 0, length = $elements.length;
1349
+ for(; index < length; index++){
1350
+ the_style = $elements[index].getAttribute('style');
1351
+ new_style = the_style.replaceAll('center', 'left');
1352
+ new_style = new_style.replaceAll('right', 'left');
1353
+ $elements[index].setAttribute('style', new_style);}"""
1354
+ )
1355
+ if __is_cdp_swap_needed(driver):
1356
+ driver.cdp.evaluate(script)
1357
+ else:
1358
+ driver.execute_script(script)
1359
+ elif (
1360
+ driver.is_element_present("form")
1361
+ and driver.is_element_present(
1362
+ 'form [id*="turnstile"] > div:not([class])'
1363
+ )
1364
+ ):
1365
+ script = (
1366
+ """var $elements = document.querySelectorAll(
1367
+ 'form [id*="turnstile"]');
1368
+ var index = 0, length = $elements.length;
1369
+ for(; index < length; index++){
1370
+ $elements[index].setAttribute('align', 'left');}"""
1371
+ )
1372
+ if __is_cdp_swap_needed(driver):
1373
+ driver.cdp.evaluate(script)
1374
+ else:
1375
+ driver.execute_script(script)
1294
1376
  if not is_in_frame or needs_switch:
1295
1377
  # Currently not in frame (or nested frame outside CF one)
1296
1378
  try:
@@ -1532,6 +1614,17 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1532
1614
  ):
1533
1615
  frame = "form div:not(:has(*))"
1534
1616
  tab_up_first = True
1617
+ elif (
1618
+ driver.is_element_present('[src*="/turnstile/"]')
1619
+ and driver.is_element_present(
1620
+ "body > div#check > div:not([class])"
1621
+ )
1622
+ ):
1623
+ frame = "body > div#check > div:not([class])"
1624
+ elif driver.is_element_present(".cf-turnstile-wrapper"):
1625
+ frame = ".cf-turnstile-wrapper"
1626
+ elif driver.is_element_present('[class="cf-turnstile"]'):
1627
+ frame = '[class="cf-turnstile"]'
1535
1628
  else:
1536
1629
  return
1537
1630
  else:
@@ -1598,9 +1691,19 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1598
1691
  ):
1599
1692
  driver.uc_open_with_disconnect(driver.current_url, 3.8)
1600
1693
  with suppress(Exception):
1694
+ if "--debug" in sys.argv:
1695
+ if sb_config._saved_cf_tab_count == 1:
1696
+ print(' <DEBUG> pyautogui.press("\\t")')
1697
+ else:
1698
+ print(
1699
+ ' <DEBUG> pyautogui.press("\\t") * %s'
1700
+ % sb_config._saved_cf_tab_count
1701
+ )
1601
1702
  for i in range(sb_config._saved_cf_tab_count):
1602
1703
  pyautogui.press("\t")
1603
1704
  time.sleep(0.027)
1705
+ if "--debug" in sys.argv:
1706
+ print(' <DEBUG> pyautogui.press(" ")')
1604
1707
  pyautogui.press(" ")
1605
1708
  else:
1606
1709
  driver.disconnect()
@@ -1987,6 +2090,7 @@ def _set_chrome_options(
1987
2090
  prefs["download.default_directory"] = downloads_path
1988
2091
  prefs["download.directory_upgrade"] = True
1989
2092
  prefs["download.prompt_for_download"] = False
2093
+ prefs["download_bubble.partial_view_enabled"] = False
1990
2094
  prefs["credentials_enable_service"] = False
1991
2095
  prefs["local_discovery.notifications_enabled"] = False
1992
2096
  prefs["safebrowsing.enabled"] = False # Prevent PW "data breach" pop-ups
@@ -2023,6 +2127,15 @@ def _set_chrome_options(
2023
2127
  prefs["enable_do_not_track"] = True
2024
2128
  if external_pdf:
2025
2129
  prefs["plugins.always_open_pdf_externally"] = True
2130
+ pdf_settings = {
2131
+ "recentDestinations": [
2132
+ {"id": "Save as PDF", "origin": "local", "account": ""}
2133
+ ],
2134
+ "selectedDestinationId": "Save as PDF",
2135
+ "version": 2,
2136
+ }
2137
+ app_state = "printing.print_preview_sticky_settings.appState"
2138
+ prefs[app_state] = json.dumps(pdf_settings)
2026
2139
  if proxy_string or proxy_pac_url:
2027
2140
  # Implementation of https://stackoverflow.com/q/65705775/7058266
2028
2141
  prefs["webrtc.ip_handling_policy"] = "disable_non_proxied_udp"
@@ -2255,6 +2368,7 @@ def _set_chrome_options(
2255
2368
  or proxy_string
2256
2369
  ):
2257
2370
  chrome_options.add_argument("--ignore-certificate-errors")
2371
+ chrome_options.add_argument("--ignore-ssl-errors=yes")
2258
2372
  if not enable_ws:
2259
2373
  chrome_options.add_argument("--disable-web-security")
2260
2374
  if (
@@ -2279,7 +2393,14 @@ def _set_chrome_options(
2279
2393
  and not enable_3d_apis
2280
2394
  ):
2281
2395
  chrome_options.add_argument("--disable-gpu")
2282
- if not IS_LINUX and is_using_uc(undetectable, browser_name):
2396
+ if (
2397
+ (not IS_LINUX and is_using_uc(undetectable, browser_name))
2398
+ or (
2399
+ IS_MAC
2400
+ and binary_location
2401
+ and "chrome-headless-shell" in binary_location
2402
+ )
2403
+ ):
2283
2404
  chrome_options.add_argument("--disable-dev-shm-usage")
2284
2405
  chrome_options.add_argument("--disable-application-cache")
2285
2406
  if IS_LINUX:
@@ -3189,7 +3310,6 @@ def get_remote_driver(
3189
3310
  from seleniumbase.core import capabilities_parser
3190
3311
  desired_caps = capabilities_parser.get_desired_capabilities(cap_file)
3191
3312
  if cap_string:
3192
- import json
3193
3313
  try:
3194
3314
  extra_caps = json.loads(str(cap_string))
3195
3315
  except Exception as e:
@@ -3568,6 +3688,7 @@ def get_local_driver(
3568
3688
  Can also be used to spin up additional browsers for the same test."""
3569
3689
  downloads_path = DOWNLOADS_FOLDER
3570
3690
  b_path = binary_location
3691
+ use_uc = is_using_uc(undetectable, browser_name)
3571
3692
  if use_wire:
3572
3693
  pip_find_lock = fasteners.InterProcessLock(
3573
3694
  constants.PipInstall.FINDLOCK
@@ -4041,7 +4162,7 @@ def get_local_driver(
4041
4162
  edge_options.add_argument("--headless=old")
4042
4163
  else:
4043
4164
  edge_options.add_argument("--headless")
4044
- if mobile_emulator and not is_using_uc(undetectable, browser_name):
4165
+ if mobile_emulator and not use_uc:
4045
4166
  emulator_settings = {}
4046
4167
  device_metrics = {}
4047
4168
  if (
@@ -4105,7 +4226,7 @@ def get_local_driver(
4105
4226
  settings.CHROME_START_HEIGHT,
4106
4227
  )
4107
4228
  )
4108
- if user_data_dir and not is_using_uc(undetectable, browser_name):
4229
+ if user_data_dir and not use_uc:
4109
4230
  abs_path = os.path.abspath(user_data_dir)
4110
4231
  edge_options.add_argument("--user-data-dir=%s" % abs_path)
4111
4232
  if extension_zip:
@@ -4140,7 +4261,7 @@ def get_local_driver(
4140
4261
  edge_options.add_argument("--disable-prompt-on-repost")
4141
4262
  if not enable_3d_apis:
4142
4263
  edge_options.add_argument("--disable-3d-apis")
4143
- if headless or headless2 or is_using_uc(undetectable, browser_name):
4264
+ if headless or headless2 or use_uc:
4144
4265
  edge_options.add_argument("--disable-renderer-backgrounding")
4145
4266
  edge_options.add_argument("--disable-backgrounding-occluded-windows")
4146
4267
  edge_options.add_argument("--disable-client-side-phishing-detection")
@@ -4205,6 +4326,7 @@ def get_local_driver(
4205
4326
  edge_options.add_argument("--log-level=3")
4206
4327
  edge_options.add_argument("--no-first-run")
4207
4328
  edge_options.add_argument("--ignore-certificate-errors")
4329
+ edge_options.add_argument("--ignore-ssl-errors=yes")
4208
4330
  if devtools and not headless:
4209
4331
  edge_options.add_argument("--auto-open-devtools-for-tabs")
4210
4332
  edge_options.add_argument("--allow-file-access-from-files")
@@ -4212,10 +4334,7 @@ def get_local_driver(
4212
4334
  edge_options.add_argument("--allow-running-insecure-content")
4213
4335
  if user_agent:
4214
4336
  edge_options.add_argument("--user-agent=%s" % user_agent)
4215
- if (
4216
- IS_LINUX
4217
- or (IS_MAC and not is_using_uc(undetectable, browser_name))
4218
- ):
4337
+ if IS_LINUX or (IS_MAC and not use_uc):
4219
4338
  edge_options.add_argument("--no-sandbox")
4220
4339
  if remote_debug:
4221
4340
  # To access the Debugger, go to: edge://inspect/#devices
@@ -4229,10 +4348,7 @@ def get_local_driver(
4229
4348
  if swiftshader:
4230
4349
  edge_options.add_argument("--use-gl=angle")
4231
4350
  edge_options.add_argument("--use-angle=swiftshader-webgl")
4232
- elif (
4233
- not is_using_uc(undetectable, browser_name)
4234
- and not enable_3d_apis
4235
- ):
4351
+ elif not use_uc and not enable_3d_apis:
4236
4352
  edge_options.add_argument("--disable-gpu")
4237
4353
  if IS_LINUX:
4238
4354
  edge_options.add_argument("--disable-dev-shm-usage")
@@ -4479,14 +4595,14 @@ def get_local_driver(
4479
4595
  and len(saved_mcv.split(".")) == 4
4480
4596
  ):
4481
4597
  driver_version = saved_mcv
4482
- if is_using_uc(undetectable, browser_name):
4598
+ if use_uc:
4483
4599
  use_br_version_for_uc = True
4484
4600
  if (
4485
4601
  (headless or headless2)
4486
4602
  and IS_WINDOWS
4487
4603
  and major_chrome_version
4488
4604
  and int(major_chrome_version) >= 117
4489
- and not is_using_uc(undetectable, browser_name)
4605
+ and not use_uc
4490
4606
  and not (remote_debug or devtools or use_wire)
4491
4607
  and not (proxy_string or multi_proxy or proxy_pac_url)
4492
4608
  and (not chromium_arg or "debug" not in chromium_arg)
@@ -4542,7 +4658,7 @@ def get_local_driver(
4542
4658
  use_version = ch_driver_version
4543
4659
  disable_build_check = True
4544
4660
  uc_driver_version = None
4545
- if is_using_uc(undetectable, browser_name):
4661
+ if use_uc:
4546
4662
  if use_br_version_for_uc or driver_version == "mlatest":
4547
4663
  uc_driver_version = get_uc_driver_version(full=True)
4548
4664
  full_ch_driver_version = uc_driver_version
@@ -4603,7 +4719,6 @@ def get_local_driver(
4603
4719
  "\nWarning: Could not make chromedriver"
4604
4720
  " executable: %s" % e
4605
4721
  )
4606
- use_uc = is_using_uc(undetectable, browser_name)
4607
4722
  make_uc_driver_from_chromedriver = False
4608
4723
  local_ch_exists = (
4609
4724
  LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER)
@@ -4820,7 +4935,7 @@ def get_local_driver(
4820
4935
  service_args = []
4821
4936
  if disable_build_check:
4822
4937
  service_args = ["--disable-build-check"]
4823
- if is_using_uc(undetectable, browser_name):
4938
+ if use_uc:
4824
4939
  uc_lock = fasteners.InterProcessLock(
4825
4940
  constants.MultiBrowser.DRIVER_FIXING_LOCK
4826
4941
  )
@@ -4849,20 +4964,14 @@ def get_local_driver(
4849
4964
  "\nWarning: Could not make uc_driver"
4850
4965
  " executable: %s" % e
4851
4966
  )
4852
- if (
4853
- not headless
4854
- or not IS_LINUX
4855
- or is_using_uc(undetectable, browser_name)
4856
- ):
4967
+ if not headless or not IS_LINUX or use_uc:
4857
4968
  uc_activated = False
4858
4969
  try:
4859
- if (
4860
- os.path.exists(LOCAL_CHROMEDRIVER)
4861
- or is_using_uc(undetectable, browser_name)
4862
- ):
4970
+ if os.path.exists(LOCAL_CHROMEDRIVER) or use_uc:
4863
4971
  if headless and not IS_LINUX:
4864
4972
  undetectable = False # No support for headless
4865
- if is_using_uc(undetectable, browser_name):
4973
+ use_uc = is_using_uc(undetectable, browser_name)
4974
+ if use_uc:
4866
4975
  from seleniumbase import undetected
4867
4976
  from urllib.error import URLError
4868
4977
  if IS_LINUX:
@@ -5162,7 +5271,7 @@ def get_local_driver(
5162
5271
  driver = webdriver.Chrome(
5163
5272
  service=service, options=chrome_options
5164
5273
  )
5165
- return extend_driver(driver)
5274
+ return extend_driver(driver, proxy_auth, use_uc)
5166
5275
  if not auto_upgrade_chromedriver:
5167
5276
  raise # Not an obvious fix.
5168
5277
  else:
@@ -5373,6 +5482,19 @@ def get_local_driver(
5373
5482
  )
5374
5483
  driver._is_hidden = (headless or headless2)
5375
5484
  driver._is_using_uc = True
5485
+ with suppress(Exception):
5486
+ if int(uc_driver_version) >= 133:
5487
+ for window_handle in driver.window_handles:
5488
+ driver.switch_to.window(window_handle)
5489
+ if driver.current_url.startswith(
5490
+ "chrome-extension://"
5491
+ ):
5492
+ driver.close()
5493
+ time.sleep(0.003)
5494
+ driver.switch_to.window(driver.window_handles[0])
5495
+ time.sleep(0.003)
5496
+ driver.connect()
5497
+ time.sleep(0.003)
5376
5498
  if mobile_emulator:
5377
5499
  uc_metrics = {}
5378
5500
  if (
@@ -5400,11 +5522,11 @@ def get_local_driver(
5400
5522
  'Emulation.setDeviceMetricsOverride',
5401
5523
  set_device_metrics_override
5402
5524
  )
5403
- return extend_driver(driver)
5525
+ return extend_driver(driver, proxy_auth, use_uc)
5404
5526
  else: # Running headless on Linux (and not using --uc)
5405
5527
  try:
5406
5528
  driver = webdriver.Chrome(options=chrome_options)
5407
- return extend_driver(driver)
5529
+ return extend_driver(driver, proxy_auth, use_uc)
5408
5530
  except Exception as e:
5409
5531
  if not hasattr(e, "msg"):
5410
5532
  raise
@@ -5426,7 +5548,7 @@ def get_local_driver(
5426
5548
  driver = webdriver.Chrome(
5427
5549
  service=service, options=chrome_options
5428
5550
  )
5429
- return extend_driver(driver)
5551
+ return extend_driver(driver, proxy_auth, use_uc)
5430
5552
  mcv = None # Major Chrome Version
5431
5553
  if "Current browser version is " in e.msg:
5432
5554
  line = e.msg.split("Current browser version is ")[1]
@@ -5469,7 +5591,7 @@ def get_local_driver(
5469
5591
  service=service,
5470
5592
  options=chrome_options,
5471
5593
  )
5472
- return extend_driver(driver)
5594
+ return extend_driver(driver, proxy_auth, use_uc)
5473
5595
  # Use the virtual display on Linux during headless errors
5474
5596
  logging.debug(
5475
5597
  "\nWarning: Chrome failed to launch in"
@@ -5487,9 +5609,9 @@ def get_local_driver(
5487
5609
  driver = webdriver.Chrome(
5488
5610
  service=service, options=chrome_options
5489
5611
  )
5490
- return extend_driver(driver)
5612
+ return extend_driver(driver, proxy_auth, use_uc)
5491
5613
  except Exception as original_exception:
5492
- if is_using_uc(undetectable, browser_name):
5614
+ if use_uc:
5493
5615
  raise
5494
5616
  # Try again if Chrome didn't launch
5495
5617
  with suppress(Exception):
@@ -5497,7 +5619,7 @@ def get_local_driver(
5497
5619
  driver = webdriver.Chrome(
5498
5620
  service=service, options=chrome_options
5499
5621
  )
5500
- return extend_driver(driver)
5622
+ return extend_driver(driver, proxy_auth, use_uc)
5501
5623
  if user_data_dir:
5502
5624
  print("\nUnable to set user_data_dir while starting Chrome!\n")
5503
5625
  raise
@@ -5524,7 +5646,7 @@ def get_local_driver(
5524
5646
  )
5525
5647
  try:
5526
5648
  driver = webdriver.Chrome(service=service)
5527
- return extend_driver(driver)
5649
+ return extend_driver(driver, proxy_auth, use_uc)
5528
5650
  except Exception:
5529
5651
  raise original_exception
5530
5652
  else:
@@ -96,14 +96,9 @@ def linux_browser_apps_to_cmd(*apps):
96
96
  )
97
97
 
98
98
 
99
- def chrome_on_linux_path(prefer_chromium=False):
99
+ def chrome_on_linux_path(chromium_ok=False):
100
100
  if os_name() != OSType.LINUX:
101
101
  return ""
102
- if prefer_chromium:
103
- paths = ["/bin/chromium", "/bin/chromium-browser"]
104
- for path in paths:
105
- if os.path.exists(path) and os.access(path, os.X_OK):
106
- return path
107
102
  paths = ["/bin/google-chrome", "/bin/google-chrome-stable"]
108
103
  for path in paths:
109
104
  if os.path.exists(path) and os.access(path, os.X_OK):
@@ -112,17 +107,22 @@ def chrome_on_linux_path(prefer_chromium=False):
112
107
  binaries = []
113
108
  binaries.append("google-chrome")
114
109
  binaries.append("google-chrome-stable")
115
- binaries.append("chrome")
116
- binaries.append("chromium")
117
- binaries.append("chromium-browser")
118
110
  binaries.append("google-chrome-beta")
119
111
  binaries.append("google-chrome-dev")
120
112
  binaries.append("google-chrome-unstable")
113
+ binaries.append("chrome")
114
+ binaries.append("chromium")
115
+ binaries.append("chromium-browser")
121
116
  for binary in binaries:
122
117
  for path in paths:
123
118
  full_path = os.path.join(path, binary)
124
119
  if os.path.exists(full_path) and os.access(full_path, os.X_OK):
125
120
  return full_path
121
+ if chromium_ok:
122
+ paths = ["/bin/chromium", "/bin/chromium-browser"]
123
+ for path in paths:
124
+ if os.path.exists(path) and os.access(path, os.X_OK):
125
+ return path
126
126
  return "/usr/bin/google-chrome"
127
127
 
128
128
 
@@ -209,12 +209,11 @@ def windows_browser_apps_to_cmd(*apps):
209
209
  return '%s -NoProfile "%s"' % (powershell, script)
210
210
 
211
211
 
212
- def get_binary_location(browser_type, prefer_chromium=False):
213
- """Return the full path of the browser binary.
214
- If going for better results in UC Mode, use: prefer_chromium=True"""
212
+ def get_binary_location(browser_type, chromium_ok=False):
213
+ """Return the full path of the browser binary."""
215
214
  cmd_mapping = {
216
215
  ChromeType.GOOGLE: {
217
- OSType.LINUX: chrome_on_linux_path(prefer_chromium),
216
+ OSType.LINUX: chrome_on_linux_path(chromium_ok),
218
217
  OSType.MAC: r"/Applications/Google Chrome.app"
219
218
  r"/Contents/MacOS/Google Chrome",
220
219
  OSType.WIN: chrome_on_windows_path(),
@@ -94,21 +94,23 @@ def create_proxy_ext(
94
94
  manifest_json = (
95
95
  """{\n"""
96
96
  """"version": "1.0.0",\n"""
97
- """"manifest_version": 2,\n"""
97
+ """"manifest_version": 3,\n"""
98
98
  """"name": "Chrome Proxy",\n"""
99
99
  """"permissions": [\n"""
100
100
  """ "proxy",\n"""
101
101
  """ "tabs",\n"""
102
102
  """ "unlimitedStorage",\n"""
103
103
  """ "storage",\n"""
104
- """ "<all_urls>",\n"""
105
104
  """ "webRequest",\n"""
106
- """ "webRequestBlocking"\n"""
105
+ """ "webRequestAuthProvider"\n"""
106
+ """],\n"""
107
+ """"host_permissions": [\n"""
108
+ """ "<all_urls>"\n"""
107
109
  """],\n"""
108
110
  """"background": {\n"""
109
- """ "scripts": ["background.js"]\n"""
111
+ """ "service_worker": "background.js"\n"""
110
112
  """},\n"""
111
- """"minimum_chrome_version":"22.0.0"\n"""
113
+ """"minimum_chrome_version":"88.0.0"\n"""
112
114
  """}"""
113
115
  )
114
116
  abs_path = os.path.abspath(".")