Skip to content

Commit 2b60087

Browse files
authored
Merge pull request #3777 from seleniumbase/fix-extensions-on-chrome-137
Fix extensions on Chrome 137+
2 parents d0a26b8 + 7d9ea59 commit 2b60087

File tree

10 files changed

+131
-22
lines changed

10 files changed

+131
-22
lines changed

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ pytest-metadata==3.1.1
6060
pytest-ordering==0.6
6161
pytest-rerunfailures==14.0;python_version<"3.9"
6262
pytest-rerunfailures==15.1;python_version>="3.9"
63-
pytest-xdist==3.6.1
63+
pytest-xdist==3.6.1;python_version<"3.9"
64+
pytest-xdist==3.7.0;python_version>="3.9"
6465
parameterized==0.9.0
6566
behave==1.2.6
6667
soupsieve==2.7

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.39.0"
2+
__version__ = "4.39.1"

seleniumbase/console_scripts/sb_mkrec.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,9 @@ def main():
192192
elif "'" not in start_page:
193193
used_sp = "'%s'" % start_page
194194
data.append(
195-
" self.uc_open_with_disconnect(\n"
196-
" %s\n"
195+
" self.activate_cdp_mode(\n"
196+
" %s,\n"
197+
" recorder=True,\n"
197198
" )" % used_sp
198199
)
199200
else:

seleniumbase/core/browser_launcher.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ def make_driver_executable_if_not(driver_path):
108108
shared_utils.make_executable(driver_path)
109109

110110

