seleniumbase 4.44.2__py3-none-any.whl → 4.45.10__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.
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +14 -0
- seleniumbase/console_scripts/run.py +1 -0
- seleniumbase/console_scripts/sb_install.py +142 -11
- seleniumbase/console_scripts/sb_mkdir.py +76 -0
- seleniumbase/console_scripts/sb_mkrec.py +25 -0
- seleniumbase/console_scripts/sb_recorder.py +40 -3
- seleniumbase/core/browser_launcher.py +279 -117
- seleniumbase/core/detect_b_ver.py +8 -6
- seleniumbase/core/log_helper.py +11 -16
- seleniumbase/core/mysql.py +1 -1
- seleniumbase/core/report_helper.py +3 -7
- seleniumbase/core/sb_cdp.py +275 -78
- seleniumbase/core/sb_driver.py +36 -5
- seleniumbase/core/session_helper.py +2 -4
- seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- seleniumbase/fixtures/base_case.py +251 -201
- seleniumbase/fixtures/constants.py +1 -0
- seleniumbase/fixtures/js_utils.py +52 -14
- seleniumbase/fixtures/page_actions.py +18 -7
- seleniumbase/fixtures/page_utils.py +4 -2
- seleniumbase/fixtures/shared_utils.py +2 -4
- seleniumbase/masterqa/master_qa.py +16 -2
- seleniumbase/plugins/base_plugin.py +8 -0
- seleniumbase/plugins/driver_manager.py +15 -5
- seleniumbase/plugins/pytest_plugin.py +43 -57
- seleniumbase/plugins/sb_manager.py +23 -19
- seleniumbase/plugins/selenium_plugin.py +20 -13
- seleniumbase/undetected/__init__.py +11 -10
- seleniumbase/undetected/cdp.py +1 -12
- seleniumbase/undetected/cdp_driver/browser.py +330 -128
- seleniumbase/undetected/cdp_driver/cdp_util.py +48 -14
- seleniumbase/undetected/cdp_driver/config.py +78 -11
- seleniumbase/undetected/cdp_driver/connection.py +15 -43
- seleniumbase/undetected/cdp_driver/element.py +37 -22
- seleniumbase/undetected/cdp_driver/tab.py +414 -39
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/METADATA +140 -152
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/RECORD +42 -41
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/licenses/LICENSE +1 -1
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/WHEEL +0 -0
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/top_level.txt +0 -0
|
@@ -32,6 +32,7 @@ from seleniumbase.drivers import opera_drivers # still uses chromedriver
|
|
|
32
32
|
from seleniumbase.drivers import brave_drivers # still uses chromedriver
|
|
33
33
|
from seleniumbase.drivers import comet_drivers # still uses chromedriver
|
|
34
34
|
from seleniumbase.drivers import atlas_drivers # still uses chromedriver
|
|
35
|
+
from seleniumbase.drivers import chromium_drivers # still uses chromedriver
|
|
35
36
|
from seleniumbase import extensions # browser extensions storage folder
|
|
36
37
|
from seleniumbase.config import settings
|
|
37
38
|
from seleniumbase.core import detect_b_ver
|
|
@@ -52,6 +53,9 @@ DRIVER_DIR_OPERA = os.path.dirname(os.path.realpath(opera_drivers.__file__))
|
|
|
52
53
|
DRIVER_DIR_BRAVE = os.path.dirname(os.path.realpath(brave_drivers.__file__))
|
|
53
54
|
DRIVER_DIR_COMET = os.path.dirname(os.path.realpath(comet_drivers.__file__))
|
|
54
55
|
DRIVER_DIR_ATLAS = os.path.dirname(os.path.realpath(atlas_drivers.__file__))
|
|
56
|
+
DRIVER_DIR_CHROMIUM = os.path.dirname(
|
|
57
|
+
os.path.realpath(chromium_drivers.__file__)
|
|
58
|
+
)
|
|
55
59
|
# Make sure that the SeleniumBase DRIVER_DIR is at the top of the System PATH
|
|
56
60
|
# (Changes to the System PATH with os.environ only last during the test run)
|
|
57
61
|
if not os.environ["PATH"].startswith(DRIVER_DIR):
|
|
@@ -104,10 +108,7 @@ else:
|
|
|
104
108
|
def log_d(message):
|
|
105
109
|
"""If setting sb_config.settings.HIDE_DRIVER_DOWNLOADS to True,
|
|
106
110
|
output from driver downloads are logged instead of printed."""
|
|
107
|
-
if (
|
|
108
|
-
hasattr(settings, "HIDE_DRIVER_DOWNLOADS")
|
|
109
|
-
and settings.HIDE_DRIVER_DOWNLOADS
|
|
110
|
-
):
|
|
111
|
+
if getattr(settings, "HIDE_DRIVER_DOWNLOADS", None):
|
|
111
112
|
logging.debug(message)
|
|
112
113
|
else:
|
|
113
114
|
print(message)
|
|
@@ -159,9 +160,21 @@ def extend_driver(
|
|
|
159
160
|
# Extend the driver with new methods
|
|
160
161
|
driver.default_find_element = driver.find_element
|
|
161
162
|
driver.default_find_elements = driver.find_elements
|
|
163
|
+
driver.default_add_cookie = driver.add_cookie
|
|
164
|
+
driver.default_get_cookie = driver.get_cookie
|
|
165
|
+
driver.default_delete_cookie = driver.delete_cookie
|
|
166
|
+
driver.default_back = driver.back
|
|
167
|
+
driver.default_forward = driver.forward
|
|
168
|
+
driver.default_refresh = driver.refresh
|
|
162
169
|
DM = sb_driver.DriverMethods(driver)
|
|
163
170
|
driver.find_element = DM.find_element
|
|
164
171
|
driver.find_elements = DM.find_elements
|
|
172
|
+
driver.add_cookie = DM.add_cookie
|
|
173
|
+
driver.get_cookie = DM.get_cookie
|
|
174
|
+
driver.delete_cookie = DM.delete_cookie
|
|
175
|
+
driver.back = DM.back
|
|
176
|
+
driver.forward = DM.forward
|
|
177
|
+
driver.refresh = DM.refresh
|
|
165
178
|
driver.locator = DM.locator
|
|
166
179
|
page = types.SimpleNamespace()
|
|
167
180
|
page.open = DM.open_url
|
|
@@ -293,7 +306,19 @@ def extend_driver(
|
|
|
293
306
|
)
|
|
294
307
|
if hasattr(driver, "proxy"):
|
|
295
308
|
driver.set_wire_proxy = DM.set_wire_proxy
|
|
309
|
+
completed_loads = []
|
|
310
|
+
for ext_dir in sb_config._ext_dirs:
|
|
311
|
+
if ext_dir not in completed_loads:
|
|
312
|
+
completed_loads.append(ext_dir)
|
|
313
|
+
if not use_uc and os.path.exists(os.path.realpath(ext_dir)):
|
|
314
|
+
with suppress(Exception):
|
|
315
|
+
driver.webextension.install(os.path.realpath(ext_dir))
|
|
316
|
+
driver._is_using_auth = False
|
|
296
317
|
if proxy_auth:
|
|
318
|
+
driver._is_using_auth = True
|
|
319
|
+
if not use_uc and os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
|
320
|
+
with suppress(Exception):
|
|
321
|
+
driver.webextension.install(proxy_helper.PROXY_DIR_PATH)
|
|
297
322
|
# Proxy needs a moment to load in Manifest V3
|
|
298
323
|
if use_uc:
|
|
299
324
|
time.sleep(0.14)
|
|
@@ -419,16 +444,16 @@ def has_captcha(text):
|
|
|
419
444
|
"<title>403 Forbidden</title>" in text
|
|
420
445
|
or "Permission Denied</title>" in text
|
|
421
446
|
or 'id="challenge-error-text"' in text
|
|
447
|
+
or "/challenge-platform/h/b/" in text
|
|
422
448
|
or "<title>Just a moment..." in text
|
|
423
449
|
or 'action="/?__cf_chl_f_tk' in text
|
|
424
450
|
or 'id="challenge-widget-' in text
|
|
425
451
|
or 'src="chromedriver.js"' in text
|
|
452
|
+
or "com/recaptcha/api.js" in text
|
|
426
453
|
or 'class="g-recaptcha"' in text
|
|
427
454
|
or 'content="Pixelscan"' in text
|
|
428
455
|
or 'id="challenge-form"' in text
|
|
429
|
-
or "/challenge-platform" in text
|
|
430
456
|
or "window._cf_chl_opt" in text
|
|
431
|
-
or "/recaptcha/api.js" in text
|
|
432
457
|
or "/turnstile/" in text
|
|
433
458
|
):
|
|
434
459
|
return True
|
|
@@ -446,6 +471,12 @@ def uc_execute_cdp_cmd(driver, *args, **kwargs):
|
|
|
446
471
|
return driver.default_execute_cdp_cmd(*args, **kwargs)
|
|
447
472
|
|
|
448
473
|
|
|
474
|
+
def updated_get(driver, url):
|
|
475
|
+
if url and ":" not in url and "." in url:
|
|
476
|
+
url = "https:" + url
|
|
477
|
+
driver.default_get(url)
|
|
478
|
+
|
|
479
|
+
|
|
449
480
|
def uc_special_open_if_cf(
|
|
450
481
|
driver,
|
|
451
482
|
url,
|
|
@@ -455,6 +486,8 @@ def uc_special_open_if_cf(
|
|
|
455
486
|
device_height=None,
|
|
456
487
|
device_pixel_ratio=None,
|
|
457
488
|
):
|
|
489
|
+
if url and ":" not in url and "." in url:
|
|
490
|
+
url = "https:" + url
|
|
458
491
|
if url.startswith("http:") or url.startswith("https:"):
|
|
459
492
|
special = False
|
|
460
493
|
with suppress(Exception):
|
|
@@ -624,10 +657,8 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
624
657
|
safe_url = False
|
|
625
658
|
|
|
626
659
|
if (
|
|
627
|
-
|
|
628
|
-
and driver
|
|
629
|
-
and hasattr(driver, "cdp")
|
|
630
|
-
and driver.cdp
|
|
660
|
+
getattr(driver, "_is_using_cdp", None)
|
|
661
|
+
and getattr(driver, "cdp", None)
|
|
631
662
|
and hasattr(driver.cdp, "loop")
|
|
632
663
|
):
|
|
633
664
|
# CDP Mode was already initialized
|
|
@@ -667,6 +698,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
667
698
|
xvfb=xvfb,
|
|
668
699
|
xvfb_metrics=xvfb_metrics,
|
|
669
700
|
browser_executable_path=binary_location,
|
|
701
|
+
mobile=getattr(sb_config, "_cdp_mobile_mode", None),
|
|
670
702
|
)
|
|
671
703
|
)
|
|
672
704
|
loop.run_until_complete(driver.cdp_base.wait(0))
|
|
@@ -730,6 +762,11 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
730
762
|
cdp.refresh = CDPM.refresh
|
|
731
763
|
cdp.add_handler = CDPM.add_handler
|
|
732
764
|
cdp.get_event_loop = CDPM.get_event_loop
|
|
765
|
+
cdp.get_rd_host = CDPM.get_rd_host
|
|
766
|
+
cdp.get_rd_port = CDPM.get_rd_port
|
|
767
|
+
cdp.get_rd_url = CDPM.get_rd_url
|
|
768
|
+
cdp.get_endpoint_url = CDPM.get_endpoint_url
|
|
769
|
+
cdp.get_port = CDPM.get_port
|
|
733
770
|
cdp.find_element = CDPM.find_element
|
|
734
771
|
cdp.find = CDPM.find_element
|
|
735
772
|
cdp.locator = CDPM.find_element
|
|
@@ -795,6 +832,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
795
832
|
cdp.is_attribute_present = CDPM.is_attribute_present
|
|
796
833
|
cdp.is_online = CDPM.is_online
|
|
797
834
|
cdp.solve_captcha = CDPM.solve_captcha
|
|
835
|
+
cdp.click_captcha = CDPM.click_captcha
|
|
798
836
|
cdp.gui_press_key = CDPM.gui_press_key
|
|
799
837
|
cdp.gui_press_keys = CDPM.gui_press_keys
|
|
800
838
|
cdp.gui_write = CDPM.gui_write
|
|
@@ -808,6 +846,8 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
808
846
|
cdp.gui_hover_x_y = CDPM.gui_hover_x_y
|
|
809
847
|
cdp.gui_hover_element = CDPM.gui_hover_element
|
|
810
848
|
cdp.gui_hover_and_click = CDPM.gui_hover_and_click
|
|
849
|
+
cdp.hover_element = CDPM.hover_element
|
|
850
|
+
cdp.hover_and_click = CDPM.hover_and_click
|
|
811
851
|
cdp.internalize_links = CDPM.internalize_links
|
|
812
852
|
cdp.open_new_window = CDPM.open_new_window
|
|
813
853
|
cdp.switch_to_window = CDPM.switch_to_window
|
|
@@ -828,6 +868,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
828
868
|
cdp.get_element_position = CDPM.get_element_position
|
|
829
869
|
cdp.get_gui_element_rect = CDPM.get_gui_element_rect
|
|
830
870
|
cdp.get_gui_element_center = CDPM.get_gui_element_center
|
|
871
|
+
cdp.get_html = CDPM.get_html
|
|
831
872
|
cdp.get_page_source = CDPM.get_page_source
|
|
832
873
|
cdp.get_user_agent = CDPM.get_user_agent
|
|
833
874
|
cdp.get_cookie_string = CDPM.get_cookie_string
|
|
@@ -924,7 +965,17 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
924
965
|
cdp.core = core_items
|
|
925
966
|
cdp.loop = cdp.get_event_loop()
|
|
926
967
|
driver.cdp = cdp
|
|
968
|
+
driver.solve_captcha = CDPM.solve_captcha
|
|
969
|
+
driver.click_captcha = CDPM.click_captcha
|
|
970
|
+
driver.find_element_by_text = CDPM.find_element_by_text
|
|
927
971
|
driver._is_using_cdp = True
|
|
972
|
+
if (
|
|
973
|
+
getattr(sb_config, "_cdp_proxy", None)
|
|
974
|
+
and "@" in sb_config._cdp_proxy
|
|
975
|
+
):
|
|
976
|
+
time.sleep(0.077)
|
|
977
|
+
loop.run_until_complete(page.wait(0.25))
|
|
978
|
+
time.sleep(0.022)
|
|
928
979
|
|
|
929
980
|
|
|
930
981
|
def uc_activate_cdp_mode(driver, url=None, **kwargs):
|
|
@@ -999,7 +1050,7 @@ def uc_click(
|
|
|
999
1050
|
def verify_pyautogui_has_a_headed_browser(driver):
|
|
1000
1051
|
"""PyAutoGUI requires a headed browser so that it can
|
|
1001
1052
|
focus on the correct element when performing actions."""
|
|
1002
|
-
if
|
|
1053
|
+
if getattr(driver, "_is_hidden", None):
|
|
1003
1054
|
raise Exception(
|
|
1004
1055
|
"PyAutoGUI can't be used in headless mode!"
|
|
1005
1056
|
)
|
|
@@ -1035,11 +1086,9 @@ def __install_pyautogui_if_missing():
|
|
|
1035
1086
|
xvfb_width = 1366
|
|
1036
1087
|
xvfb_height = 768
|
|
1037
1088
|
if (
|
|
1038
|
-
|
|
1039
|
-
and sb_config._xvfb_width
|
|
1089
|
+
getattr(sb_config, "_xvfb_width", None)
|
|
1040
1090
|
and isinstance(sb_config._xvfb_width, int)
|
|
1041
|
-
and
|
|
1042
|
-
and sb_config._xvfb_height
|
|
1091
|
+
and getattr(sb_config, "_xvfb_height", None)
|
|
1043
1092
|
and isinstance(sb_config._xvfb_height, int)
|
|
1044
1093
|
):
|
|
1045
1094
|
xvfb_width = sb_config._xvfb_width
|
|
@@ -1066,8 +1115,7 @@ def __install_pyautogui_if_missing():
|
|
|
1066
1115
|
sb_config._virtual_display = _xvfb_display
|
|
1067
1116
|
sb_config.headless_active = True
|
|
1068
1117
|
if (
|
|
1069
|
-
|
|
1070
|
-
and sb_config.reuse_session
|
|
1118
|
+
getattr(sb_config, "reuse_session", None)
|
|
1071
1119
|
and hasattr(sb_config, "_vd_list")
|
|
1072
1120
|
and isinstance(sb_config._vd_list, list)
|
|
1073
1121
|
):
|
|
@@ -1099,8 +1147,7 @@ def get_configured_pyautogui(pyautogui_copy):
|
|
|
1099
1147
|
and "DISPLAY" in os.environ.keys()
|
|
1100
1148
|
):
|
|
1101
1149
|
if (
|
|
1102
|
-
|
|
1103
|
-
and sb_config._pyautogui_x11_display
|
|
1150
|
+
getattr(sb_config, "_pyautogui_x11_display", None)
|
|
1104
1151
|
and hasattr(pyautogui_copy._pyautogui_x11, "_display")
|
|
1105
1152
|
and (
|
|
1106
1153
|
sb_config._pyautogui_x11_display
|
|
@@ -1205,10 +1252,7 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
|
|
|
1205
1252
|
connected = driver.is_connected()
|
|
1206
1253
|
if (
|
|
1207
1254
|
not connected
|
|
1208
|
-
and (
|
|
1209
|
-
not hasattr(sb_config, "_saved_width_ratio")
|
|
1210
|
-
or not sb_config._saved_width_ratio
|
|
1211
|
-
)
|
|
1255
|
+
and not getattr(sb_config, "_saved_width_ratio", None)
|
|
1212
1256
|
and not __is_cdp_swap_needed(driver)
|
|
1213
1257
|
):
|
|
1214
1258
|
driver.reconnect(0.1)
|
|
@@ -1257,8 +1301,12 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
|
|
|
1257
1301
|
def _on_a_cf_turnstile_page(driver):
|
|
1258
1302
|
source = driver.get_page_source()
|
|
1259
1303
|
if (
|
|
1260
|
-
|
|
1261
|
-
|
|
1304
|
+
(
|
|
1305
|
+
'data-callback="onCaptchaSuccess"' in source
|
|
1306
|
+
and 'title="reCAPTCHA"' not in source
|
|
1307
|
+
and 'id="recaptcha-token"' not in source
|
|
1308
|
+
)
|
|
1309
|
+
or "/challenge-platform/h/b/" in source
|
|
1262
1310
|
or 'id="challenge-widget-' in source
|
|
1263
1311
|
or "challenges.cloudf" in source
|
|
1264
1312
|
or "cf-turnstile-" in source
|
|
@@ -1387,14 +1435,10 @@ def _uc_gui_click_captcha(
|
|
|
1387
1435
|
and driver.is_element_present("%s div" % frame)
|
|
1388
1436
|
):
|
|
1389
1437
|
frame = "%s div" % frame
|
|
1390
|
-
elif (
|
|
1391
|
-
driver.is_element_present('[name*="cf-turnstile-"]')
|
|
1392
|
-
and driver.is_element_present("#challenge-form div > div")
|
|
1393
|
-
):
|
|
1438
|
+
elif driver.is_element_present("#challenge-form div > div"):
|
|
1394
1439
|
frame = "#challenge-form div > div"
|
|
1395
1440
|
elif (
|
|
1396
|
-
driver.is_element_present(
|
|
1397
|
-
and driver.is_element_present(
|
|
1441
|
+
driver.is_element_present(
|
|
1398
1442
|
'[style="display: grid;"] div div'
|
|
1399
1443
|
)
|
|
1400
1444
|
):
|
|
@@ -1407,13 +1451,11 @@ def _uc_gui_click_captcha(
|
|
|
1407
1451
|
):
|
|
1408
1452
|
frame = '.spacer + div div:not([class])'
|
|
1409
1453
|
elif (
|
|
1410
|
-
driver.is_element_present(
|
|
1411
|
-
and driver.is_element_present(".spacer div:not([class])")
|
|
1454
|
+
driver.is_element_present(".spacer div:not([class])")
|
|
1412
1455
|
):
|
|
1413
1456
|
frame = ".spacer div:not([class])"
|
|
1414
1457
|
elif (
|
|
1415
|
-
driver.is_element_present(
|
|
1416
|
-
and driver.is_element_present(
|
|
1458
|
+
driver.is_element_present(
|
|
1417
1459
|
'[data-testid*="challenge-"] div'
|
|
1418
1460
|
)
|
|
1419
1461
|
):
|
|
@@ -1458,6 +1500,10 @@ def _uc_gui_click_captcha(
|
|
|
1458
1500
|
'[data-callback="onCaptchaSuccess"]'
|
|
1459
1501
|
):
|
|
1460
1502
|
frame = '[data-callback="onCaptchaSuccess"]'
|
|
1503
|
+
elif driver.is_element_present(
|
|
1504
|
+
"div:not([class]) > div:not([class])"
|
|
1505
|
+
):
|
|
1506
|
+
frame = "div:not([class]) > div:not([class])"
|
|
1461
1507
|
else:
|
|
1462
1508
|
return
|
|
1463
1509
|
if (
|
|
@@ -1801,6 +1847,10 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
|
1801
1847
|
frame = ".cf-turnstile-wrapper"
|
|
1802
1848
|
elif driver.is_element_present('[class="cf-turnstile"]'):
|
|
1803
1849
|
frame = '[class="cf-turnstile"]'
|
|
1850
|
+
elif driver.is_element_present(
|
|
1851
|
+
"div:not([class]) > div:not([class])"
|
|
1852
|
+
):
|
|
1853
|
+
frame = "div:not([class]) > div:not([class])"
|
|
1804
1854
|
else:
|
|
1805
1855
|
return
|
|
1806
1856
|
else:
|
|
@@ -1860,8 +1910,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
|
1860
1910
|
driver.is_element_present(".footer .clearfix .ray-id")
|
|
1861
1911
|
or driver.is_element_present("script[data-cf-beacon]")
|
|
1862
1912
|
)
|
|
1863
|
-
and
|
|
1864
|
-
and sb_config._saved_cf_tab_count
|
|
1913
|
+
and getattr(sb_config, "_saved_cf_tab_count", None)
|
|
1865
1914
|
and not __is_cdp_swap_needed(driver)
|
|
1866
1915
|
):
|
|
1867
1916
|
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
|
@@ -2087,6 +2136,7 @@ def _add_chrome_proxy_extension(
|
|
|
2087
2136
|
"""Implementation of https://stackoverflow.com/a/35293284/7058266
|
|
2088
2137
|
for https://stackoverflow.com/q/12848327/7058266
|
|
2089
2138
|
(Run Selenium on a proxy server that requires authentication.)"""
|
|
2139
|
+
zip_it = False
|
|
2090
2140
|
args = " ".join(sys.argv)
|
|
2091
2141
|
bypass_list = proxy_bypass_list
|
|
2092
2142
|
if (
|
|
@@ -2466,14 +2516,28 @@ def _set_chrome_options(
|
|
|
2466
2516
|
# Can be a comma-separated list of .ZIP or .CRX files
|
|
2467
2517
|
extension_zip_list = extension_zip.split(",")
|
|
2468
2518
|
for extension_zip_item in extension_zip_list:
|
|
2469
|
-
abs_path = os.path.
|
|
2470
|
-
|
|
2519
|
+
abs_path = os.path.realpath(extension_zip_item)
|
|
2520
|
+
if os.path.exists(abs_path):
|
|
2521
|
+
try:
|
|
2522
|
+
abs_path_dir = os.path.join(
|
|
2523
|
+
DOWNLOADS_FOLDER, abs_path.split(".")[0]
|
|
2524
|
+
)
|
|
2525
|
+
_unzip_to_new_folder(abs_path, abs_path_dir)
|
|
2526
|
+
chrome_options = add_chrome_ext_dir(
|
|
2527
|
+
chrome_options, abs_path_dir
|
|
2528
|
+
)
|
|
2529
|
+
sb_config._ext_dirs.append(abs_path_dir)
|
|
2530
|
+
except Exception:
|
|
2531
|
+
with suppress(Exception):
|
|
2532
|
+
chrome_options.add_extension(abs_path)
|
|
2471
2533
|
if extension_dir:
|
|
2472
2534
|
# load-extension input can be a comma-separated list
|
|
2473
2535
|
abs_path = (
|
|
2474
|
-
",".join(os.path.
|
|
2536
|
+
",".join(os.path.realpath(p) for p in extension_dir.split(","))
|
|
2475
2537
|
)
|
|
2476
2538
|
chrome_options = add_chrome_ext_dir(chrome_options, abs_path)
|
|
2539
|
+
for p in extension_dir.split(","):
|
|
2540
|
+
sb_config._ext_dirs.append(os.path.realpath(p))
|
|
2477
2541
|
if (
|
|
2478
2542
|
page_load_strategy
|
|
2479
2543
|
and page_load_strategy.lower() in ["eager", "none"]
|
|
@@ -2482,8 +2546,7 @@ def _set_chrome_options(
|
|
|
2482
2546
|
chrome_options.page_load_strategy = page_load_strategy.lower()
|
|
2483
2547
|
elif (
|
|
2484
2548
|
not page_load_strategy
|
|
2485
|
-
and
|
|
2486
|
-
and settings.PAGE_LOAD_STRATEGY
|
|
2549
|
+
and getattr(settings, "PAGE_LOAD_STRATEGY", None)
|
|
2487
2550
|
and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"]
|
|
2488
2551
|
):
|
|
2489
2552
|
# Only change it if not "normal", which is the default.
|
|
@@ -2508,37 +2571,32 @@ def _set_chrome_options(
|
|
|
2508
2571
|
if (settings.DISABLE_CSP_ON_CHROME or disable_csp) and not headless:
|
|
2509
2572
|
# Headless Chrome does not support extensions, which are required
|
|
2510
2573
|
# for disabling the Content Security Policy on Chrome.
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
chrome_options
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
else:
|
|
2519
|
-
chrome_options = _add_chrome_disable_csp_extension(chrome_options)
|
|
2574
|
+
disable_csp_zip = DISABLE_CSP_ZIP_PATH
|
|
2575
|
+
disable_csp_dir = os.path.join(DOWNLOADS_FOLDER, "disable_csp")
|
|
2576
|
+
_unzip_to_new_folder(disable_csp_zip, disable_csp_dir)
|
|
2577
|
+
chrome_options = add_chrome_ext_dir(
|
|
2578
|
+
chrome_options, disable_csp_dir
|
|
2579
|
+
)
|
|
2580
|
+
sb_config._ext_dirs.append(disable_csp_dir)
|
|
2520
2581
|
if ad_block_on and not headless:
|
|
2521
2582
|
# Headless Chrome does not support extensions.
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
else:
|
|
2528
|
-
chrome_options = _add_chrome_ad_block_extension(chrome_options)
|
|
2583
|
+
ad_block_zip = AD_BLOCK_ZIP_PATH
|
|
2584
|
+
ad_block_dir = os.path.join(DOWNLOADS_FOLDER, "ad_block")
|
|
2585
|
+
_unzip_to_new_folder(ad_block_zip, ad_block_dir)
|
|
2586
|
+
chrome_options = add_chrome_ext_dir(chrome_options, ad_block_dir)
|
|
2587
|
+
sb_config._ext_dirs.append(ad_block_dir)
|
|
2529
2588
|
if recorder_ext and not headless:
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
else:
|
|
2536
|
-
chrome_options = _add_chrome_recorder_extension(chrome_options)
|
|
2589
|
+
recorder_zip = RECORDER_ZIP_PATH
|
|
2590
|
+
recorder_dir = os.path.join(DOWNLOADS_FOLDER, "recorder")
|
|
2591
|
+
_unzip_to_new_folder(recorder_zip, recorder_dir)
|
|
2592
|
+
chrome_options = add_chrome_ext_dir(chrome_options, recorder_dir)
|
|
2593
|
+
sb_config._ext_dirs.append(recorder_dir)
|
|
2537
2594
|
if chromium_arg and "sbase" in chromium_arg:
|
|
2538
2595
|
sbase_ext_zip = SBASE_EXT_ZIP_PATH
|
|
2539
2596
|
sbase_ext_dir = os.path.join(DOWNLOADS_FOLDER, "sbase_ext")
|
|
2540
2597
|
_unzip_to_new_folder(sbase_ext_zip, sbase_ext_dir)
|
|
2541
2598
|
chrome_options = add_chrome_ext_dir(chrome_options, sbase_ext_dir)
|
|
2599
|
+
sb_config._ext_dirs.append(sbase_ext_dir)
|
|
2542
2600
|
if proxy_string:
|
|
2543
2601
|
if proxy_auth:
|
|
2544
2602
|
zip_it = True
|
|
@@ -2691,6 +2749,7 @@ def _set_chrome_options(
|
|
|
2691
2749
|
chrome_options.add_argument("--disable-renderer-backgrounding")
|
|
2692
2750
|
chrome_options.add_argument("--disable-backgrounding-occluded-windows")
|
|
2693
2751
|
chrome_options.add_argument("--disable-client-side-phishing-detection")
|
|
2752
|
+
chrome_options.add_argument("--disable-device-discovery-notifications")
|
|
2694
2753
|
chrome_options.add_argument("--disable-oopr-debug-crash-dump")
|
|
2695
2754
|
chrome_options.add_argument("--disable-top-sites")
|
|
2696
2755
|
chrome_options.add_argument("--ash-no-nudges")
|
|
@@ -2707,6 +2766,7 @@ def _set_chrome_options(
|
|
|
2707
2766
|
included_disabled_features.append("OptimizationHints")
|
|
2708
2767
|
included_disabled_features.append("OptimizationHintsFetching")
|
|
2709
2768
|
included_disabled_features.append("Translate")
|
|
2769
|
+
included_disabled_features.append("ComponentUpdater")
|
|
2710
2770
|
included_disabled_features.append("OptimizationTargetPrediction")
|
|
2711
2771
|
included_disabled_features.append("OptimizationGuideModelDownloading")
|
|
2712
2772
|
included_disabled_features.append("DownloadBubble")
|
|
@@ -2717,13 +2777,24 @@ def _set_chrome_options(
|
|
|
2717
2777
|
included_disabled_features.append("SidePanelPinning")
|
|
2718
2778
|
included_disabled_features.append("UserAgentClientHint")
|
|
2719
2779
|
included_disabled_features.append("DisableLoadExtensionCommandLineSwitch")
|
|
2780
|
+
included_disabled_features.append("Bluetooth")
|
|
2781
|
+
included_disabled_features.append("WebBluetooth")
|
|
2782
|
+
included_disabled_features.append("UnifiedWebBluetooth")
|
|
2783
|
+
included_disabled_features.append("WebAuthentication")
|
|
2784
|
+
included_disabled_features.append("PasskeyAuth")
|
|
2720
2785
|
for item in extra_disabled_features:
|
|
2721
2786
|
if item not in included_disabled_features:
|
|
2722
2787
|
included_disabled_features.append(item)
|
|
2723
2788
|
d_f_string = ",".join(included_disabled_features)
|
|
2724
2789
|
chrome_options.add_argument("--disable-features=%s" % d_f_string)
|
|
2725
|
-
|
|
2790
|
+
chrome_options.add_argument("--enable-unsafe-extension-debugging")
|
|
2791
|
+
if proxy_string:
|
|
2726
2792
|
chrome_options.add_argument("--test-type")
|
|
2793
|
+
if proxy_auth or sb_config._ext_dirs:
|
|
2794
|
+
if not is_using_uc(undetectable, browser_name):
|
|
2795
|
+
chrome_options.add_argument("--remote-debugging-pipe")
|
|
2796
|
+
chrome_options.enable_webextensions = True
|
|
2797
|
+
chrome_options.enable_bidi = True
|
|
2727
2798
|
if (
|
|
2728
2799
|
is_using_uc(undetectable, browser_name)
|
|
2729
2800
|
and (
|
|
@@ -2741,7 +2812,7 @@ def _set_chrome_options(
|
|
|
2741
2812
|
chrome_options.add_argument("--disable-popup-blocking")
|
|
2742
2813
|
# Skip remaining options that trigger anti-bot services
|
|
2743
2814
|
return chrome_options
|
|
2744
|
-
if not
|
|
2815
|
+
if not proxy_string:
|
|
2745
2816
|
chrome_options.add_argument("--test-type")
|
|
2746
2817
|
chrome_options.add_argument("--log-level=3")
|
|
2747
2818
|
chrome_options.add_argument("--no-first-run")
|
|
@@ -2988,33 +3059,29 @@ def get_driver(
|
|
|
2988
3059
|
device_pixel_ratio=None,
|
|
2989
3060
|
browser=None, # A duplicate of browser_name to avoid confusion
|
|
2990
3061
|
):
|
|
3062
|
+
sb_config._ext_dirs = []
|
|
2991
3063
|
driver_dir = DRIVER_DIR
|
|
2992
|
-
if
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
):
|
|
3064
|
+
if binary_location == "_chromium_":
|
|
3065
|
+
driver_dir = DRIVER_DIR_CHROMIUM
|
|
3066
|
+
elif binary_location == "cft":
|
|
2996
3067
|
driver_dir = DRIVER_DIR_CFT
|
|
2997
|
-
|
|
2998
|
-
hasattr(sb_config, "binary_location")
|
|
2999
|
-
and sb_config.binary_location == "chs"
|
|
3000
|
-
):
|
|
3068
|
+
elif binary_location == "chs":
|
|
3001
3069
|
driver_dir = DRIVER_DIR_CHS
|
|
3002
|
-
|
|
3070
|
+
elif _special_binary_exists(binary_location, "opera"):
|
|
3003
3071
|
driver_dir = DRIVER_DIR_OPERA
|
|
3004
3072
|
sb_config._cdp_browser = "opera"
|
|
3005
|
-
|
|
3073
|
+
elif _special_binary_exists(binary_location, "brave"):
|
|
3006
3074
|
driver_dir = DRIVER_DIR_BRAVE
|
|
3007
3075
|
sb_config._cdp_browser = "brave"
|
|
3008
|
-
|
|
3076
|
+
elif _special_binary_exists(binary_location, "comet"):
|
|
3009
3077
|
driver_dir = DRIVER_DIR_COMET
|
|
3010
3078
|
sb_config._cdp_browser = "comet"
|
|
3011
|
-
|
|
3079
|
+
elif _special_binary_exists(binary_location, "atlas"):
|
|
3012
3080
|
driver_dir = DRIVER_DIR_ATLAS
|
|
3013
3081
|
sb_config._cdp_browser = "atlas"
|
|
3014
3082
|
if (
|
|
3015
3083
|
hasattr(sb_config, "settings")
|
|
3016
|
-
and
|
|
3017
|
-
and sb_config.settings.NEW_DRIVER_DIR
|
|
3084
|
+
and getattr(sb_config.settings, "NEW_DRIVER_DIR", None)
|
|
3018
3085
|
and os.path.exists(sb_config.settings.NEW_DRIVER_DIR)
|
|
3019
3086
|
):
|
|
3020
3087
|
driver_dir = sb_config.settings.NEW_DRIVER_DIR
|
|
@@ -3026,6 +3093,23 @@ def get_driver(
|
|
|
3026
3093
|
if browser_name in constants.ChromiumSubs.chromium_subs:
|
|
3027
3094
|
browser_name = "chrome"
|
|
3028
3095
|
browser_name = browser_name.lower()
|
|
3096
|
+
if is_using_uc(undetectable, browser_name):
|
|
3097
|
+
if ad_block_on:
|
|
3098
|
+
sb_config.ad_block_on = True
|
|
3099
|
+
else:
|
|
3100
|
+
sb_config.ad_block_on = False
|
|
3101
|
+
if disable_csp:
|
|
3102
|
+
sb_config.disable_csp = True
|
|
3103
|
+
else:
|
|
3104
|
+
sb_config.disable_csp = False
|
|
3105
|
+
if mobile_emulator:
|
|
3106
|
+
# For stealthy mobile mode, see the CDP Mode examples
|
|
3107
|
+
# to learn how to properly configure it.
|
|
3108
|
+
user_agent = None # Undo the override
|
|
3109
|
+
mobile_emulator = False # Instead, set from CDP Mode
|
|
3110
|
+
sb_config._cdp_mobile_mode = True
|
|
3111
|
+
else:
|
|
3112
|
+
sb_config._cdp_mobile_mode = False
|
|
3029
3113
|
if headless2 and browser_name == constants.Browser.FIREFOX:
|
|
3030
3114
|
headless2 = False # Only for Chromium
|
|
3031
3115
|
headless = True
|
|
@@ -3046,6 +3130,51 @@ def get_driver(
|
|
|
3046
3130
|
or browser_name == constants.Browser.EDGE
|
|
3047
3131
|
)
|
|
3048
3132
|
):
|
|
3133
|
+
if (
|
|
3134
|
+
binary_location.lower() == "_chromium_"
|
|
3135
|
+
and browser_name == constants.Browser.GOOGLE_CHROME
|
|
3136
|
+
):
|
|
3137
|
+
binary_folder = None
|
|
3138
|
+
if IS_MAC:
|
|
3139
|
+
binary_folder = "chrome-mac"
|
|
3140
|
+
elif IS_LINUX:
|
|
3141
|
+
binary_folder = "chrome-linux"
|
|
3142
|
+
elif IS_WINDOWS:
|
|
3143
|
+
binary_folder = "chrome-win"
|
|
3144
|
+
if binary_folder:
|
|
3145
|
+
binary_location = os.path.join(driver_dir, binary_folder)
|
|
3146
|
+
if not os.path.exists(binary_location):
|
|
3147
|
+
from seleniumbase.console_scripts import sb_install
|
|
3148
|
+
args = " ".join(sys.argv)
|
|
3149
|
+
if not (
|
|
3150
|
+
"-n" in sys.argv or " -n=" in args or args == "-c"
|
|
3151
|
+
):
|
|
3152
|
+
# (Not multithreaded)
|
|
3153
|
+
sys_args = sys.argv # Save a copy of current sys args
|
|
3154
|
+
log_d("\nWarning: Chromium binary not found...")
|
|
3155
|
+
try:
|
|
3156
|
+
sb_install.main(override="chromium")
|
|
3157
|
+
except Exception as e:
|
|
3158
|
+
log_d("\nWarning: Chrome download failed: %s" % e)
|
|
3159
|
+
sys.argv = sys_args # Put back the original sys args
|
|
3160
|
+
else:
|
|
3161
|
+
chrome_fixing_lock = fasteners.InterProcessLock(
|
|
3162
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
|
3163
|
+
)
|
|
3164
|
+
with chrome_fixing_lock:
|
|
3165
|
+
with suppress(Exception):
|
|
3166
|
+
shared_utils.make_writable(
|
|
3167
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
|
3168
|
+
)
|
|
3169
|
+
if not os.path.exists(binary_location):
|
|
3170
|
+
sys_args = sys.argv # Save a copy of sys args
|
|
3171
|
+
log_d(
|
|
3172
|
+
"\nWarning: Chromium binary not found..."
|
|
3173
|
+
)
|
|
3174
|
+
sb_install.main(override="chromium")
|
|
3175
|
+
sys.argv = sys_args # Put back original args
|
|
3176
|
+
else:
|
|
3177
|
+
binary_location = None
|
|
3049
3178
|
if (
|
|
3050
3179
|
binary_location.lower() == "cft"
|
|
3051
3180
|
and browser_name == constants.Browser.GOOGLE_CHROME
|
|
@@ -3183,12 +3312,25 @@ def get_driver(
|
|
|
3183
3312
|
binary_name = "Google Chrome for Testing"
|
|
3184
3313
|
binary_location += "/Google Chrome for Testing.app"
|
|
3185
3314
|
binary_location += "/Contents/MacOS/Google Chrome for Testing"
|
|
3315
|
+
elif binary_name == "Chromium.app":
|
|
3316
|
+
binary_name = "Chromium"
|
|
3317
|
+
binary_location += "/Contents/MacOS/Chromium"
|
|
3318
|
+
elif binary_name in ["chrome-mac"]:
|
|
3319
|
+
binary_name = "Chromium"
|
|
3320
|
+
binary_location += "/Chromium.app"
|
|
3321
|
+
binary_location += "/Contents/MacOS/Chromium"
|
|
3186
3322
|
elif binary_name == "chrome-linux64":
|
|
3187
3323
|
binary_name = "chrome"
|
|
3188
3324
|
binary_location += "/chrome"
|
|
3325
|
+
elif binary_name == "chrome-linux":
|
|
3326
|
+
binary_name = "chrome"
|
|
3327
|
+
binary_location += "/chrome"
|
|
3189
3328
|
elif binary_name in ["chrome-win32", "chrome-win64"]:
|
|
3190
3329
|
binary_name = "chrome.exe"
|
|
3191
3330
|
binary_location += "\\chrome.exe"
|
|
3331
|
+
elif binary_name in ["chrome-win"]:
|
|
3332
|
+
binary_name = "chrome.exe"
|
|
3333
|
+
binary_location += "\\chrome.exe"
|
|
3192
3334
|
elif binary_name in [
|
|
3193
3335
|
"chrome-headless-shell-mac-arm64",
|
|
3194
3336
|
"chrome-headless-shell-mac-x64",
|
|
@@ -3226,8 +3368,8 @@ def get_driver(
|
|
|
3226
3368
|
proxy_pass = None
|
|
3227
3369
|
proxy_scheme = "http"
|
|
3228
3370
|
if proxy_string:
|
|
3229
|
-
# (The
|
|
3230
|
-
|
|
3371
|
+
# (The line below is for the Chrome 142 proxy auth fix)
|
|
3372
|
+
sb_config._cdp_proxy = proxy_string
|
|
3231
3373
|
username_and_password = None
|
|
3232
3374
|
if "@" in proxy_string:
|
|
3233
3375
|
# Format => username:password@hostname:port
|
|
@@ -3960,34 +4102,34 @@ def get_local_driver(
|
|
|
3960
4102
|
downloads_path = DOWNLOADS_FOLDER
|
|
3961
4103
|
driver_dir = DRIVER_DIR
|
|
3962
4104
|
special_chrome = False
|
|
3963
|
-
if
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
4105
|
+
if binary_location:
|
|
4106
|
+
if (
|
|
4107
|
+
binary_location == "_chromium_"
|
|
4108
|
+
or "chromium_drivers" in binary_location
|
|
4109
|
+
):
|
|
4110
|
+
special_chrome = True
|
|
4111
|
+
driver_dir = DRIVER_DIR_CHROMIUM
|
|
4112
|
+
elif binary_location == "cft" or "cft_drivers" in binary_location:
|
|
4113
|
+
special_chrome = True
|
|
4114
|
+
driver_dir = DRIVER_DIR_CFT
|
|
4115
|
+
elif binary_location == "chs" or "chs_drivers" in binary_location:
|
|
4116
|
+
special_chrome = True
|
|
4117
|
+
driver_dir = DRIVER_DIR_CHS
|
|
4118
|
+
elif _special_binary_exists(binary_location, "opera"):
|
|
4119
|
+
special_chrome = True
|
|
4120
|
+
driver_dir = DRIVER_DIR_OPERA
|
|
4121
|
+
elif _special_binary_exists(binary_location, "brave"):
|
|
4122
|
+
special_chrome = True
|
|
4123
|
+
driver_dir = DRIVER_DIR_BRAVE
|
|
4124
|
+
elif _special_binary_exists(binary_location, "comet"):
|
|
4125
|
+
special_chrome = True
|
|
4126
|
+
driver_dir = DRIVER_DIR_COMET
|
|
4127
|
+
elif _special_binary_exists(binary_location, "atlas"):
|
|
4128
|
+
special_chrome = True
|
|
4129
|
+
driver_dir = DRIVER_DIR_ATLAS
|
|
3987
4130
|
if (
|
|
3988
4131
|
hasattr(sb_config, "settings")
|
|
3989
|
-
and
|
|
3990
|
-
and sb_config.settings.NEW_DRIVER_DIR
|
|
4132
|
+
and getattr(sb_config.settings, "NEW_DRIVER_DIR", None)
|
|
3991
4133
|
and os.path.exists(sb_config.settings.NEW_DRIVER_DIR)
|
|
3992
4134
|
):
|
|
3993
4135
|
driver_dir = sb_config.settings.NEW_DRIVER_DIR
|
|
@@ -4552,12 +4694,12 @@ def get_local_driver(
|
|
|
4552
4694
|
# Can be a comma-separated list of .ZIP or .CRX files
|
|
4553
4695
|
extension_zip_list = extension_zip.split(",")
|
|
4554
4696
|
for extension_zip_item in extension_zip_list:
|
|
4555
|
-
abs_path = os.path.
|
|
4697
|
+
abs_path = os.path.realpath(extension_zip_item)
|
|
4556
4698
|
edge_options.add_extension(abs_path)
|
|
4557
4699
|
if extension_dir:
|
|
4558
4700
|
# load-extension input can be a comma-separated list
|
|
4559
4701
|
abs_path = (
|
|
4560
|
-
",".join(os.path.
|
|
4702
|
+
",".join(os.path.realpath(p) for p in extension_dir.split(","))
|
|
4561
4703
|
)
|
|
4562
4704
|
edge_options = add_chrome_ext_dir(edge_options, abs_path)
|
|
4563
4705
|
edge_options.add_argument("--disable-infobars")
|
|
@@ -4597,8 +4739,7 @@ def get_local_driver(
|
|
|
4597
4739
|
edge_options.page_load_strategy = page_load_strategy.lower()
|
|
4598
4740
|
elif (
|
|
4599
4741
|
not page_load_strategy
|
|
4600
|
-
and
|
|
4601
|
-
and settings.PAGE_LOAD_STRATEGY
|
|
4742
|
+
and getattr(settings, "PAGE_LOAD_STRATEGY", None)
|
|
4602
4743
|
and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"]
|
|
4603
4744
|
):
|
|
4604
4745
|
# Only change it if not "normal", which is the default.
|
|
@@ -4709,6 +4850,7 @@ def get_local_driver(
|
|
|
4709
4850
|
included_disabled_features.append("OptimizationHints")
|
|
4710
4851
|
included_disabled_features.append("OptimizationHintsFetching")
|
|
4711
4852
|
included_disabled_features.append("Translate")
|
|
4853
|
+
included_disabled_features.append("ComponentUpdater")
|
|
4712
4854
|
included_disabled_features.append("OptimizationTargetPrediction")
|
|
4713
4855
|
included_disabled_features.append("OptimizationGuideModelDownloading")
|
|
4714
4856
|
included_disabled_features.append("InsecureDownloadWarnings")
|
|
@@ -4719,6 +4861,11 @@ def get_local_driver(
|
|
|
4719
4861
|
included_disabled_features.append(
|
|
4720
4862
|
"DisableLoadExtensionCommandLineSwitch"
|
|
4721
4863
|
)
|
|
4864
|
+
included_disabled_features.append("Bluetooth")
|
|
4865
|
+
included_disabled_features.append("WebBluetooth")
|
|
4866
|
+
included_disabled_features.append("UnifiedWebBluetooth")
|
|
4867
|
+
included_disabled_features.append("WebAuthentication")
|
|
4868
|
+
included_disabled_features.append("PasskeyAuth")
|
|
4722
4869
|
for item in extra_disabled_features:
|
|
4723
4870
|
if item not in included_disabled_features:
|
|
4724
4871
|
included_disabled_features.append(item)
|
|
@@ -4810,8 +4957,7 @@ def get_local_driver(
|
|
|
4810
4957
|
options.page_load_strategy = page_load_strategy.lower()
|
|
4811
4958
|
elif (
|
|
4812
4959
|
not page_load_strategy
|
|
4813
|
-
and
|
|
4814
|
-
and settings.PAGE_LOAD_STRATEGY
|
|
4960
|
+
and getattr(settings, "PAGE_LOAD_STRATEGY", None)
|
|
4815
4961
|
and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"]
|
|
4816
4962
|
):
|
|
4817
4963
|
# Only change it if not "normal", which is the default.
|
|
@@ -4899,6 +5045,8 @@ def get_local_driver(
|
|
|
4899
5045
|
device_height,
|
|
4900
5046
|
device_pixel_ratio,
|
|
4901
5047
|
)
|
|
5048
|
+
if binary_location and "chromium_drivers" in binary_location:
|
|
5049
|
+
chrome_options.add_argument("--use-mock-keychain")
|
|
4902
5050
|
use_version = "latest"
|
|
4903
5051
|
major_chrome_version = None
|
|
4904
5052
|
saved_mcv = None
|
|
@@ -5748,6 +5896,7 @@ def get_local_driver(
|
|
|
5748
5896
|
)
|
|
5749
5897
|
driver.default_get = driver.get # Save copy of original
|
|
5750
5898
|
driver.cdp = None # Set a placeholder
|
|
5899
|
+
driver._is_using_uc = False
|
|
5751
5900
|
driver._is_using_cdp = False
|
|
5752
5901
|
driver._is_connected = True
|
|
5753
5902
|
if uc_activated:
|
|
@@ -5782,6 +5931,7 @@ def get_local_driver(
|
|
|
5782
5931
|
driver, *args, **kwargs
|
|
5783
5932
|
)
|
|
5784
5933
|
)
|
|
5934
|
+
driver.activate_cdp_mode = driver.uc_activate_cdp_mode
|
|
5785
5935
|
driver.uc_open_with_cdp_mode = (
|
|
5786
5936
|
lambda *args, **kwargs: uc_open_with_cdp_mode(
|
|
5787
5937
|
driver, *args, **kwargs
|
|
@@ -5861,8 +6011,18 @@ def get_local_driver(
|
|
|
5861
6011
|
time.sleep(0.003)
|
|
5862
6012
|
driver.switch_to.window(driver.window_handles[0])
|
|
5863
6013
|
time.sleep(0.003)
|
|
5864
|
-
|
|
5865
|
-
|
|
6014
|
+
# seleniumbase/SeleniumBase/discussions/4190
|
|
6015
|
+
if getattr(sb_config, "skip_133_patch", None):
|
|
6016
|
+
# To skip the connect() patch for Chrome 133+:
|
|
6017
|
+
# from seleniumbase import config as sb_config
|
|
6018
|
+
# sb_config.skip_133_patch = True
|
|
6019
|
+
# (Do the above before launching the browser.)
|
|
6020
|
+
pass
|
|
6021
|
+
else:
|
|
6022
|
+
# This fixes an issue on Chrome 133+
|
|
6023
|
+
# (Some people might not need it though.)
|
|
6024
|
+
driver.connect()
|
|
6025
|
+
time.sleep(0.003)
|
|
5866
6026
|
if mobile_emulator:
|
|
5867
6027
|
uc_metrics = {}
|
|
5868
6028
|
if (
|
|
@@ -5890,6 +6050,8 @@ def get_local_driver(
|
|
|
5890
6050
|
'Emulation.setDeviceMetricsOverride',
|
|
5891
6051
|
set_device_metrics_override
|
|
5892
6052
|
)
|
|
6053
|
+
else:
|
|
6054
|
+
driver.get = lambda url: updated_get(driver, url)
|
|
5893
6055
|
return extend_driver(
|
|
5894
6056
|
driver, proxy_auth, use_uc, recorder_ext
|
|
5895
6057
|
)
|