seleniumbase 4.32.1__py3-none-any.whl → 4.32.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- seleniumbase/__version__.py +1 -1
- seleniumbase/fixtures/base_case.py +87 -49
- seleniumbase/plugins/driver_manager.py +13 -4
- 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 +317 -0
- seleniumbase/undetected/cdp_driver/config.py +322 -0
- seleniumbase/undetected/cdp_driver/connection.py +625 -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.2.dist-info}/METADATA +1 -1
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.2.dist-info}/RECORD +18 -10
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.2.dist-info}/LICENSE +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.2.dist-info}/WHEEL +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.2.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.2.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.2"
|
@@ -4090,6 +4090,88 @@ 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
|
+
):
|
4103
|
+
import tempfile
|
4104
|
+
if not user_data_dir:
|
4105
|
+
user_data_dir = os.path.normpath(tempfile.mkdtemp())
|
4106
|
+
self.user_data_dir = user_data_dir
|
4107
|
+
sb_config.user_data_dir = user_data_dir
|
4108
|
+
try:
|
4109
|
+
decoy_driver = browser_launcher.get_driver(
|
4110
|
+
browser_name=browser_name,
|
4111
|
+
headless=headless,
|
4112
|
+
locale_code=locale_code,
|
4113
|
+
use_grid=use_grid,
|
4114
|
+
protocol=protocol,
|
4115
|
+
servername=servername,
|
4116
|
+
port=port,
|
4117
|
+
proxy_string=proxy_string,
|
4118
|
+
proxy_bypass_list=proxy_bypass_list,
|
4119
|
+
proxy_pac_url=proxy_pac_url,
|
4120
|
+
multi_proxy=multi_proxy,
|
4121
|
+
user_agent=user_agent,
|
4122
|
+
cap_file=cap_file,
|
4123
|
+
cap_string=cap_string,
|
4124
|
+
recorder_ext=recorder_ext,
|
4125
|
+
disable_cookies=disable_cookies,
|
4126
|
+
disable_js=disable_js,
|
4127
|
+
disable_csp=disable_csp,
|
4128
|
+
enable_ws=enable_ws,
|
4129
|
+
enable_sync=enable_sync,
|
4130
|
+
use_auto_ext=use_auto_ext,
|
4131
|
+
undetectable=undetectable,
|
4132
|
+
uc_cdp_events=uc_cdp_events,
|
4133
|
+
uc_subprocess=uc_subprocess,
|
4134
|
+
log_cdp_events=log_cdp_events,
|
4135
|
+
no_sandbox=no_sandbox,
|
4136
|
+
disable_gpu=disable_gpu,
|
4137
|
+
headless1=headless1,
|
4138
|
+
headless2=True,
|
4139
|
+
incognito=incognito,
|
4140
|
+
guest_mode=guest_mode,
|
4141
|
+
dark_mode=dark_mode,
|
4142
|
+
devtools=devtools,
|
4143
|
+
remote_debug=remote_debug,
|
4144
|
+
enable_3d_apis=enable_3d_apis,
|
4145
|
+
swiftshader=swiftshader,
|
4146
|
+
ad_block_on=ad_block_on,
|
4147
|
+
host_resolver_rules=host_resolver_rules,
|
4148
|
+
block_images=block_images,
|
4149
|
+
do_not_track=do_not_track,
|
4150
|
+
chromium_arg=chromium_arg,
|
4151
|
+
firefox_arg=firefox_arg,
|
4152
|
+
firefox_pref=firefox_pref,
|
4153
|
+
user_data_dir=user_data_dir,
|
4154
|
+
extension_zip=extension_zip,
|
4155
|
+
extension_dir=extension_dir,
|
4156
|
+
disable_features=disable_features,
|
4157
|
+
binary_location=binary_location,
|
4158
|
+
driver_version=driver_version,
|
4159
|
+
page_load_strategy=page_load_strategy,
|
4160
|
+
use_wire=use_wire,
|
4161
|
+
external_pdf=external_pdf,
|
4162
|
+
test_id=test_id,
|
4163
|
+
mobile_emulator=is_mobile,
|
4164
|
+
device_width=d_width,
|
4165
|
+
device_height=d_height,
|
4166
|
+
device_pixel_ratio=d_p_r,
|
4167
|
+
browser=browser_name,
|
4168
|
+
)
|
4169
|
+
time.sleep(0.555)
|
4170
|
+
except Exception:
|
4171
|
+
pass
|
4172
|
+
finally:
|
4173
|
+
with suppress(Exception):
|
4174
|
+
decoy_driver.quit()
|
4093
4175
|
# Launch a web browser
|
4094
4176
|
new_driver = browser_launcher.get_driver(
|
4095
4177
|
browser_name=browser_name,
|
@@ -4435,7 +4517,12 @@ class BaseCase(unittest.TestCase):
|
|
4435
4517
|
"""Loads the page cookies from the "saved_cookies" folder."""
|
4436
4518
|
cookies = self.get_saved_cookies(name)
|
4437
4519
|
self.wait_for_ready_state_complete()
|
4520
|
+
origin = self.get_origin()
|
4521
|
+
trim_origin = origin.split("://")[-1]
|
4438
4522
|
for cookie in cookies:
|
4523
|
+
if "domain" in cookie:
|
4524
|
+
if cookie["domain"] not in origin:
|
4525
|
+
cookie["domain"] = trim_origin
|
4439
4526
|
if "expiry" in cookie:
|
4440
4527
|
del cookie["expiry"]
|
4441
4528
|
self.driver.add_cookie(cookie)
|
@@ -4656,30 +4743,6 @@ class BaseCase(unittest.TestCase):
|
|
4656
4743
|
if hasattr(self.driver, "_is_using_uc") and self.driver._is_using_uc:
|
4657
4744
|
self.driver.uc_open_with_cdp_mode(url)
|
4658
4745
|
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
4746
|
self.get_new_driver(undetectable=True)
|
4684
4747
|
self.driver.uc_open_with_cdp_mode(url)
|
4685
4748
|
self.cdp = self.driver.cdp
|
@@ -14941,31 +15004,6 @@ class BaseCase(unittest.TestCase):
|
|
14941
15004
|
self.__js_start_time = int(time.time() * 1000.0)
|
14942
15005
|
else:
|
14943
15006
|
# 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
15007
|
self.driver = self.get_new_driver(
|
14970
15008
|
browser=self.browser,
|
14971
15009
|
headless=self.headless,
|
@@ -792,12 +792,21 @@ def Driver(
|
|
792
792
|
from seleniumbase.core import browser_launcher
|
793
793
|
|
794
794
|
# Fix Chrome-130 issues by creating a user-data-dir in advance
|
795
|
-
if
|
795
|
+
if (
|
796
|
+
undetectable
|
797
|
+
and (
|
798
|
+
not user_data_dir
|
799
|
+
or not os.path.exists(user_data_dir)
|
800
|
+
or not any(os.scandir(user_data_dir))
|
801
|
+
)
|
802
|
+
and browser == "chrome"
|
803
|
+
):
|
796
804
|
import tempfile
|
797
805
|
import time
|
798
|
-
|
799
|
-
|
800
|
-
|
806
|
+
if not user_data_dir:
|
807
|
+
user_data_dir = (
|
808
|
+
os.path.normpath(tempfile.mkdtemp())
|
809
|
+
)
|
801
810
|
try:
|
802
811
|
decoy_driver = browser_launcher.get_driver(
|
803
812
|
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
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import warnings as _warnings
|
2
|
+
from collections.abc import Mapping as _Mapping, Sequence as _Sequence
|
3
|
+
import logging
|
4
|
+
|
5
|
+
__logger__ = logging.getLogger(__name__)
|
6
|
+
__all__ = ["cdict", "ContraDict"]
|
7
|
+
|
8
|
+
|
9
|
+
def cdict(*args, **kwargs):
|
10
|
+
"""Factory function"""
|
11
|
+
return ContraDict(*args, **kwargs)
|
12
|
+
|
13
|
+
|
14
|
+
class ContraDict(dict):
|
15
|
+
"""
|
16
|
+
Directly inherited from dict.
|
17
|
+
Accessible by attribute. o.x == o['x']
|
18
|
+
This works also for all corner cases.
|
19
|
+
Native json.dumps and json.loads work with it.
|
20
|
+
|
21
|
+
Names like "keys", "update", "values" etc won't overwrite the methods,
|
22
|
+
but will just be available using dict lookup notation obj['items']
|
23
|
+
instead of obj.items.
|
24
|
+
|
25
|
+
All key names are converted to snake_case.
|
26
|
+
Hyphen's (-), dot's (.) or whitespaces are replaced by underscore (_).
|
27
|
+
Autocomplete works even if the objects comes from a list.
|
28
|
+
Recursive action. Dict assignments will be converted too.
|
29
|
+
"""
|
30
|
+
__module__ = None
|
31
|
+
|
32
|
+
def __init__(self, *args, **kwargs):
|
33
|
+
super().__init__()
|
34
|
+
silent = kwargs.pop("silent", False)
|
35
|
+
_ = dict(*args, **kwargs)
|
36
|
+
|
37
|
+
super().__setattr__("__dict__", self)
|
38
|
+
for k, v in _.items():
|
39
|
+
_check_key(k, self, False, silent)
|
40
|
+
super().__setitem__(k, _wrap(self.__class__, v))
|
41
|
+
|
42
|
+
def __setitem__(self, key, value):
|
43
|
+
super().__setitem__(key, _wrap(self.__class__, value))
|
44
|
+
|
45
|
+
def __setattr__(self, key, value):
|
46
|
+
super().__setitem__(key, _wrap(self.__class__, value))
|
47
|
+
|
48
|
+
def __getattribute__(self, attribute):
|
49
|
+
if attribute in self:
|
50
|
+
return self[attribute]
|
51
|
+
if not _check_key(attribute, self, True, silent=True):
|
52
|
+
return getattr(super(), attribute)
|
53
|
+
return object.__getattribute__(self, attribute)
|
54
|
+
|
55
|
+
|
56
|
+
def _wrap(cls, v):
|
57
|
+
if isinstance(v, _Mapping):
|
58
|
+
v = cls(v)
|
59
|
+
elif isinstance(v, _Sequence) and not isinstance(
|
60
|
+
v, (str, bytes, bytearray, set, tuple)
|
61
|
+
):
|
62
|
+
v = list([_wrap(cls, x) for x in v])
|
63
|
+
return v
|
64
|
+
|
65
|
+
|
66
|
+
_warning_names = (
|
67
|
+
"items",
|
68
|
+
"keys",
|
69
|
+
"values",
|
70
|
+
"update",
|
71
|
+
"clear",
|
72
|
+
"copy",
|
73
|
+
"fromkeys",
|
74
|
+
"get",
|
75
|
+
"items",
|
76
|
+
"keys",
|
77
|
+
"pop",
|
78
|
+
"popitem",
|
79
|
+
"setdefault",
|
80
|
+
"update",
|
81
|
+
"values",
|
82
|
+
"class",
|
83
|
+
)
|
84
|
+
|
85
|
+
_warning_names_message = """\n\
|
86
|
+
While creating a ContraDict object, a key offending key name '{0}'
|
87
|
+
has been found, which might behave unexpected.
|
88
|
+
You will only be able to look it up using key,
|
89
|
+
eg. myobject['{0}']. myobject.{0} will not work with that name."""
|
90
|
+
|
91
|
+
|
92
|
+
def _check_key(
|
93
|
+
key: str, mapping: _Mapping, boolean: bool = False, silent=False
|
94
|
+
):
|
95
|
+
"""Checks `key` and warns if needed.
|
96
|
+
:param key:
|
97
|
+
:param boolean: return True or False instead of passthrough
|
98
|
+
"""
|
99
|
+
e = None
|
100
|
+
if not isinstance(key, (str,)):
|
101
|
+
if boolean:
|
102
|
+
return True
|
103
|
+
return key
|
104
|
+
if key.lower() in _warning_names or any(_ in key for _ in ("-", ".")):
|
105
|
+
if not silent:
|
106
|
+
_warnings.warn(_warning_names_message.format(key))
|
107
|
+
e = True
|
108
|
+
if not boolean:
|
109
|
+
return key
|
110
|
+
return not e
|