111-
def extend_driver(driver, proxy_auth=False, use_uc=True):
111+
def extend_driver(
112+
driver, proxy_auth=False, use_uc=True, recorder_ext=False
113+
):
112114
# Extend the driver with new methods
113115
driver.default_find_element = driver.find_element
114116
driver.default_find_elements = driver.find_elements
@@ -234,6 +236,14 @@ def extend_driver(driver, proxy_auth=False, use_uc=True):
234236
driver.switch_to_tab = DM.switch_to_tab
235237
driver.switch_to_frame = DM.switch_to_frame
236238
driver.reset_window_size = DM.reset_window_size
239+
if recorder_ext:
240+
from seleniumbase.js_code.recorder_js import recorder_js
241+
recorder_code = (
242+
"""window.onload = function() { %s };""" % recorder_js
243+
)
244+
driver.execute_cdp_cmd(
245+
"Page.addScriptToEvaluateOnNewDocument", {"source": recorder_code}
246+
)
237247
if hasattr(driver, "proxy"):
238248
driver.set_wire_proxy = DM.set_wire_proxy
239249
if proxy_auth:
@@ -2542,6 +2552,7 @@ def _set_chrome_options(
25422552
included_disabled_features.append("PrivacySandboxSettings4")
25432553
included_disabled_features.append("SidePanelPinning")
25442554
included_disabled_features.append("UserAgentClientHint")
2555+
included_disabled_features.append("DisableLoadExtensionCommandLineSwitch")
25452556
for item in extra_disabled_features:
25462557
if item not in included_disabled_features:
25472558
included_disabled_features.append(item)
@@ -2819,6 +2830,8 @@ def get_driver(
28192830
if headless2 and browser_name == constants.Browser.FIREFOX:
28202831
headless2 = False # Only for Chromium
28212832
headless = True
2833+
if binary_location and isinstance(binary_location, str):
2834+
binary_location = binary_location.strip()
28222835
if (
28232836
is_using_uc(undetectable, browser_name)
28242837
and binary_location
@@ -3014,6 +3027,8 @@ def get_driver(
30143027
proxy_pass = None
30153028
proxy_scheme = "http"
30163029
if proxy_string:
3030+
# (The code below was for the Chrome 137 extension fix)
3031+
# sb_config._cdp_proxy = proxy_string
30173032
username_and_password = None
30183033
if "@" in proxy_string:
30193034
# Format => username:password@hostname:port
@@ -4450,6 +4465,9 @@ def get_local_driver(
44504465
included_disabled_features.append("PrivacySandboxSettings4")
44514466
included_disabled_features.append("SidePanelPinning")
44524467
included_disabled_features.append("UserAgentClientHint")
4468+
included_disabled_features.append(
4469+
"DisableLoadExtensionCommandLineSwitch"
4470+
)
44534471
for item in extra_disabled_features:
44544472
if item not in included_disabled_features:
44554473
included_disabled_features.append(item)
@@ -5328,7 +5346,9 @@ def get_local_driver(
53285346
driver = webdriver.Chrome(
53295347
service=service, options=chrome_options
53305348
)
5331-
return extend_driver(driver, proxy_auth, use_uc)
5349+
return extend_driver(
5350+
driver, proxy_auth, use_uc, recorder_ext
5351+
)
53325352
if not auto_upgrade_chromedriver:
53335353
raise # Not an obvious fix.
53345354
else:
@@ -5580,11 +5600,15 @@ def get_local_driver(
55805600
'Emulation.setDeviceMetricsOverride',
55815601
set_device_metrics_override
55825602
)
5583-
return extend_driver(driver, proxy_auth, use_uc)
5603+
return extend_driver(
5604+
driver, proxy_auth, use_uc, recorder_ext
5605+
)
55845606
else: # Running headless on Linux (and not using --uc)
55855607
try:
55865608
driver = webdriver.Chrome(options=chrome_options)
5587-
return extend_driver(driver, proxy_auth, use_uc)
5609+
return extend_driver(
5610+
driver, proxy_auth, use_uc, recorder_ext
5611+
)
55885612
except Exception as e:
55895613
if not hasattr(e, "msg"):
55905614
raise
@@ -5606,7 +5630,9 @@ def get_local_driver(
56065630
driver = webdriver.Chrome(
56075631
service=service, options=chrome_options
56085632
)
5609-
return extend_driver(driver, proxy_auth, use_uc)
5633+
return extend_driver(
5634+
driver, proxy_auth, use_uc, recorder_ext
5635+
)
56105636
mcv = None # Major Chrome Version
56115637
if "Current browser version is " in e.msg:
56125638
line = e.msg.split("Current browser version is ")[1]
@@ -5649,7 +5675,9 @@ def get_local_driver(
56495675
service=service,
56505676
options=chrome_options,
56515677
)
5652-
return extend_driver(driver, proxy_auth, use_uc)
5678+
return extend_driver(
5679+
driver, proxy_auth, use_uc, recorder_ext
5680+
)
56535681
# Use the virtual display on Linux during headless errors
56545682
logging.debug(
56555683
"\nWarning: Chrome failed to launch in"
@@ -5667,7 +5695,9 @@ def get_local_driver(
56675695
driver = webdriver.Chrome(
56685696
service=service, options=chrome_options
56695697
)
5670-
return extend_driver(driver, proxy_auth, use_uc)
5698+
return extend_driver(
5699+
driver, proxy_auth, use_uc, recorder_ext
5700+
)
56715701
except Exception as original_exception:
56725702
if use_uc:
56735703
raise
@@ -5677,7 +5707,9 @@ def get_local_driver(
56775707
driver = webdriver.Chrome(
56785708
service=service, options=chrome_options
56795709
)
5680-
return extend_driver(driver, proxy_auth, use_uc)
5710+
return extend_driver(
5711+
driver, proxy_auth, use_uc, recorder_ext
5712+
)
56815713
if user_data_dir:
56825714
print("\nUnable to set user_data_dir while starting Chrome!\n")
56835715
raise
@@ -5704,7 +5736,9 @@ def get_local_driver(
57045736
)
57055737
try:
57065738
driver = webdriver.Chrome(service=service)
5707-
return extend_driver(driver, proxy_auth, use_uc)
5739+
return extend_driver(
5740+
driver, proxy_auth, use_uc, recorder_ext
5741+
)
57085742
except Exception:
57095743
raise original_exception
57105744
else:

seleniumbase/extensions/recorder.zip

-105 Bytes
Binary file not shown.

seleniumbase/undetected/cdp_driver/browser.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ async def get(
292292
_cdp_locale = None
293293
_cdp_platform = None
294294
_cdp_geolocation = None
295+
_cdp_recorder = None
295296
if (
296297
hasattr(sb_config, "_cdp_timezone") and sb_config._cdp_timezone
297298
):
@@ -330,6 +331,8 @@ async def get(
330331
_cdp_geolocation = kwargs["geolocation"]
331332
elif "geoloc" in kwargs:
332333
_cdp_geolocation = kwargs["geoloc"]
334+
if "recorder" in kwargs:
335+
_cdp_recorder = kwargs["recorder"]
333336
if _cdp_timezone:
334337
await connection.send(cdp.page.navigate("about:blank"))
335338
await connection.set_timezone(_cdp_timezone)
@@ -344,9 +347,37 @@ async def get(
344347
await connection.send(cdp.page.navigate("about:blank"))
345348
await connection.set_geolocation(_cdp_geolocation)
346349
# Use the tab to navigate to new url
350+
if (
351+
hasattr(sb_config, "_cdp_proxy")
352+
and "@" in sb_config._cdp_proxy
353+
and sb_config._cdp_proxy
354+
and "auth" not in kwargs
355+
):
356+
username_and_password = sb_config._cdp_proxy.split("@")[0]
357+
proxy_user = username_and_password.split(":")[0]
358+
proxy_pass = username_and_password.split(":")[1]
359+
await connection.set_auth(
360+
proxy_user, proxy_pass, self.tabs[0]
361+
)
362+
time.sleep(0.25)
363+
elif "auth" in kwargs and kwargs["auth"] and ":" in kwargs["auth"]:
364+
username_and_password = kwargs["auth"]
365+
proxy_user = username_and_password.split(":")[0]
366+
proxy_pass = username_and_password.split(":")[1]
367+
await connection.set_auth(
368+
proxy_user, proxy_pass, self.tabs[0]
369+
)
370+
time.sleep(0.25)
347371
frame_id, loader_id, *_ = await connection.send(
348372
cdp.page.navigate(url)
349373
)
374+
if _cdp_recorder:
375+
pass # (The code below was for the Chrome 137 extension fix)
376+
'''from seleniumbase.js_code.recorder_js import recorder_js
377+
recorder_code = (
378+
"""window.onload = function() { %s };""" % recorder_js
379+
)
380+
await connection.send(cdp.runtime.evaluate(recorder_code))'''
350381
# Update the frame_id on the tab
351382
connection.frame_id = frame_id
352383
connection.browser = self

seleniumbase/undetected/cdp_driver/cdp_util.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,10 @@ async def start(
360360
except Exception:
361361
time.sleep(0.15)
362362
driver = await Browser.create(config)
363-
if proxy and "@" in str(proxy):
364-
time.sleep(0.15)
363+
if proxy:
364+
sb_config._cdp_proxy = proxy
365+
if "@" in str(proxy):
366+
time.sleep(0.15)
365367
if lang:
366368
sb_config._cdp_locale = lang
367369
elif "locale" in kwargs:
@@ -402,10 +404,14 @@ async def start_async(*args, **kwargs) -> Browser:
402404
binary_location = None
403405
if "browser_executable_path" in kwargs:
404406
binary_location = kwargs["browser_executable_path"]
407+
if binary_location and isinstance(binary_location, str):
408+
binary_location = binary_location.strip()
405409
else:
406410
binary_location = detect_b_ver.get_binary_location("google-chrome")
407-
if binary_location and not os.path.exists(binary_location):
408-
binary_location = None
411+
if binary_location and isinstance(binary_location, str):
412+
binary_location = binary_location.strip()
413+
if not os.path.exists(binary_location):
414+
binary_location = None
409415
if (
410416
shared_utils.is_chrome_130_or_newer(binary_location)
411417
and "user_data_dir" in kwargs
@@ -438,10 +444,14 @@ def start_sync(*args, **kwargs) -> Browser:
438444
binary_location = None
439445
if "browser_executable_path" in kwargs:
440446
binary_location = kwargs["browser_executable_path"]
447+
if binary_location and isinstance(binary_location, str):
448+
binary_location = binary_location.strip()
441449
else:
442450
binary_location = detect_b_ver.get_binary_location("google-chrome")
443-
if binary_location and not os.path.exists(binary_location):
444-
binary_location = None
451+
if binary_location and isinstance(binary_location, str):
452+
binary_location = binary_location.strip()
453+
if not os.path.exists(binary_location):
454+
binary_location = None
445455
if (
446456
shared_utils.is_chrome_130_or_newer(binary_location)
447457
and "user_data_dir" in kwargs

seleniumbase/undetected/cdp_driver/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ def __init__(
144144
"--disable-features=IsolateOrigins,site-per-process,Translate,"
145145
"InsecureDownloadWarnings,DownloadBubble,DownloadBubbleV2,"
146146
"OptimizationTargetPrediction,OptimizationGuideModelDownloading,"
147-
"SidePanelPinning,UserAgentClientHint,PrivacySandboxSettings4",
147+
"SidePanelPinning,UserAgentClientHint,PrivacySandboxSettings4,"
148+
"DisableLoadExtensionCommandLineSwitch",
148149
]
149150

150151
@property

seleniumbase/undetected/cdp_driver/connection.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,36 @@ async def set_geolocation(self, geolocation: Optional[tuple] = None):
378378
accuracy=100,
379379
))
380380

381+
async def set_auth(self, username, password, tab):
382+
async def auth_challenge_handler(event: cdp.fetch.AuthRequired):
383+
await tab.send(
384+
cdp.fetch.continue_with_auth(
385+
request_id=event.request_id,
386+
auth_challenge_response=cdp.fetch.AuthChallengeResponse(
387+
response="ProvideCredentials",
388+
username=username,
389+
password=password,
390+
),
391+
)
392+
)
393+
394+
async def req_paused(event: cdp.fetch.RequestPaused):
395+
await tab.send(
396+
cdp.fetch.continue_request(request_id=event.request_id)
397+
)
398+
399+
tab.add_handler(
400+
cdp.fetch.RequestPaused,
401+
lambda event: asyncio.create_task(req_paused(event)),
402+
)
403+
404+
tab.add_handler(
405+
cdp.fetch.AuthRequired,
406+
lambda event: asyncio.create_task(auth_challenge_handler(event)),
407+
)
408+
409+
await tab.send(cdp.fetch.enable(handle_auth_requests=True))
410+
381411
def __getattr__(self, item):
382412
""":meta private:"""
383413
try:

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@
211211
"pytest-ordering==0.6",
212212
'pytest-rerunfailures==14.0;python_version<"3.9"',
213213
'pytest-rerunfailures==15.1;python_version>="3.9"',
214-
'pytest-xdist==3.6.1',
214+
'pytest-xdist==3.6.1;python_version<"3.9"',
215+
'pytest-xdist==3.7.0;python_version>="3.9"',
215216
'parameterized==0.9.0',
216217
"behave==1.2.6",
217218
'soupsieve==2.7',
@@ -268,7 +269,7 @@
268269
'pdfminer.six==20250324;python_version<"3.9"',
269270
'pdfminer.six==20250506;python_version>="3.9"',
270271
'cryptography==39.0.2;python_version<"3.9"',
271-
'cryptography==45.0.2;python_version>="3.9"',
272+
'cryptography==45.0.3;python_version>="3.9"',
272273
'cffi==1.17.1',
273274
"pycparser==2.22",
274275
],

0 commit comments

Comments
 (0)