seleniumbase 4.32.1__py3-none-any.whl → 4.32.3__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/core/browser_launcher.py +9 -2
- seleniumbase/core/sb_cdp.py +65 -13
- seleniumbase/fixtures/base_case.py +148 -56
- seleniumbase/fixtures/shared_utils.py +18 -0
- seleniumbase/plugins/driver_manager.py +21 -11
- seleniumbase/plugins/sb_manager.py +0 -24
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +830 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +328 -0
- seleniumbase/undetected/cdp_driver/config.py +328 -0
- seleniumbase/undetected/cdp_driver/connection.py +630 -0
- seleniumbase/undetected/cdp_driver/element.py +1150 -0
- seleniumbase/undetected/cdp_driver/tab.py +1319 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/METADATA +1 -1
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/RECORD +21 -13
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/LICENSE +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/WHEEL +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/top_level.txt +0 -0
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.32.
|
2
|
+
__version__ = "4.32.3"
|
@@ -549,7 +549,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
549
549
|
cdp = types.SimpleNamespace()
|
550
550
|
CDPM = sb_cdp.CDPMethods(loop, page, driver)
|
551
551
|
cdp.get = CDPM.get
|
552
|
-
cdp.open = CDPM.
|
552
|
+
cdp.open = CDPM.open
|
553
553
|
cdp.reload = CDPM.reload
|
554
554
|
cdp.refresh = CDPM.refresh
|
555
555
|
cdp.add_handler = CDPM.add_handler
|
@@ -590,6 +590,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
590
590
|
cdp.medimize = CDPM.medimize
|
591
591
|
cdp.set_window_rect = CDPM.set_window_rect
|
592
592
|
cdp.reset_window_size = CDPM.reset_window_size
|
593
|
+
cdp.set_locale = CDPM.set_locale
|
593
594
|
cdp.set_attributes = CDPM.set_attributes
|
594
595
|
cdp.internalize_links = CDPM.internalize_links
|
595
596
|
cdp.get_window = CDPM.get_window
|
@@ -2179,8 +2180,13 @@ def _set_chrome_options(
|
|
2179
2180
|
or IS_LINUX # switches to Xvfb (non-headless)
|
2180
2181
|
)
|
2181
2182
|
):
|
2183
|
+
chrome_options.add_argument("--no-pings")
|
2182
2184
|
chrome_options.add_argument("--disable-popup-blocking")
|
2183
|
-
chrome_options.add_argument("--homepage=chrome://
|
2185
|
+
chrome_options.add_argument("--homepage=chrome://version/")
|
2186
|
+
chrome_options.add_argument("--animation-duration-scale=0")
|
2187
|
+
chrome_options.add_argument("--wm-window-animations-disabled")
|
2188
|
+
chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
|
2189
|
+
chrome_options.add_argument("--disable-background-timer-throttling")
|
2184
2190
|
# Skip remaining options that trigger anti-bot services
|
2185
2191
|
return chrome_options
|
2186
2192
|
chrome_options.add_argument("--test-type")
|
@@ -4523,6 +4529,7 @@ def get_local_driver(
|
|
4523
4529
|
and uc_chrome_version
|
4524
4530
|
and uc_chrome_version >= 117
|
4525
4531
|
and (headless or headless2)
|
4532
|
+
and chromium_arg != "decoy"
|
4526
4533
|
):
|
4527
4534
|
from seleniumbase.console_scripts import (
|
4528
4535
|
sb_install
|
seleniumbase/core/sb_cdp.py
CHANGED
@@ -76,13 +76,21 @@ class CDPMethods():
|
|
76
76
|
|
77
77
|
def get(self, url):
|
78
78
|
url = shared_utils.fix_url_as_needed(url)
|
79
|
-
|
79
|
+
driver = self.driver
|
80
|
+
if hasattr(driver, "cdp_base"):
|
81
|
+
driver = driver.cdp_base
|
82
|
+
self.page = self.loop.run_until_complete(driver.get(url))
|
80
83
|
url_protocol = url.split(":")[0]
|
81
84
|
safe_url = True
|
82
85
|
if url_protocol not in ["about", "data", "chrome"]:
|
83
86
|
safe_url = False
|
84
87
|
if not safe_url:
|
85
88
|
time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
|
89
|
+
self.__slow_mode_pause_if_set()
|
90
|
+
self.loop.run_until_complete(self.page.wait())
|
91
|
+
|
92
|
+
def open(self, url):
|
93
|
+
self.get(url)
|
86
94
|
|
87
95
|
def reload(self, ignore_cache=True, script_to_evaluate_on_load=None):
|
88
96
|
self.loop.run_until_complete(
|
@@ -111,18 +119,28 @@ class CDPMethods():
|
|
111
119
|
with the closest text-length to the text being searched for."""
|
112
120
|
self.__add_light_pause()
|
113
121
|
selector = self.__convert_to_css_if_xpath(selector)
|
122
|
+
early_failure = False
|
114
123
|
if (":contains(" in selector):
|
115
124
|
tag_name = selector.split(":contains(")[0].split(" ")[-1]
|
116
125
|
text = selector.split(":contains(")[1].split(")")[0][1:-1]
|
117
126
|
with suppress(Exception):
|
118
127
|
self.loop.run_until_complete(
|
119
|
-
self.page.select(tag_name, timeout=
|
128
|
+
self.page.select(tag_name, timeout=timeout)
|
120
129
|
)
|
121
|
-
self.loop.run_until_complete(
|
122
|
-
|
123
|
-
|
130
|
+
self.loop.run_until_complete(
|
131
|
+
self.page.find(text, timeout=timeout)
|
132
|
+
)
|
133
|
+
elements = []
|
134
|
+
with suppress(Exception):
|
135
|
+
elements = self.find_elements_by_text(text, tag_name=tag_name)
|
136
|
+
if elements:
|
137
|
+
return self.__add_sync_methods(elements[0])
|
138
|
+
else:
|
139
|
+
early_failure = True
|
124
140
|
failure = False
|
125
141
|
try:
|
142
|
+
if early_failure:
|
143
|
+
raise Exception("Failed!")
|
126
144
|
element = self.loop.run_until_complete(
|
127
145
|
self.page.find(
|
128
146
|
selector, best_match=best_match, timeout=timeout
|
@@ -230,9 +248,11 @@ class CDPMethods():
|
|
230
248
|
)
|
231
249
|
|
232
250
|
def __click(self, element):
|
233
|
-
|
251
|
+
result = (
|
234
252
|
self.loop.run_until_complete(element.click_async())
|
235
253
|
)
|
254
|
+
self.loop.run_until_complete(self.page.wait())
|
255
|
+
return result
|
236
256
|
|
237
257
|
def __flash(self, element):
|
238
258
|
return (
|
@@ -250,9 +270,11 @@ class CDPMethods():
|
|
250
270
|
)
|
251
271
|
|
252
272
|
def __mouse_click(self, element):
|
253
|
-
|
273
|
+
result = (
|
254
274
|
self.loop.run_until_complete(element.mouse_click_async())
|
255
275
|
)
|
276
|
+
self.loop.run_until_complete(self.page.wait())
|
277
|
+
return result
|
256
278
|
|
257
279
|
def __mouse_drag(self, element, destination):
|
258
280
|
return (
|
@@ -353,33 +375,51 @@ class CDPMethods():
|
|
353
375
|
|
354
376
|
def tile_windows(self, windows=None, max_columns=0):
|
355
377
|
"""Tile windows and return the grid of tiled windows."""
|
378
|
+
driver = self.driver
|
379
|
+
if hasattr(driver, "cdp_base"):
|
380
|
+
driver = driver.cdp_base
|
356
381
|
return self.loop.run_until_complete(
|
357
|
-
|
382
|
+
driver.tile_windows(windows, max_columns)
|
358
383
|
)
|
359
384
|
|
360
385
|
def get_all_cookies(self, *args, **kwargs):
|
386
|
+
driver = self.driver
|
387
|
+
if hasattr(driver, "cdp_base"):
|
388
|
+
driver = driver.cdp_base
|
361
389
|
return self.loop.run_until_complete(
|
362
|
-
|
390
|
+
driver.cookies.get_all(*args, **kwargs)
|
363
391
|
)
|
364
392
|
|
365
393
|
def set_all_cookies(self, *args, **kwargs):
|
394
|
+
driver = self.driver
|
395
|
+
if hasattr(driver, "cdp_base"):
|
396
|
+
driver = driver.cdp_base
|
366
397
|
return self.loop.run_until_complete(
|
367
|
-
|
398
|
+
driver.cookies.set_all(*args, **kwargs)
|
368
399
|
)
|
369
400
|
|
370
401
|
def save_cookies(self, *args, **kwargs):
|
402
|
+
driver = self.driver
|
403
|
+
if hasattr(driver, "cdp_base"):
|
404
|
+
driver = driver.cdp_base
|
371
405
|
return self.loop.run_until_complete(
|
372
|
-
|
406
|
+
driver.cookies.save(*args, **kwargs)
|
373
407
|
)
|
374
408
|
|
375
409
|
def load_cookies(self, *args, **kwargs):
|
410
|
+
driver = self.driver
|
411
|
+
if hasattr(driver, "cdp_base"):
|
412
|
+
driver = driver.cdp_base
|
376
413
|
return self.loop.run_until_complete(
|
377
|
-
|
414
|
+
driver.cookies.load(*args, **kwargs)
|
378
415
|
)
|
379
416
|
|
380
417
|
def clear_cookies(self, *args, **kwargs):
|
418
|
+
driver = self.driver
|
419
|
+
if hasattr(driver, "cdp_base"):
|
420
|
+
driver = driver.cdp_base
|
381
421
|
return self.loop.run_until_complete(
|
382
|
-
|
422
|
+
driver.cookies.clear(*args, **kwargs)
|
383
423
|
)
|
384
424
|
|
385
425
|
def sleep(self, seconds):
|
@@ -408,17 +448,20 @@ class CDPMethods():
|
|
408
448
|
self.__add_light_pause()
|
409
449
|
element.click()
|
410
450
|
self.__slow_mode_pause_if_set()
|
451
|
+
self.loop.run_until_complete(self.page.wait())
|
411
452
|
|
412
453
|
def click_active_element(self):
|
413
454
|
self.loop.run_until_complete(
|
414
455
|
self.page.evaluate("document.activeElement.click()")
|
415
456
|
)
|
416
457
|
self.__slow_mode_pause_if_set()
|
458
|
+
self.loop.run_until_complete(self.page.wait())
|
417
459
|
|
418
460
|
def click_if_visible(self, selector):
|
419
461
|
if self.is_element_visible(selector):
|
420
462
|
self.find_element(selector).click()
|
421
463
|
self.__slow_mode_pause_if_set()
|
464
|
+
self.loop.run_until_complete(self.page.wait())
|
422
465
|
|
423
466
|
def mouse_click(self, selector, timeout=settings.SMALL_TIMEOUT):
|
424
467
|
"""(Attempt simulating a mouse click)"""
|
@@ -427,6 +470,7 @@ class CDPMethods():
|
|
427
470
|
self.__add_light_pause()
|
428
471
|
element.mouse_click()
|
429
472
|
self.__slow_mode_pause_if_set()
|
473
|
+
self.loop.run_until_complete(self.page.wait())
|
430
474
|
|
431
475
|
def nested_click(self, parent_selector, selector):
|
432
476
|
"""
|
@@ -436,6 +480,7 @@ class CDPMethods():
|
|
436
480
|
element = self.find_element(parent_selector)
|
437
481
|
element.query_selector(selector).mouse_click()
|
438
482
|
self.__slow_mode_pause_if_set()
|
483
|
+
self.loop.run_until_complete(self.page.wait())
|
439
484
|
|
440
485
|
def get_nested_element(self, parent_selector, selector):
|
441
486
|
"""(Can be used to find an element inside an iframe)"""
|
@@ -483,6 +528,7 @@ class CDPMethods():
|
|
483
528
|
text = text[:-1] + "\r\n"
|
484
529
|
element.send_keys(text)
|
485
530
|
self.__slow_mode_pause_if_set()
|
531
|
+
self.loop.run_until_complete(self.page.wait())
|
486
532
|
|
487
533
|
def press_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
|
488
534
|
"""Similar to send_keys(), but presses keys at human speed."""
|
@@ -499,6 +545,7 @@ class CDPMethods():
|
|
499
545
|
element.send_keys("\r\n")
|
500
546
|
time.sleep(0.0375)
|
501
547
|
self.__slow_mode_pause_if_set()
|
548
|
+
self.loop.run_until_complete(self.page.wait())
|
502
549
|
|
503
550
|
def type(self, selector, text, timeout=settings.SMALL_TIMEOUT):
|
504
551
|
"""Similar to send_keys(), but clears the text field first."""
|
@@ -510,6 +557,7 @@ class CDPMethods():
|
|
510
557
|
text = text[:-1] + "\r\n"
|
511
558
|
element.send_keys(text)
|
512
559
|
self.__slow_mode_pause_if_set()
|
560
|
+
self.loop.run_until_complete(self.page.wait())
|
513
561
|
|
514
562
|
def evaluate(self, expression):
|
515
563
|
"""Run a JavaScript expression and return the result."""
|
@@ -760,6 +808,10 @@ class CDPMethods():
|
|
760
808
|
)
|
761
809
|
)
|
762
810
|
|
811
|
+
def set_locale(self, locale):
|
812
|
+
"""(Settings will take effect on the next page load)"""
|
813
|
+
self.loop.run_until_complete(self.page.set_locale(locale))
|
814
|
+
|
763
815
|
def set_attributes(self, selector, attribute, value):
|
764
816
|
"""This method uses JavaScript to set/update a common attribute.
|
765
817
|
All matching selectors from querySelectorAll() are used.
|
@@ -4090,6 +4090,90 @@ class BaseCase(unittest.TestCase):
|
|
4090
4090
|
"Browser: {%s} is not a valid browser option. "
|
4091
4091
|
"Valid options = {%s}" % (browser, valid_browsers)
|
4092
4092
|
)
|
4093
|
+
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
4094
|
+
if (
|
4095
|
+
undetectable
|
4096
|
+
and (
|
4097
|
+
not user_data_dir
|
4098
|
+
or not os.path.exists(user_data_dir)
|
4099
|
+
or not any(os.scandir(user_data_dir))
|
4100
|
+
)
|
4101
|
+
and self.browser == "chrome"
|
4102
|
+
and shared_utils.is_chrome_130_or_newer(binary_location)
|
4103
|
+
):
|
4104
|
+
import tempfile
|
4105
|
+
if not user_data_dir:
|
4106
|
+
user_data_dir = os.path.normpath(tempfile.mkdtemp())
|
4107
|
+
self.user_data_dir = user_data_dir
|
4108
|
+
sb_config.user_data_dir = user_data_dir
|
4109
|
+
try:
|
4110
|
+
decoy_driver = browser_launcher.get_driver(
|
4111
|
+
browser_name=browser_name,
|
4112
|
+
headless=False,
|
4113
|
+
locale_code=locale_code,
|
4114
|
+
use_grid=use_grid,
|
4115
|
+
protocol=protocol,
|
4116
|
+
servername=servername,
|
4117
|
+
port=port,
|
4118
|
+
proxy_string=proxy_string,
|
4119
|
+
proxy_bypass_list=proxy_bypass_list,
|
4120
|
+
proxy_pac_url=proxy_pac_url,
|
4121
|
+
multi_proxy=multi_proxy,
|
4122
|
+
user_agent=user_agent,
|
4123
|
+
cap_file=cap_file,
|
4124
|
+
cap_string=cap_string,
|
4125
|
+
recorder_ext=recorder_ext,
|
4126
|
+
disable_cookies=disable_cookies,
|
4127
|
+
disable_js=disable_js,
|
4128
|
+
disable_csp=disable_csp,
|
4129
|
+
enable_ws=enable_ws,
|
4130
|
+
enable_sync=enable_sync,
|
4131
|
+
use_auto_ext=use_auto_ext,
|
4132
|
+
undetectable=undetectable,
|
4133
|
+
uc_cdp_events=uc_cdp_events,
|
4134
|
+
uc_subprocess=uc_subprocess,
|
4135
|
+
log_cdp_events=log_cdp_events,
|
4136
|
+
no_sandbox=no_sandbox,
|
4137
|
+
disable_gpu=disable_gpu,
|
4138
|
+
headless1=False,
|
4139
|
+
headless2=True,
|
4140
|
+
incognito=incognito,
|
4141
|
+
guest_mode=guest_mode,
|
4142
|
+
dark_mode=dark_mode,
|
4143
|
+
devtools=devtools,
|
4144
|
+
remote_debug=remote_debug,
|
4145
|
+
enable_3d_apis=enable_3d_apis,
|
4146
|
+
swiftshader=swiftshader,
|
4147
|
+
ad_block_on=ad_block_on,
|
4148
|
+
host_resolver_rules=host_resolver_rules,
|
4149
|
+
block_images=block_images,
|
4150
|
+
do_not_track=do_not_track,
|
4151
|
+
chromium_arg="decoy",
|
4152
|
+
firefox_arg=firefox_arg,
|
4153
|
+
firefox_pref=firefox_pref,
|
4154
|
+
user_data_dir=user_data_dir,
|
4155
|
+
extension_zip=None,
|
4156
|
+
extension_dir=None,
|
4157
|
+
disable_features=disable_features,
|
4158
|
+
binary_location=binary_location,
|
4159
|
+
driver_version=driver_version,
|
4160
|
+
page_load_strategy=page_load_strategy,
|
4161
|
+
use_wire=use_wire,
|
4162
|
+
external_pdf=external_pdf,
|
4163
|
+
test_id=test_id,
|
4164
|
+
mobile_emulator=is_mobile,
|
4165
|
+
device_width=d_width,
|
4166
|
+
device_height=d_height,
|
4167
|
+
device_pixel_ratio=d_p_r,
|
4168
|
+
browser=browser_name,
|
4169
|
+
)
|
4170
|
+
time.sleep(0.2)
|
4171
|
+
except Exception:
|
4172
|
+
pass
|
4173
|
+
finally:
|
4174
|
+
with suppress(Exception):
|
4175
|
+
decoy_driver.quit()
|
4176
|
+
time.sleep(0.1)
|
4093
4177
|
# Launch a web browser
|
4094
4178
|
new_driver = browser_launcher.get_driver(
|
4095
4179
|
browser_name=browser_name,
|
@@ -4431,13 +4515,31 @@ class BaseCase(unittest.TestCase):
|
|
4431
4515
|
cookies_file.writelines(json_cookies)
|
4432
4516
|
cookies_file.close()
|
4433
4517
|
|
4434
|
-
def load_cookies(self, name="cookies.txt"):
|
4435
|
-
"""
|
4518
|
+
def load_cookies(self, name="cookies.txt", expiry=False):
|
4519
|
+
"""
|
4520
|
+
Loads the page cookies from the "saved_cookies" folder.
|
4521
|
+
Usage for setting expiry:
|
4522
|
+
If expiry == 0 or False: Delete "expiry".
|
4523
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4524
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4525
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4526
|
+
"""
|
4436
4527
|
cookies = self.get_saved_cookies(name)
|
4437
4528
|
self.wait_for_ready_state_complete()
|
4529
|
+
origin = self.get_origin()
|
4530
|
+
trim_origin = origin.split("://")[-1]
|
4438
4531
|
for cookie in cookies:
|
4439
|
-
if "
|
4532
|
+
if "domain" in cookie:
|
4533
|
+
if cookie["domain"] not in origin:
|
4534
|
+
cookie["domain"] = trim_origin
|
4535
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4440
4536
|
del cookie["expiry"]
|
4537
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4538
|
+
pass
|
4539
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4540
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4541
|
+
elif expiry:
|
4542
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4441
4543
|
self.driver.add_cookie(cookie)
|
4442
4544
|
|
4443
4545
|
def delete_all_cookies(self):
|
@@ -4498,18 +4600,57 @@ class BaseCase(unittest.TestCase):
|
|
4498
4600
|
def get_cookies(self):
|
4499
4601
|
return self.driver.get_cookies()
|
4500
4602
|
|
4501
|
-
def add_cookie(self, cookie_dict):
|
4603
|
+
def add_cookie(self, cookie_dict, expiry=False):
|
4502
4604
|
"""Usage examples:
|
4503
4605
|
self.add_cookie({'name': 'foo', 'value': 'bar'})
|
4504
4606
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'path': '/'})
|
4505
4607
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'secure': True})
|
4506
4608
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'sameSite': 'Strict'})
|
4609
|
+
Usage for setting expiry:
|
4610
|
+
If expiry == 0 or False: Delete "expiry".
|
4611
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4612
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4613
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4507
4614
|
"""
|
4615
|
+
cookie = cookie_dict
|
4616
|
+
if "domain" in cookie:
|
4617
|
+
origin = self.get_origin()
|
4618
|
+
trim_origin = origin.split("://")[-1]
|
4619
|
+
if cookie["domain"] not in origin:
|
4620
|
+
cookie["domain"] = trim_origin
|
4621
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4622
|
+
del cookie["expiry"]
|
4623
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4624
|
+
pass
|
4625
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4626
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4627
|
+
elif expiry:
|
4628
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4508
4629
|
self.driver.add_cookie(cookie_dict)
|
4509
4630
|
|
4510
|
-
def add_cookies(self, cookies):
|
4511
|
-
|
4512
|
-
|
4631
|
+
def add_cookies(self, cookies, expiry=False):
|
4632
|
+
"""
|
4633
|
+
Usage for setting expiry:
|
4634
|
+
If expiry == 0 or False: Delete "expiry".
|
4635
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4636
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4637
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4638
|
+
"""
|
4639
|
+
origin = self.get_origin()
|
4640
|
+
trim_origin = origin.split("://")[-1]
|
4641
|
+
for cookie in cookies:
|
4642
|
+
if "domain" in cookie:
|
4643
|
+
if cookie["domain"] not in origin:
|
4644
|
+
cookie["domain"] = trim_origin
|
4645
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4646
|
+
del cookie["expiry"]
|
4647
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4648
|
+
pass
|
4649
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4650
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4651
|
+
elif expiry:
|
4652
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4653
|
+
self.driver.add_cookie(cookie)
|
4513
4654
|
|
4514
4655
|
def __set_esc_skip(self):
|
4515
4656
|
if hasattr(self, "esc_end") and self.esc_end:
|
@@ -4656,30 +4797,6 @@ class BaseCase(unittest.TestCase):
|
|
4656
4797
|
if hasattr(self.driver, "_is_using_uc") and self.driver._is_using_uc:
|
4657
4798
|
self.driver.uc_open_with_cdp_mode(url)
|
4658
4799
|
else:
|
4659
|
-
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
4660
|
-
if (
|
4661
|
-
(
|
4662
|
-
not self.user_data_dir
|
4663
|
-
or not os.path.exists(self.user_data_dir)
|
4664
|
-
)
|
4665
|
-
and self.browser == "chrome"
|
4666
|
-
):
|
4667
|
-
import tempfile
|
4668
|
-
user_data_dir = os.path.normpath(tempfile.mkdtemp())
|
4669
|
-
self.user_data_dir = user_data_dir
|
4670
|
-
sb_config.user_data_dir = user_data_dir
|
4671
|
-
try:
|
4672
|
-
driver = self.get_new_driver(
|
4673
|
-
user_data_dir=user_data_dir,
|
4674
|
-
undetectable=True,
|
4675
|
-
headless2=True,
|
4676
|
-
)
|
4677
|
-
time.sleep(0.555)
|
4678
|
-
except Exception:
|
4679
|
-
pass
|
4680
|
-
finally:
|
4681
|
-
with suppress(Exception):
|
4682
|
-
driver.quit()
|
4683
4800
|
self.get_new_driver(undetectable=True)
|
4684
4801
|
self.driver.uc_open_with_cdp_mode(url)
|
4685
4802
|
self.cdp = self.driver.cdp
|
@@ -14941,31 +15058,6 @@ class BaseCase(unittest.TestCase):
|
|
14941
15058
|
self.__js_start_time = int(time.time() * 1000.0)
|
14942
15059
|
else:
|
14943
15060
|
# Launch WebDriver for both pytest and pynose
|
14944
|
-
|
14945
|
-
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
14946
|
-
if (
|
14947
|
-
self.undetectable
|
14948
|
-
and (
|
14949
|
-
not self.user_data_dir
|
14950
|
-
or not os.path.exists(self.user_data_dir)
|
14951
|
-
)
|
14952
|
-
and self.browser == "chrome"
|
14953
|
-
):
|
14954
|
-
import tempfile
|
14955
|
-
user_data_dir = os.path.normpath(tempfile.mkdtemp())
|
14956
|
-
self.user_data_dir = user_data_dir
|
14957
|
-
sb_config.user_data_dir = user_data_dir
|
14958
|
-
try:
|
14959
|
-
driver = self.get_new_driver(
|
14960
|
-
user_data_dir=user_data_dir,
|
14961
|
-
headless2=True,
|
14962
|
-
)
|
14963
|
-
time.sleep(0.555)
|
14964
|
-
except Exception:
|
14965
|
-
pass
|
14966
|
-
finally:
|
14967
|
-
with suppress(Exception):
|
14968
|
-
driver.quit()
|
14969
15061
|
self.driver = self.get_new_driver(
|
14970
15062
|
browser=self.browser,
|
14971
15063
|
headless=self.headless,
|
@@ -4,6 +4,7 @@ import os
|
|
4
4
|
import platform
|
5
5
|
import sys
|
6
6
|
import time
|
7
|
+
from contextlib import suppress
|
7
8
|
from seleniumbase import config as sb_config
|
8
9
|
from seleniumbase.fixtures import constants
|
9
10
|
|
@@ -99,6 +100,23 @@ def is_cdp_swap_needed(driver):
|
|
99
100
|
)
|
100
101
|
|
101
102
|
|
103
|
+
def is_chrome_130_or_newer(self, binary_location=None):
|
104
|
+
from seleniumbase.core import detect_b_ver
|
105
|
+
|
106
|
+
"""Due to changes in Chrome-130, UC Mode freezes at start-up
|
107
|
+
unless the user-data-dir already exists and is populated."""
|
108
|
+
with suppress(Exception):
|
109
|
+
if not binary_location:
|
110
|
+
ver = detect_b_ver.get_browser_version_from_os("google-chrome")
|
111
|
+
else:
|
112
|
+
ver = detect_b_ver.get_browser_version_from_binary(
|
113
|
+
binary_location
|
114
|
+
)
|
115
|
+
if ver and len(ver) > 3 and int(ver.split(".")[0]) >= 130:
|
116
|
+
return True
|
117
|
+
return False
|
118
|
+
|
119
|
+
|
102
120
|
def format_exc(exception, message):
|
103
121
|
"""Formats an exception message to make the output cleaner."""
|
104
122
|
from selenium.common.exceptions import ElementNotVisibleException
|
@@ -233,6 +233,7 @@ def Driver(
|
|
233
233
|
wire (bool): Shortcut / Duplicate of "use_wire".
|
234
234
|
pls (str): Shortcut / Duplicate of "page_load_strategy".
|
235
235
|
"""
|
236
|
+
from contextlib import suppress
|
236
237
|
from seleniumbase import config as sb_config
|
237
238
|
from seleniumbase.config import settings
|
238
239
|
from seleniumbase.fixtures import constants
|
@@ -792,12 +793,22 @@ def Driver(
|
|
792
793
|
from seleniumbase.core import browser_launcher
|
793
794
|
|
794
795
|
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
795
|
-
if
|
796
|
+
if (
|
797
|
+
undetectable
|
798
|
+
and (
|
799
|
+
not user_data_dir
|
800
|
+
or not os.path.exists(user_data_dir)
|
801
|
+
or not any(os.scandir(user_data_dir))
|
802
|
+
)
|
803
|
+
and browser == "chrome"
|
804
|
+
and shared_utils.is_chrome_130_or_newer(binary_location)
|
805
|
+
):
|
796
806
|
import tempfile
|
797
807
|
import time
|
798
|
-
|
799
|
-
|
800
|
-
|
808
|
+
if not user_data_dir:
|
809
|
+
user_data_dir = (
|
810
|
+
os.path.normpath(tempfile.mkdtemp())
|
811
|
+
)
|
801
812
|
try:
|
802
813
|
decoy_driver = browser_launcher.get_driver(
|
803
814
|
browser_name=browser_name,
|
@@ -840,12 +851,12 @@ def Driver(
|
|
840
851
|
host_resolver_rules=host_resolver_rules,
|
841
852
|
block_images=block_images,
|
842
853
|
do_not_track=do_not_track,
|
843
|
-
chromium_arg=
|
854
|
+
chromium_arg="decoy",
|
844
855
|
firefox_arg=firefox_arg,
|
845
856
|
firefox_pref=firefox_pref,
|
846
857
|
user_data_dir=user_data_dir,
|
847
|
-
extension_zip=
|
848
|
-
extension_dir=
|
858
|
+
extension_zip=None,
|
859
|
+
extension_dir=None,
|
849
860
|
disable_features=disable_features,
|
850
861
|
binary_location=binary_location,
|
851
862
|
driver_version=driver_version,
|
@@ -859,14 +870,13 @@ def Driver(
|
|
859
870
|
device_pixel_ratio=d_p_r,
|
860
871
|
browser=browser_name,
|
861
872
|
)
|
862
|
-
time.sleep(0.
|
873
|
+
time.sleep(0.2)
|
863
874
|
except Exception:
|
864
875
|
pass
|
865
876
|
finally:
|
866
|
-
|
877
|
+
with suppress(Exception):
|
867
878
|
decoy_driver.quit()
|
868
|
-
|
869
|
-
pass
|
879
|
+
time.sleep(0.1)
|
870
880
|
|
871
881
|
driver = browser_launcher.get_driver(
|
872
882
|
browser_name=browser_name,
|
@@ -1212,30 +1212,6 @@ def SB(
|
|
1212
1212
|
if not sb_config.multi_proxy:
|
1213
1213
|
proxy_helper.remove_proxy_zip_if_present()
|
1214
1214
|
start_time = time.time()
|
1215
|
-
saved_headless2 = headless2
|
1216
|
-
|
1217
|
-
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
1218
|
-
if undetectable and not user_data_dir and browser == "chrome":
|
1219
|
-
import tempfile
|
1220
|
-
user_data_dir = (
|
1221
|
-
os.path.normpath(tempfile.mkdtemp())
|
1222
|
-
)
|
1223
|
-
sb.user_data_dir = user_data_dir
|
1224
|
-
sb_config.user_data_dir = user_data_dir
|
1225
|
-
try:
|
1226
|
-
decoy = sb
|
1227
|
-
decoy.headless2 = True
|
1228
|
-
decoy.setUp()
|
1229
|
-
decoy.sleep(0.555)
|
1230
|
-
except Exception:
|
1231
|
-
pass
|
1232
|
-
finally:
|
1233
|
-
try:
|
1234
|
-
decoy.tearDown()
|
1235
|
-
except Exception:
|
1236
|
-
pass
|
1237
|
-
sb.headless2 = saved_headless2
|
1238
|
-
|
1239
1215
|
sb.setUp()
|
1240
1216
|
test_passed = True # This can change later
|
1241
1217
|
teardown_exception = None
|
@@ -0,0 +1 @@
|
|
1
|
+
from seleniumbase.undetected.cdp_driver import cdp_util # noqa
|