seleniumbase 4.34.8__py3-none-any.whl → 4.36.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seleniumbase/__init__.py +2 -0
- seleniumbase/__version__.py +1 -1
- seleniumbase/config/proxy_list.py +2 -2
- seleniumbase/console_scripts/sb_mkdir.py +3 -0
- seleniumbase/core/browser_launcher.py +160 -38
- seleniumbase/core/detect_b_ver.py +12 -13
- seleniumbase/core/proxy_helper.py +7 -5
- seleniumbase/core/sb_cdp.py +328 -91
- seleniumbase/core/sb_driver.py +7 -0
- seleniumbase/extensions/ad_block.zip +0 -0
- seleniumbase/extensions/disable_csp.zip +0 -0
- seleniumbase/fixtures/base_case.py +104 -19
- seleniumbase/fixtures/js_utils.py +33 -9
- seleniumbase/plugins/base_plugin.py +12 -15
- seleniumbase/plugins/driver_manager.py +19 -2
- seleniumbase/plugins/pytest_plugin.py +3 -0
- seleniumbase/plugins/sb_manager.py +18 -1
- seleniumbase/plugins/selenium_plugin.py +1 -0
- seleniumbase/undetected/__init__.py +38 -17
- seleniumbase/undetected/cdp_driver/__init__.py +2 -0
- seleniumbase/undetected/cdp_driver/browser.py +16 -10
- seleniumbase/undetected/cdp_driver/cdp_util.py +135 -11
- seleniumbase/undetected/cdp_driver/config.py +10 -0
- seleniumbase/undetected/cdp_driver/connection.py +1 -1
- seleniumbase/undetected/cdp_driver/tab.py +37 -4
- seleniumbase/undetected/webelement.py +3 -2
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info}/METADATA +30 -28
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info}/RECORD +32 -32
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info}/WHEEL +1 -1
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info/licenses}/LICENSE +0 -0
- {seleniumbase-4.34.8.dist-info → seleniumbase-4.36.2.dist-info}/top_level.txt +0 -0
seleniumbase/core/sb_driver.py
CHANGED
@@ -51,6 +51,13 @@ class DriverMethods():
|
|
51
51
|
element = self.locator(selector, by=by)
|
52
52
|
return element.get_attribute(attribute)
|
53
53
|
|
54
|
+
def get_parent(self, element):
|
55
|
+
if self.__is_cdp_swap_needed():
|
56
|
+
return self.driver.cdp.get_parent(element)
|
57
|
+
if isinstance(element, str):
|
58
|
+
element = self.locator(element)
|
59
|
+
return element.find_element(by="xpath", value="..")
|
60
|
+
|
54
61
|
def get_current_url(self):
|
55
62
|
if self.__is_cdp_swap_needed():
|
56
63
|
current_url = self.driver.cdp.get_current_url()
|
Binary file
|
Binary file
|
@@ -1164,6 +1164,9 @@ class BaseCase(unittest.TestCase):
|
|
1164
1164
|
"""Alternative to self.driver.find_element_by_*(SELECTOR).submit()"""
|
1165
1165
|
self.__check_scope()
|
1166
1166
|
selector, by = self.__recalculate_selector(selector, by)
|
1167
|
+
if self.__is_cdp_swap_needed():
|
1168
|
+
self.cdp.submit(selector)
|
1169
|
+
return
|
1167
1170
|
element = self.wait_for_element_clickable(
|
1168
1171
|
selector, by=by, timeout=settings.SMALL_TIMEOUT
|
1169
1172
|
)
|
@@ -1454,6 +1457,8 @@ class BaseCase(unittest.TestCase):
|
|
1454
1457
|
|
1455
1458
|
def is_text_visible(self, text, selector="body", by="css selector"):
|
1456
1459
|
"""Returns whether the text substring is visible in the element."""
|
1460
|
+
if self.__is_cdp_swap_needed():
|
1461
|
+
return self.cdp.is_text_visible(text, selector)
|
1457
1462
|
self.wait_for_ready_state_complete()
|
1458
1463
|
time.sleep(0.01)
|
1459
1464
|
selector, by = self.__recalculate_selector(selector, by)
|
@@ -1464,6 +1469,8 @@ class BaseCase(unittest.TestCase):
|
|
1464
1469
|
def is_exact_text_visible(self, text, selector="body", by="css selector"):
|
1465
1470
|
"""Returns whether the text is exactly equal to the element text.
|
1466
1471
|
(Leading and trailing whitespace is ignored in the verification.)"""
|
1472
|
+
if self.__is_cdp_swap_needed():
|
1473
|
+
return self.cdp.is_exact_text_visible(text, selector)
|
1467
1474
|
self.wait_for_ready_state_complete()
|
1468
1475
|
time.sleep(0.01)
|
1469
1476
|
selector, by = self.__recalculate_selector(selector, by)
|
@@ -2072,6 +2079,19 @@ class BaseCase(unittest.TestCase):
|
|
2072
2079
|
return
|
2073
2080
|
self.set_attributes('[target="_blank"]', "target", "_self")
|
2074
2081
|
|
2082
|
+
def get_parent(self, element, by="css selector", timeout=None):
|
2083
|
+
"""Returns the parent element.
|
2084
|
+
If element is a string, then finds element first via selector."""
|
2085
|
+
if self.__is_cdp_swap_needed():
|
2086
|
+
return self.cdp.get_parent(element)
|
2087
|
+
if isinstance(element, str):
|
2088
|
+
if not timeout:
|
2089
|
+
timeout = settings.LARGE_TIMEOUT
|
2090
|
+
element = self.wait_for_element_present(
|
2091
|
+
element, by=by, timeout=timeout
|
2092
|
+
)
|
2093
|
+
return element.find_element(by="xpath", value="..")
|
2094
|
+
|
2075
2095
|
def get_property(
|
2076
2096
|
self, selector, property, by="css selector", timeout=None
|
2077
2097
|
):
|
@@ -3256,7 +3276,7 @@ class BaseCase(unittest.TestCase):
|
|
3256
3276
|
html_string = "\n".join(new_lines)
|
3257
3277
|
soup = self.get_beautiful_soup(html_string)
|
3258
3278
|
found_base = False
|
3259
|
-
links = soup.
|
3279
|
+
links = soup.find_all("link")
|
3260
3280
|
href = None
|
3261
3281
|
for link in links:
|
3262
3282
|
if link.get("rel") == ["canonical"] and link.get("href"):
|
@@ -3272,7 +3292,7 @@ class BaseCase(unittest.TestCase):
|
|
3272
3292
|
"<head>", '<head><base href="%s">' % href
|
3273
3293
|
)
|
3274
3294
|
elif not found_base:
|
3275
|
-
bases = soup.
|
3295
|
+
bases = soup.find_all("base")
|
3276
3296
|
for base in bases:
|
3277
3297
|
if base.get("href"):
|
3278
3298
|
href = base.get("href")
|
@@ -3280,7 +3300,7 @@ class BaseCase(unittest.TestCase):
|
|
3280
3300
|
html_string = html_string.replace('base: "."', 'base: "%s"' % href)
|
3281
3301
|
|
3282
3302
|
soup = self.get_beautiful_soup(html_string)
|
3283
|
-
scripts = soup.
|
3303
|
+
scripts = soup.find_all("script")
|
3284
3304
|
for script in scripts:
|
3285
3305
|
if script.get("type") != "application/json":
|
3286
3306
|
html_string = html_string.replace(str(script), "")
|
@@ -3879,6 +3899,9 @@ class BaseCase(unittest.TestCase):
|
|
3879
3899
|
|
3880
3900
|
def open_new_window(self, switch_to=True):
|
3881
3901
|
"""Opens a new browser tab/window and switches to it by default."""
|
3902
|
+
if self.__is_cdp_swap_needed():
|
3903
|
+
self.cdp.open_new_tab(switch_to=switch_to)
|
3904
|
+
return
|
3882
3905
|
self.wait_for_ready_state_complete()
|
3883
3906
|
if switch_to:
|
3884
3907
|
try:
|
@@ -3901,6 +3924,9 @@ class BaseCase(unittest.TestCase):
|
|
3901
3924
|
timeout = settings.SMALL_TIMEOUT
|
3902
3925
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
3903
3926
|
timeout = self.__get_new_timeout(timeout)
|
3927
|
+
if self.__is_cdp_swap_needed() and not isinstance(window, str):
|
3928
|
+
self.cdp.switch_to_tab(window)
|
3929
|
+
return
|
3904
3930
|
page_actions.switch_to_window(self.driver, window, timeout)
|
3905
3931
|
|
3906
3932
|
def switch_to_default_window(self):
|
@@ -3967,6 +3993,7 @@ class BaseCase(unittest.TestCase):
|
|
3967
3993
|
d_width=None,
|
3968
3994
|
d_height=None,
|
3969
3995
|
d_p_r=None,
|
3996
|
+
**kwargs,
|
3970
3997
|
):
|
3971
3998
|
"""This method spins up an extra browser for tests that require
|
3972
3999
|
more than one. The first browser is already provided by tests
|
@@ -4055,6 +4082,11 @@ class BaseCase(unittest.TestCase):
|
|
4055
4082
|
" for examples!)"
|
4056
4083
|
% (browserstack_ref, sauce_labs_ref)
|
4057
4084
|
)
|
4085
|
+
shortcuts = ["dark", "guest", "locale", "mobile", "pls", "uc", "wire"]
|
4086
|
+
if kwargs:
|
4087
|
+
for key in kwargs.keys():
|
4088
|
+
if key not in shortcuts:
|
4089
|
+
raise TypeError("Unexpected keyword argument '%s'" % key)
|
4058
4090
|
if browser is None:
|
4059
4091
|
browser = self.browser
|
4060
4092
|
browser_name = browser
|
@@ -4062,6 +4094,8 @@ class BaseCase(unittest.TestCase):
|
|
4062
4094
|
headless = self.headless
|
4063
4095
|
if locale_code is None:
|
4064
4096
|
locale_code = self.locale_code
|
4097
|
+
if "locale" in kwargs and not locale_code:
|
4098
|
+
locale_code = kwargs["locale"]
|
4065
4099
|
if protocol is None:
|
4066
4100
|
protocol = self.protocol
|
4067
4101
|
if servername is None:
|
@@ -4104,6 +4138,8 @@ class BaseCase(unittest.TestCase):
|
|
4104
4138
|
uc_cdp_events = self.uc_cdp_events
|
4105
4139
|
if uc_subprocess is None:
|
4106
4140
|
uc_subprocess = self.uc_subprocess
|
4141
|
+
if "uc" in kwargs and not undetectable:
|
4142
|
+
undetectable = kwargs["uc"]
|
4107
4143
|
if log_cdp_events is None:
|
4108
4144
|
log_cdp_events = self.log_cdp_events
|
4109
4145
|
if no_sandbox is None:
|
@@ -4118,8 +4154,12 @@ class BaseCase(unittest.TestCase):
|
|
4118
4154
|
incognito = self.incognito
|
4119
4155
|
if guest_mode is None:
|
4120
4156
|
guest_mode = self.guest_mode
|
4157
|
+
if "guest" in kwargs and not guest_mode:
|
4158
|
+
guest_mode = kwargs["guest"]
|
4121
4159
|
if dark_mode is None:
|
4122
4160
|
dark_mode = self.dark_mode
|
4161
|
+
if "dark" in kwargs and not dark_mode:
|
4162
|
+
dark_mode = kwargs["dark"]
|
4123
4163
|
if devtools is None:
|
4124
4164
|
devtools = self.devtools
|
4125
4165
|
if remote_debug is None:
|
@@ -4156,8 +4196,12 @@ class BaseCase(unittest.TestCase):
|
|
4156
4196
|
driver_version = self.driver_version
|
4157
4197
|
if page_load_strategy is None:
|
4158
4198
|
page_load_strategy = self.page_load_strategy
|
4199
|
+
if "pls" in kwargs and not page_load_strategy:
|
4200
|
+
page_load_strategy = kwargs["pls"]
|
4159
4201
|
if use_wire is None:
|
4160
4202
|
use_wire = self.use_wire
|
4203
|
+
if "wire" in kwargs and not use_wire:
|
4204
|
+
use_wire = kwargs["wire"]
|
4161
4205
|
if external_pdf is None:
|
4162
4206
|
external_pdf = self.external_pdf
|
4163
4207
|
test_id = self.__get_test_id()
|
@@ -4167,6 +4211,8 @@ class BaseCase(unittest.TestCase):
|
|
4167
4211
|
cap_string = self.cap_string
|
4168
4212
|
if is_mobile is None:
|
4169
4213
|
is_mobile = self.mobile_emulator
|
4214
|
+
if "mobile" in kwargs and not is_mobile:
|
4215
|
+
is_mobile = kwargs["mobile"]
|
4170
4216
|
if d_width is None:
|
4171
4217
|
d_width = self.__device_width
|
4172
4218
|
if d_height is None:
|
@@ -8047,10 +8093,6 @@ class BaseCase(unittest.TestCase):
|
|
8047
8093
|
else:
|
8048
8094
|
found = False
|
8049
8095
|
message = entry["message"]
|
8050
|
-
if message.count(" - Failed to load resource") == 1:
|
8051
|
-
message = message.split(
|
8052
|
-
" - Failed to load resource"
|
8053
|
-
)[0]
|
8054
8096
|
for substring in exclude:
|
8055
8097
|
substring = str(substring)
|
8056
8098
|
if (
|
@@ -8068,7 +8110,30 @@ class BaseCase(unittest.TestCase):
|
|
8068
8110
|
u_c_t_e = " Uncaught TypeError: "
|
8069
8111
|
if f_t_l_r in errors[n]["message"]:
|
8070
8112
|
url = errors[n]["message"].split(f_t_l_r)[0]
|
8071
|
-
|
8113
|
+
if "status of 400" in errors[n]["message"]:
|
8114
|
+
errors[n] = {"Error 400 (Bad Request)": url}
|
8115
|
+
elif "status of 401" in errors[n]["message"]:
|
8116
|
+
errors[n] = {"Error 401 (Unauthorized)": url}
|
8117
|
+
elif "status of 402" in errors[n]["message"]:
|
8118
|
+
errors[n] = {"Error 402 (Payment Required)": url}
|
8119
|
+
elif "status of 403" in errors[n]["message"]:
|
8120
|
+
errors[n] = {"Error 403 (Forbidden)": url}
|
8121
|
+
elif "status of 404" in errors[n]["message"]:
|
8122
|
+
errors[n] = {"Error 404 (Not Found)": url}
|
8123
|
+
elif "status of 405" in errors[n]["message"]:
|
8124
|
+
errors[n] = {"Error 405 (Method Not Allowed)": url}
|
8125
|
+
elif "status of 406" in errors[n]["message"]:
|
8126
|
+
errors[n] = {"Error 406 (Not Acceptable)": url}
|
8127
|
+
elif "status of 407" in errors[n]["message"]:
|
8128
|
+
errors[n] = {"Error 407 (Proxy Auth Required)": url}
|
8129
|
+
elif "status of 408" in errors[n]["message"]:
|
8130
|
+
errors[n] = {"Error 408 (Request Timeout)": url}
|
8131
|
+
elif "status of 409" in errors[n]["message"]:
|
8132
|
+
errors[n] = {"Error 409 (Conflict)": url}
|
8133
|
+
elif "status of 410" in errors[n]["message"]:
|
8134
|
+
errors[n] = {"Error 410 (Gone)": url}
|
8135
|
+
else:
|
8136
|
+
errors[n] = {"Failed to load resource": url}
|
8072
8137
|
elif u_c_s_e in errors[n]["message"]:
|
8073
8138
|
url = errors[n]["message"].split(u_c_s_e)[0]
|
8074
8139
|
error = errors[n]["message"].split(u_c_s_e)[1]
|
@@ -8758,6 +8823,9 @@ class BaseCase(unittest.TestCase):
|
|
8758
8823
|
self.__check_scope()
|
8759
8824
|
if not self.__is_valid_storage_url():
|
8760
8825
|
raise WebDriverException("Local Storage is not available here!")
|
8826
|
+
if self.__is_cdp_swap_needed():
|
8827
|
+
self.cdp.set_local_storage_item(key, value)
|
8828
|
+
return
|
8761
8829
|
self.execute_script(
|
8762
8830
|
"window.localStorage.setItem('{}', '{}');".format(key, value)
|
8763
8831
|
)
|
@@ -8766,6 +8834,8 @@ class BaseCase(unittest.TestCase):
|
|
8766
8834
|
self.__check_scope()
|
8767
8835
|
if not self.__is_valid_storage_url():
|
8768
8836
|
raise WebDriverException("Local Storage is not available here!")
|
8837
|
+
if self.__is_cdp_swap_needed():
|
8838
|
+
return self.cdp.get_local_storage_item(key)
|
8769
8839
|
return self.execute_script(
|
8770
8840
|
"return window.localStorage.getItem('{}');".format(key)
|
8771
8841
|
)
|
@@ -8817,6 +8887,9 @@ class BaseCase(unittest.TestCase):
|
|
8817
8887
|
self.__check_scope()
|
8818
8888
|
if not self.__is_valid_storage_url():
|
8819
8889
|
raise WebDriverException("Session Storage is not available here!")
|
8890
|
+
if self.__is_cdp_swap_needed():
|
8891
|
+
self.cdp.set_session_storage_item(key, value)
|
8892
|
+
return
|
8820
8893
|
self.execute_script(
|
8821
8894
|
"window.sessionStorage.setItem('{}', '{}');".format(key, value)
|
8822
8895
|
)
|
@@ -8825,6 +8898,8 @@ class BaseCase(unittest.TestCase):
|
|
8825
8898
|
self.__check_scope()
|
8826
8899
|
if not self.__is_valid_storage_url():
|
8827
8900
|
raise WebDriverException("Session Storage is not available here!")
|
8901
|
+
if self.__is_cdp_swap_needed():
|
8902
|
+
return self.cdp.get_session_storage_item(key)
|
8828
8903
|
return self.execute_script(
|
8829
8904
|
"return window.sessionStorage.getItem('{}');".format(key)
|
8830
8905
|
)
|
@@ -9107,7 +9182,7 @@ class BaseCase(unittest.TestCase):
|
|
9107
9182
|
original_selector = selector
|
9108
9183
|
selector, by = self.__recalculate_selector(selector, by)
|
9109
9184
|
if self.__is_cdp_swap_needed():
|
9110
|
-
self.cdp.
|
9185
|
+
self.cdp.wait_for_element_absent(selector, timeout=timeout)
|
9111
9186
|
return True
|
9112
9187
|
return page_actions.wait_for_element_absent(
|
9113
9188
|
self.driver,
|
@@ -9268,7 +9343,8 @@ class BaseCase(unittest.TestCase):
|
|
9268
9343
|
"bottom_left", "bottom_center", "bottom_right"]
|
9269
9344
|
max_messages: The limit of concurrent messages to display."""
|
9270
9345
|
self.__check_scope()
|
9271
|
-
self.
|
9346
|
+
if not self.__is_cdp_swap_needed():
|
9347
|
+
self._check_browser()
|
9272
9348
|
if not theme:
|
9273
9349
|
theme = "default" # "flat"
|
9274
9350
|
if not location:
|
@@ -9295,7 +9371,8 @@ class BaseCase(unittest.TestCase):
|
|
9295
9371
|
You can also post messages by using =>
|
9296
9372
|
self.execute_script('Messenger().post("My Message")') """
|
9297
9373
|
self.__check_scope()
|
9298
|
-
self.
|
9374
|
+
if not self.__is_cdp_swap_needed():
|
9375
|
+
self._check_browser()
|
9299
9376
|
if style not in ["info", "success", "error"]:
|
9300
9377
|
style = "info"
|
9301
9378
|
if not duration:
|
@@ -9566,7 +9643,7 @@ class BaseCase(unittest.TestCase):
|
|
9566
9643
|
self.assert_elements_present(selector, by=by, timeout=timeout)
|
9567
9644
|
return True
|
9568
9645
|
if self.__is_cdp_swap_needed():
|
9569
|
-
self.cdp.assert_element_present(selector)
|
9646
|
+
self.cdp.assert_element_present(selector, timeout=timeout)
|
9570
9647
|
return True
|
9571
9648
|
if self.__is_shadow_selector(selector):
|
9572
9649
|
self.__assert_shadow_element_present(selector)
|
@@ -9643,7 +9720,7 @@ class BaseCase(unittest.TestCase):
|
|
9643
9720
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
9644
9721
|
timeout = self.__get_new_timeout(timeout)
|
9645
9722
|
if self.__is_cdp_swap_needed():
|
9646
|
-
self.cdp.assert_element(selector)
|
9723
|
+
self.cdp.assert_element(selector, timeout=timeout)
|
9647
9724
|
return True
|
9648
9725
|
if isinstance(selector, list):
|
9649
9726
|
self.assert_elements(selector, by=by, timeout=timeout)
|
@@ -9936,7 +10013,7 @@ class BaseCase(unittest.TestCase):
|
|
9936
10013
|
messenger_post, selector, by
|
9937
10014
|
)
|
9938
10015
|
elif self.__is_cdp_swap_needed():
|
9939
|
-
self.cdp.assert_text(text, selector)
|
10016
|
+
self.cdp.assert_text(text, selector, timeout=timeout)
|
9940
10017
|
return True
|
9941
10018
|
elif not self.is_connected():
|
9942
10019
|
self.connect()
|
@@ -9986,7 +10063,7 @@ class BaseCase(unittest.TestCase):
|
|
9986
10063
|
original_selector = selector
|
9987
10064
|
selector, by = self.__recalculate_selector(selector, by)
|
9988
10065
|
if self.__is_cdp_swap_needed():
|
9989
|
-
self.cdp.assert_exact_text(text, selector)
|
10066
|
+
self.cdp.assert_exact_text(text, selector, timeout=timeout)
|
9990
10067
|
return True
|
9991
10068
|
if self.__is_shadow_selector(selector):
|
9992
10069
|
self.__assert_exact_shadow_text_visible(text, selector, timeout)
|
@@ -10226,6 +10303,9 @@ class BaseCase(unittest.TestCase):
|
|
10226
10303
|
timeout = self.__get_new_timeout(timeout)
|
10227
10304
|
original_selector = selector
|
10228
10305
|
selector, by = self.__recalculate_selector(selector, by)
|
10306
|
+
if self.__is_cdp_swap_needed():
|
10307
|
+
self.cdp.wait_for_element_absent(selector, timeout=timeout)
|
10308
|
+
return True
|
10229
10309
|
return page_actions.wait_for_element_absent(
|
10230
10310
|
self.driver,
|
10231
10311
|
selector,
|
@@ -10248,7 +10328,7 @@ class BaseCase(unittest.TestCase):
|
|
10248
10328
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
10249
10329
|
timeout = self.__get_new_timeout(timeout)
|
10250
10330
|
if self.__is_cdp_swap_needed():
|
10251
|
-
self.cdp.assert_element_absent(selector)
|
10331
|
+
self.cdp.assert_element_absent(selector, timeout=timeout)
|
10252
10332
|
return True
|
10253
10333
|
self.wait_for_element_absent(selector, by=by, timeout=timeout)
|
10254
10334
|
return True
|
@@ -10269,7 +10349,7 @@ class BaseCase(unittest.TestCase):
|
|
10269
10349
|
original_selector = selector
|
10270
10350
|
selector, by = self.__recalculate_selector(selector, by)
|
10271
10351
|
if self.__is_cdp_swap_needed():
|
10272
|
-
self.cdp.
|
10352
|
+
self.cdp.wait_for_element_not_visible(selector, timeout=timeout)
|
10273
10353
|
return True
|
10274
10354
|
return page_actions.wait_for_element_not_visible(
|
10275
10355
|
self.driver,
|
@@ -10291,7 +10371,7 @@ class BaseCase(unittest.TestCase):
|
|
10291
10371
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
10292
10372
|
timeout = self.__get_new_timeout(timeout)
|
10293
10373
|
if self.__is_cdp_swap_needed():
|
10294
|
-
self.cdp.assert_element_not_visible(selector)
|
10374
|
+
self.cdp.assert_element_not_visible(selector, timeout=timeout)
|
10295
10375
|
return True
|
10296
10376
|
self.wait_for_element_not_visible(selector, by=by, timeout=timeout)
|
10297
10377
|
if self.recorder_mode and self.__current_url_is_recordable():
|
@@ -10313,6 +10393,10 @@ class BaseCase(unittest.TestCase):
|
|
10313
10393
|
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
10314
10394
|
timeout = self.__get_new_timeout(timeout)
|
10315
10395
|
selector, by = self.__recalculate_selector(selector, by)
|
10396
|
+
if self.__is_cdp_swap_needed():
|
10397
|
+
return self.cdp.wait_for_text_not_visible(
|
10398
|
+
text, selector=selector, timeout=timeout
|
10399
|
+
)
|
10316
10400
|
return page_actions.wait_for_text_not_visible(
|
10317
10401
|
self.driver, text, selector, by, timeout
|
10318
10402
|
)
|
@@ -13896,7 +13980,8 @@ class BaseCase(unittest.TestCase):
|
|
13896
13980
|
js_utils.highlight_element_with_js(self.driver, element, loops, o_bs)
|
13897
13981
|
|
13898
13982
|
def __highlight_with_jquery(self, selector, loops, o_bs):
|
13899
|
-
self.
|
13983
|
+
if not self.__is_cdp_swap_needed():
|
13984
|
+
self.wait_for_ready_state_complete()
|
13900
13985
|
js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)
|
13901
13986
|
|
13902
13987
|
def __highlight_with_js_2(self, message, selector, o_bs):
|
@@ -585,52 +585,60 @@ def highlight_with_jquery(driver, selector, loops=4, o_bs=""):
|
|
585
585
|
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)');"""
|
586
586
|
% selector
|
587
587
|
)
|
588
|
-
|
588
|
+
with suppress(Exception):
|
589
|
+
safe_execute_script(driver, script)
|
589
590
|
for n in range(loops):
|
590
591
|
script = (
|
591
592
|
"""jQuery('%s').css('box-shadow',
|
592
593
|
'0px 0px 6px 6px rgba(255, 0, 0, 1)');"""
|
593
594
|
% selector
|
594
595
|
)
|
595
|
-
|
596
|
+
with suppress(Exception):
|
597
|
+
execute_script(driver, script)
|
596
598
|
time.sleep(0.0181)
|
597
599
|
script = (
|
598
600
|
"""jQuery('%s').css('box-shadow',
|
599
601
|
'0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
|
600
602
|
% selector
|
601
603
|
)
|
602
|
-
|
604
|
+
with suppress(Exception):
|
605
|
+
execute_script(driver, script)
|
603
606
|
time.sleep(0.0181)
|
604
607
|
script = (
|
605
608
|
"""jQuery('%s').css('box-shadow',
|
606
609
|
'0px 0px 6px 6px rgba(0, 0, 255, 1)');"""
|
607
610
|
% selector
|
608
611
|
)
|
609
|
-
|
612
|
+
with suppress(Exception):
|
613
|
+
execute_script(driver, script)
|
610
614
|
time.sleep(0.0181)
|
611
615
|
script = (
|
612
616
|
"""jQuery('%s').css('box-shadow',
|
613
617
|
'0px 0px 6px 6px rgba(0, 255, 0, 1)');"""
|
614
618
|
% selector
|
615
619
|
)
|
616
|
-
|
620
|
+
with suppress(Exception):
|
621
|
+
execute_script(driver, script)
|
617
622
|
time.sleep(0.0181)
|
618
623
|
script = (
|
619
624
|
"""jQuery('%s').css('box-shadow',
|
620
625
|
'0px 0px 6px 6px rgba(128, 128, 0, 1)');"""
|
621
626
|
% selector
|
622
627
|
)
|
623
|
-
|
628
|
+
with suppress(Exception):
|
629
|
+
execute_script(driver, script)
|
624
630
|
time.sleep(0.0181)
|
625
631
|
script = (
|
626
632
|
"""jQuery('%s').css('box-shadow',
|
627
633
|
'0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
|
628
634
|
% selector
|
629
635
|
)
|
630
|
-
|
636
|
+
with suppress(Exception):
|
637
|
+
execute_script(driver, script)
|
631
638
|
time.sleep(0.0181)
|
632
639
|
script = """jQuery('%s').css('box-shadow', '%s');""" % (selector, o_bs)
|
633
|
-
|
640
|
+
with suppress(Exception):
|
641
|
+
execute_script(driver, script)
|
634
642
|
|
635
643
|
|
636
644
|
def add_css_link(driver, css_link):
|
@@ -924,13 +932,26 @@ def post_message(driver, message, msg_dur=None, style="info"):
|
|
924
932
|
"""hideAfter: %s, hideOnNavigate: true});"""
|
925
933
|
% (message, style, msg_dur)
|
926
934
|
)
|
935
|
+
retry = False
|
927
936
|
try:
|
928
937
|
execute_script(driver, messenger_script)
|
938
|
+
except TypeError as e:
|
939
|
+
if (
|
940
|
+
shared_utils.is_cdp_swap_needed(driver)
|
941
|
+
and "cannot unpack non-iterable" in str(e)
|
942
|
+
):
|
943
|
+
pass
|
944
|
+
else:
|
945
|
+
retry = True
|
929
946
|
except Exception:
|
947
|
+
retry = True
|
948
|
+
if retry:
|
930
949
|
activate_messenger(driver)
|
931
950
|
set_messenger_theme(driver)
|
932
951
|
try:
|
933
952
|
execute_script(driver, messenger_script)
|
953
|
+
except TypeError:
|
954
|
+
pass
|
934
955
|
except Exception:
|
935
956
|
time.sleep(0.17)
|
936
957
|
activate_messenger(driver)
|
@@ -1273,7 +1294,10 @@ def slow_scroll_to_element(driver, element, *args, **kwargs):
|
|
1273
1294
|
scroll_position = execute_script(driver, "return window.scrollY;")
|
1274
1295
|
element_location_y = None
|
1275
1296
|
try:
|
1276
|
-
|
1297
|
+
if shared_utils.is_cdp_swap_needed(driver):
|
1298
|
+
element.get_position().y
|
1299
|
+
else:
|
1300
|
+
element_location_y = element.location["y"]
|
1277
1301
|
except Exception:
|
1278
1302
|
element.location_once_scrolled_into_view
|
1279
1303
|
return
|
@@ -208,7 +208,6 @@ class Base(Plugin):
|
|
208
208
|
self.duration = float(0)
|
209
209
|
self.page_results_list = []
|
210
210
|
self.test_count = 0
|
211
|
-
self.import_error = False
|
212
211
|
log_path = constants.Logs.LATEST + "/"
|
213
212
|
archive_logs = options.archive_logs
|
214
213
|
log_helper.log_folder_setup(log_path, archive_logs)
|
@@ -238,6 +237,7 @@ class Base(Plugin):
|
|
238
237
|
)
|
239
238
|
else:
|
240
239
|
variables = {}
|
240
|
+
test.test.test_id = test.id()
|
241
241
|
test.test.is_nosetest = True
|
242
242
|
test.test.environment = self.options.environment
|
243
243
|
test.test.env = self.options.environment # Add a shortened version
|
@@ -263,17 +263,16 @@ class Base(Plugin):
|
|
263
263
|
)
|
264
264
|
log_helper.clear_empty_logs()
|
265
265
|
if self.report_on:
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
)
|
266
|
+
report_helper.add_bad_page_log_file(self.page_results_list)
|
267
|
+
report_log_path = report_helper.archive_new_report_logs()
|
268
|
+
report_helper.build_report(
|
269
|
+
report_log_path,
|
270
|
+
self.page_results_list,
|
271
|
+
self.successes,
|
272
|
+
self.failures,
|
273
|
+
self.options.browser,
|
274
|
+
self.show_report,
|
275
|
+
)
|
277
276
|
|
278
277
|
def addSuccess(self, test, capt):
|
279
278
|
if self.report_on:
|
@@ -293,9 +292,6 @@ class Base(Plugin):
|
|
293
292
|
"%.2fs" % (float(time.time()) - float(self.start_time))
|
294
293
|
)
|
295
294
|
if test.id() == "nose.failure.Failure.runTest":
|
296
|
-
print(">>> ERROR: Could not locate tests to run!")
|
297
|
-
print(">>> The Test Report WILL NOT be generated!")
|
298
|
-
self.import_error = True
|
299
295
|
return
|
300
296
|
self.failures.append(test.id())
|
301
297
|
self.page_results_list.append(
|
@@ -314,6 +310,7 @@ class Base(Plugin):
|
|
314
310
|
test._log_fail_data()
|
315
311
|
sb_config._excinfo_tb = err
|
316
312
|
log_path = None
|
313
|
+
source = None
|
317
314
|
if hasattr(sb_config, "_test_logpath"):
|
318
315
|
log_path = sb_config._test_logpath
|
319
316
|
if hasattr(sb_config, "_last_page_source"):
|
@@ -10,7 +10,7 @@ Example -->
|
|
10
10
|
```python
|
11
11
|
from seleniumbase import DriverContext
|
12
12
|
|
13
|
-
with DriverContext() as driver:
|
13
|
+
with DriverContext(uc=True) as driver:
|
14
14
|
driver.get("https://google.com/ncr")
|
15
15
|
```
|
16
16
|
|
@@ -30,7 +30,7 @@ Example -->
|
|
30
30
|
```python
|
31
31
|
from seleniumbase import Driver
|
32
32
|
|
33
|
-
driver = Driver()
|
33
|
+
driver = Driver(uc=True)
|
34
34
|
driver.get("https://google.com/ncr")
|
35
35
|
```
|
36
36
|
|
@@ -781,6 +781,23 @@ def Driver(
|
|
781
781
|
swiftshader = False
|
782
782
|
if locale is not None and locale_code is None:
|
783
783
|
locale_code = locale
|
784
|
+
if locale_code is None:
|
785
|
+
if '--locale="' in arg_join:
|
786
|
+
locale_code = (
|
787
|
+
arg_join.split('--locale="')[1].split('"')[0]
|
788
|
+
)
|
789
|
+
elif '--locale=' in arg_join:
|
790
|
+
locale_code = (
|
791
|
+
arg_join.split('--locale=')[1].split(' ')[0]
|
792
|
+
)
|
793
|
+
elif '--locale-code="' in arg_join:
|
794
|
+
locale_code = (
|
795
|
+
arg_join.split('--locale-code="')[1].split('"')[0]
|
796
|
+
)
|
797
|
+
elif '--locale-code=' in arg_join:
|
798
|
+
locale_code = (
|
799
|
+
arg_join.split('--locale-code=')[1].split(' ')[0]
|
800
|
+
)
|
784
801
|
if ad_block is not None and ad_block_on is None:
|
785
802
|
ad_block_on = ad_block
|
786
803
|
if ad_block_on is None:
|
@@ -2496,6 +2496,9 @@ def pytest_unconfigure(config):
|
|
2496
2496
|
"""This runs after all tests have completed with pytest."""
|
2497
2497
|
if "--co" in sys_argv or "--collect-only" in sys_argv:
|
2498
2498
|
return
|
2499
|
+
reporter = config.pluginmanager.get_plugin("terminalreporter")
|
2500
|
+
if not hasattr(reporter, "_sessionstarttime"):
|
2501
|
+
return
|
2499
2502
|
if hasattr(sb_config, "_multithreaded") and sb_config._multithreaded:
|
2500
2503
|
import fasteners
|
2501
2504
|
|
@@ -10,7 +10,7 @@ Example -->
|
|
10
10
|
```python
|
11
11
|
from seleniumbase import SB
|
12
12
|
|
13
|
-
with SB() as sb: # Many args! Eg. SB(browser="edge")
|
13
|
+
with SB(uc=True) as sb: # Many args! Eg. SB(browser="edge")
|
14
14
|
sb.open("https://google.com/ncr")
|
15
15
|
sb.type('[name="q"]', "SeleniumBase on GitHub\n")
|
16
16
|
sb.click('a[href*="github.com/seleniumbase"]')
|
@@ -942,6 +942,23 @@ def SB(
|
|
942
942
|
swiftshader = False
|
943
943
|
if locale is not None and locale_code is None:
|
944
944
|
locale_code = locale
|
945
|
+
if locale_code is None:
|
946
|
+
if '--locale="' in arg_join:
|
947
|
+
locale_code = (
|
948
|
+
arg_join.split('--locale="')[1].split('"')[0]
|
949
|
+
)
|
950
|
+
elif '--locale=' in arg_join:
|
951
|
+
locale_code = (
|
952
|
+
arg_join.split('--locale=')[1].split(' ')[0]
|
953
|
+
)
|
954
|
+
elif '--locale-code="' in arg_join:
|
955
|
+
locale_code = (
|
956
|
+
arg_join.split('--locale-code="')[1].split('"')[0]
|
957
|
+
)
|
958
|
+
elif '--locale-code=' in arg_join:
|
959
|
+
locale_code = (
|
960
|
+
arg_join.split('--locale-code=')[1].split(' ')[0]
|
961
|
+
)
|
945
962
|
if ad_block is not None and ad_block_on is None:
|
946
963
|
ad_block_on = ad_block
|
947
964
|
if ad_block_on is None:
|
@@ -1309,6 +1309,7 @@ class SeleniumBrowser(Plugin):
|
|
1309
1309
|
test.test.dashboard = False
|
1310
1310
|
test.test._multithreaded = False
|
1311
1311
|
test.test._reuse_session = False
|
1312
|
+
sb_config.recorder_mode = test.test.recorder_mode
|
1312
1313
|
sb_config.no_screenshot = test.test.no_screenshot_after_test
|
1313
1314
|
if test.test.servername != "localhost":
|
1314
1315
|
# Using Selenium Grid
|