seleniumbase 4.39.6a2__py3-none-any.whl → 4.40.0__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 +16 -0
- seleniumbase/console_scripts/sb_install.py +15 -0
- seleniumbase/core/browser_launcher.py +161 -61
- seleniumbase/core/log_helper.py +5 -1
- seleniumbase/core/sb_cdp.py +144 -0
- seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- seleniumbase/fixtures/base_case.py +166 -4
- seleniumbase/fixtures/page_actions.py +149 -0
- seleniumbase/plugins/pytest_plugin.py +2 -0
- seleniumbase/plugins/selenium_plugin.py +3 -0
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/METADATA +6 -6
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/RECORD +18 -16
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/WHEEL +0 -0
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/licenses/LICENSE +0 -0
- {seleniumbase-4.39.6a2.dist-info → seleniumbase-4.40.0.dist-info}/top_level.txt +0 -0
seleniumbase/core/sb_cdp.py
CHANGED
@@ -2014,6 +2014,150 @@ class CDPMethods():
|
|
2014
2014
|
% (selector, timeout, plural)
|
2015
2015
|
)
|
2016
2016
|
|
2017
|
+
def wait_for_any_of_elements_visible(self, *args, **kwargs):
|
2018
|
+
"""Waits for at least one of the elements to be visible.
|
2019
|
+
Returns the first element that is found.
|
2020
|
+
The input is a list of elements. (Should be CSS selectors)
|
2021
|
+
Optional kwargs include: "timeout" (used by all selectors).
|
2022
|
+
Raises an exception if no elements are visible by the timeout.
|
2023
|
+
Examples:
|
2024
|
+
sb.cdp.wait_for_any_of_elements_visible("h1", "h2", "h3")
|
2025
|
+
OR
|
2026
|
+
sb.cdp.wait_for_any_of_elements_visible(["h1", "h2", "h3"]) """
|
2027
|
+
selectors = []
|
2028
|
+
timeout = None
|
2029
|
+
for kwarg in kwargs:
|
2030
|
+
if kwarg == "timeout":
|
2031
|
+
timeout = kwargs["timeout"]
|
2032
|
+
elif kwarg == "by":
|
2033
|
+
pass # Autodetected
|
2034
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
2035
|
+
selector = kwargs[kwarg]
|
2036
|
+
if isinstance(selector, str):
|
2037
|
+
selectors.append(selector)
|
2038
|
+
elif isinstance(selector, list):
|
2039
|
+
selectors_list = selector
|
2040
|
+
for selector in selectors_list:
|
2041
|
+
if isinstance(selector, str):
|
2042
|
+
selectors.append(selector)
|
2043
|
+
else:
|
2044
|
+
raise Exception('Unknown kwarg: "%s"!' % kwarg)
|
2045
|
+
if not timeout:
|
2046
|
+
timeout = settings.SMALL_TIMEOUT
|
2047
|
+
for arg in args:
|
2048
|
+
if isinstance(arg, list):
|
2049
|
+
for selector in arg:
|
2050
|
+
if isinstance(selector, str):
|
2051
|
+
selectors.append(selector)
|
2052
|
+
elif isinstance(arg, str):
|
2053
|
+
selectors.append(arg)
|
2054
|
+
if not selectors:
|
2055
|
+
raise Exception("The selectors list was empty!")
|
2056
|
+
start_ms = time.time() * 1000.0
|
2057
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
2058
|
+
any_present = False
|
2059
|
+
for i in range(int(timeout * 10)):
|
2060
|
+
for selector in selectors:
|
2061
|
+
if self.is_element_visible(selector):
|
2062
|
+
return self.select(selector)
|
2063
|
+
if self.is_element_present(selector):
|
2064
|
+
any_present = True
|
2065
|
+
now_ms = time.time() * 1000.0
|
2066
|
+
if now_ms >= stop_ms:
|
2067
|
+
break
|
2068
|
+
time.sleep(0.1)
|
2069
|
+
plural = "s"
|
2070
|
+
if timeout == 1:
|
2071
|
+
plural = ""
|
2072
|
+
if not any_present:
|
2073
|
+
# None of the elements exist in the HTML
|
2074
|
+
raise Exception(
|
2075
|
+
"None of the elements {%s} were present after %s second%s!" % (
|
2076
|
+
str(selectors),
|
2077
|
+
timeout,
|
2078
|
+
plural,
|
2079
|
+
)
|
2080
|
+
)
|
2081
|
+
raise Exception(
|
2082
|
+
"None of the elements %s were visible after %s second%s!" % (
|
2083
|
+
str(selectors),
|
2084
|
+
timeout,
|
2085
|
+
plural,
|
2086
|
+
)
|
2087
|
+
)
|
2088
|
+
|
2089
|
+
def wait_for_any_of_elements_present(self, *args, **kwargs):
|
2090
|
+
"""Waits for at least one of the elements to be present.
|
2091
|
+
Visibility not required, but element must be in the DOM.
|
2092
|
+
Returns the first element that is found.
|
2093
|
+
The input is a list of elements. (Should be CSS selectors)
|
2094
|
+
Optional kwargs include: "timeout" (used by all selectors).
|
2095
|
+
Raises an exception if no elements are present by the timeout.
|
2096
|
+
Examples:
|
2097
|
+
self.wait_for_any_of_elements_present("style", "script")
|
2098
|
+
OR
|
2099
|
+
self.wait_for_any_of_elements_present(["style", "script"]) """
|
2100
|
+
selectors = []
|
2101
|
+
timeout = None
|
2102
|
+
for kwarg in kwargs:
|
2103
|
+
if kwarg == "timeout":
|
2104
|
+
timeout = kwargs["timeout"]
|
2105
|
+
elif kwarg == "by":
|
2106
|
+
pass # Autodetected
|
2107
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
2108
|
+
selector = kwargs[kwarg]
|
2109
|
+
if isinstance(selector, str):
|
2110
|
+
selectors.append(selector)
|
2111
|
+
elif isinstance(selector, list):
|
2112
|
+
selectors_list = selector
|
2113
|
+
for selector in selectors_list:
|
2114
|
+
if isinstance(selector, str):
|
2115
|
+
selectors.append(selector)
|
2116
|
+
else:
|
2117
|
+
raise Exception('Unknown kwarg: "%s"!' % kwarg)
|
2118
|
+
if not timeout:
|
2119
|
+
timeout = settings.SMALL_TIMEOUT
|
2120
|
+
for arg in args:
|
2121
|
+
if isinstance(arg, list):
|
2122
|
+
for selector in arg:
|
2123
|
+
if isinstance(selector, str):
|
2124
|
+
selectors.append(selector)
|
2125
|
+
elif isinstance(arg, str):
|
2126
|
+
selectors.append(arg)
|
2127
|
+
if not selectors:
|
2128
|
+
raise Exception("The selectors list was empty!")
|
2129
|
+
start_ms = time.time() * 1000.0
|
2130
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
2131
|
+
for i in range(int(timeout * 10)):
|
2132
|
+
for selector in selectors:
|
2133
|
+
if self.is_element_present(selector):
|
2134
|
+
return self.select(selector)
|
2135
|
+
now_ms = time.time() * 1000.0
|
2136
|
+
if now_ms >= stop_ms:
|
2137
|
+
break
|
2138
|
+
time.sleep(0.1)
|
2139
|
+
plural = "s"
|
2140
|
+
if timeout == 1:
|
2141
|
+
plural = ""
|
2142
|
+
# None of the elements exist in the HTML
|
2143
|
+
raise Exception(
|
2144
|
+
"None of the elements %s were present after %s second%s!" % (
|
2145
|
+
str(selectors),
|
2146
|
+
timeout,
|
2147
|
+
plural,
|
2148
|
+
)
|
2149
|
+
)
|
2150
|
+
|
2151
|
+
def assert_any_of_elements_visible(self, *args, **kwargs):
|
2152
|
+
"""Like wait_for_any_of_elements_visible(), but returns nothing."""
|
2153
|
+
self.wait_for_any_of_elements_visible(*args, **kwargs)
|
2154
|
+
return True
|
2155
|
+
|
2156
|
+
def assert_any_of_elements_present(self, *args, **kwargs):
|
2157
|
+
"""Like wait_for_any_of_elements_present(), but returns nothing."""
|
2158
|
+
self.wait_for_any_of_elements_present(*args, **kwargs)
|
2159
|
+
return True
|
2160
|
+
|
2017
2161
|
def assert_element(self, selector, timeout=None):
|
2018
2162
|
"""Same as assert_element_visible()"""
|
2019
2163
|
self.assert_element_visible(selector, timeout=timeout)
|
File without changes
|
File without changes
|
@@ -4894,7 +4894,7 @@ class BaseCase(unittest.TestCase):
|
|
4894
4894
|
self.driver.connect()
|
4895
4895
|
current_url = self.get_current_url()
|
4896
4896
|
if not current_url.startswith(("about", "data", "chrome")):
|
4897
|
-
self.
|
4897
|
+
self.open("about:blank")
|
4898
4898
|
self.driver.uc_open_with_cdp_mode(url, **kwargs)
|
4899
4899
|
else:
|
4900
4900
|
self.get_new_driver(undetectable=True)
|
@@ -9227,6 +9227,162 @@ class BaseCase(unittest.TestCase):
|
|
9227
9227
|
original_selector=original_selector,
|
9228
9228
|
)
|
9229
9229
|
|
9230
|
+
def wait_for_any_of_elements_visible(self, *args, **kwargs):
|
9231
|
+
"""Waits for at least one of the elements to be visible.
|
9232
|
+
Returns the first element that is found.
|
9233
|
+
The input is a list of elements. (Should be CSS selectors or XPath)
|
9234
|
+
Optional kwargs include: "timeout" (used by all selectors).
|
9235
|
+
Raises an exception if no elements are visible by the timeout.
|
9236
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9237
|
+
Examples:
|
9238
|
+
self.wait_for_any_of_elements_visible("h1", "h2", "h3")
|
9239
|
+
OR
|
9240
|
+
self.wait_for_any_of_elements_visible(["h1", "h2", "h3"]) """
|
9241
|
+
self.__check_scope()
|
9242
|
+
selectors = []
|
9243
|
+
timeout = None
|
9244
|
+
for kwarg in kwargs:
|
9245
|
+
if kwarg == "timeout":
|
9246
|
+
timeout = kwargs["timeout"]
|
9247
|
+
elif kwarg == "by":
|
9248
|
+
pass # Autodetected
|
9249
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
9250
|
+
selector = kwargs[kwarg]
|
9251
|
+
if isinstance(selector, str):
|
9252
|
+
selectors.append(selector)
|
9253
|
+
elif isinstance(selector, list):
|
9254
|
+
selectors_list = selector
|
9255
|
+
for selector in selectors_list:
|
9256
|
+
if isinstance(selector, str):
|
9257
|
+
selectors.append(selector)
|
9258
|
+
else:
|
9259
|
+
raise Exception('Unknown kwarg: "%s"!' % kwarg)
|
9260
|
+
if not timeout:
|
9261
|
+
timeout = settings.LARGE_TIMEOUT
|
9262
|
+
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
9263
|
+
timeout = self.__get_new_timeout(timeout)
|
9264
|
+
for arg in args:
|
9265
|
+
if isinstance(arg, list):
|
9266
|
+
for selector in arg:
|
9267
|
+
if isinstance(selector, str):
|
9268
|
+
selectors.append(selector)
|
9269
|
+
elif isinstance(arg, str):
|
9270
|
+
selectors.append(arg)
|
9271
|
+
if not selectors:
|
9272
|
+
raise Exception("The selectors list was empty!")
|
9273
|
+
original_selectors = selectors
|
9274
|
+
updated_selectors = []
|
9275
|
+
for selector in selectors:
|
9276
|
+
by = "css selector"
|
9277
|
+
if page_utils.is_xpath_selector(selector):
|
9278
|
+
by = "xpath"
|
9279
|
+
selector, by = self.__recalculate_selector(selector, by)
|
9280
|
+
updated_selectors.append(selector)
|
9281
|
+
selectors = updated_selectors
|
9282
|
+
if self.__is_cdp_swap_needed():
|
9283
|
+
return self.cdp.wait_for_any_of_elements_visible(
|
9284
|
+
selectors, timeout=timeout
|
9285
|
+
)
|
9286
|
+
return page_actions.wait_for_any_of_elements_visible(
|
9287
|
+
self.driver,
|
9288
|
+
selectors,
|
9289
|
+
timeout=timeout,
|
9290
|
+
original_selectors=original_selectors,
|
9291
|
+
)
|
9292
|
+
|
9293
|
+
def wait_for_any_of_elements_present(self, *args, **kwargs):
|
9294
|
+
"""Waits for at least one of the elements to be present.
|
9295
|
+
Visibility not required, but element must be in the DOM.
|
9296
|
+
Returns the first element that is found.
|
9297
|
+
The input is a list of elements. (Should be CSS selectors or XPath)
|
9298
|
+
Optional kwargs include: "timeout" (used by all selectors).
|
9299
|
+
Raises an exception if no elements are present by the timeout.
|
9300
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9301
|
+
Examples:
|
9302
|
+
self.wait_for_any_of_elements_present("style", "script")
|
9303
|
+
OR
|
9304
|
+
self.wait_for_any_of_elements_present(["style", "script"]) """
|
9305
|
+
self.__check_scope()
|
9306
|
+
selectors = []
|
9307
|
+
timeout = None
|
9308
|
+
for kwarg in kwargs:
|
9309
|
+
if kwarg == "timeout":
|
9310
|
+
timeout = kwargs["timeout"]
|
9311
|
+
elif kwarg == "by":
|
9312
|
+
pass # Autodetected
|
9313
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
9314
|
+
selector = kwargs[kwarg]
|
9315
|
+
if isinstance(selector, str):
|
9316
|
+
selectors.append(selector)
|
9317
|
+
elif isinstance(selector, list):
|
9318
|
+
selectors_list = selector
|
9319
|
+
for selector in selectors_list:
|
9320
|
+
if isinstance(selector, str):
|
9321
|
+
selectors.append(selector)
|
9322
|
+
else:
|
9323
|
+
raise Exception('Unknown kwarg: "%s"!' % kwarg)
|
9324
|
+
if not timeout:
|
9325
|
+
timeout = settings.LARGE_TIMEOUT
|
9326
|
+
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
9327
|
+
timeout = self.__get_new_timeout(timeout)
|
9328
|
+
for arg in args:
|
9329
|
+
if isinstance(arg, list):
|
9330
|
+
for selector in arg:
|
9331
|
+
if isinstance(selector, str):
|
9332
|
+
selectors.append(selector)
|
9333
|
+
elif isinstance(arg, str):
|
9334
|
+
selectors.append(arg)
|
9335
|
+
if not selectors:
|
9336
|
+
raise Exception("The selectors list was empty!")
|
9337
|
+
original_selectors = selectors
|
9338
|
+
updated_selectors = []
|
9339
|
+
for selector in selectors:
|
9340
|
+
by = "css selector"
|
9341
|
+
if page_utils.is_xpath_selector(selector):
|
9342
|
+
by = "xpath"
|
9343
|
+
selector, by = self.__recalculate_selector(selector, by)
|
9344
|
+
updated_selectors.append(selector)
|
9345
|
+
selectors = updated_selectors
|
9346
|
+
if self.__is_cdp_swap_needed():
|
9347
|
+
return self.cdp.wait_for_any_of_elements_present(
|
9348
|
+
selectors, timeout=timeout
|
9349
|
+
)
|
9350
|
+
return page_actions.wait_for_any_of_elements_present(
|
9351
|
+
self.driver,
|
9352
|
+
selectors,
|
9353
|
+
timeout=timeout,
|
9354
|
+
original_selectors=original_selectors,
|
9355
|
+
)
|
9356
|
+
|
9357
|
+
def assert_any_of_elements_visible(self, *args, **kwargs):
|
9358
|
+
"""Similar to wait_for_any_of_elements_visible(), but returns nothing.
|
9359
|
+
As above, raises an exception if none of the set elements are visible.
|
9360
|
+
Returns True if successful. Default timeout = SMALL_TIMEOUT.
|
9361
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9362
|
+
Examples:
|
9363
|
+
self.assert_any_of_elements_visible("h1", "h2", "h3")
|
9364
|
+
OR
|
9365
|
+
self.assert_any_of_elements_visible(["h1", "h2", "h3"]) """
|
9366
|
+
if "timeout" not in kwargs:
|
9367
|
+
kwargs["timeout"] = settings.SMALL_TIMEOUT
|
9368
|
+
self.wait_for_any_of_elements_visible(*args, **kwargs)
|
9369
|
+
return True
|
9370
|
+
|
9371
|
+
def assert_any_of_elements_present(self, *args, **kwargs):
|
9372
|
+
"""Similar to wait_for_any_of_elements_present(), but returns nothing.
|
9373
|
+
As above, raises an exception if none of the given elements are found.
|
9374
|
+
Visibility is not required, but element must exist in the DOM.
|
9375
|
+
Returns True if successful. Default timeout = SMALL_TIMEOUT.
|
9376
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9377
|
+
Examples:
|
9378
|
+
self.assert_any_of_elements_present("h1", "h2", "h3")
|
9379
|
+
OR
|
9380
|
+
self.assert_any_of_elements_present(["h1", "h2", "h3"]) """
|
9381
|
+
if "timeout" not in kwargs:
|
9382
|
+
kwargs["timeout"] = settings.SMALL_TIMEOUT
|
9383
|
+
self.wait_for_any_of_elements_present(*args, **kwargs)
|
9384
|
+
return True
|
9385
|
+
|
9230
9386
|
def select_all(self, selector, by="css selector", limit=0):
|
9231
9387
|
return self.find_elements(selector, by=by, limit=limit)
|
9232
9388
|
|
@@ -9698,6 +9854,7 @@ class BaseCase(unittest.TestCase):
|
|
9698
9854
|
The input is a list of elements.
|
9699
9855
|
Optional kwargs include "by" and "timeout" (used by all selectors).
|
9700
9856
|
Raises an exception if any of the elements are not visible.
|
9857
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9701
9858
|
Examples:
|
9702
9859
|
self.assert_elements_present("head", "style", "script", "body")
|
9703
9860
|
OR
|
@@ -9711,7 +9868,7 @@ class BaseCase(unittest.TestCase):
|
|
9711
9868
|
timeout = kwargs["timeout"]
|
9712
9869
|
elif kwarg == "by":
|
9713
9870
|
by = kwargs["by"]
|
9714
|
-
elif kwarg == "selector":
|
9871
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
9715
9872
|
selector = kwargs["selector"]
|
9716
9873
|
if isinstance(selector, str):
|
9717
9874
|
selectors.append(selector)
|
@@ -9804,6 +9961,7 @@ class BaseCase(unittest.TestCase):
|
|
9804
9961
|
The input is a list of elements.
|
9805
9962
|
Optional kwargs include "by" and "timeout" (used by all selectors).
|
9806
9963
|
Raises an exception if any of the elements are not visible.
|
9964
|
+
Allows flexible inputs (Eg. Multiple args or a list of args)
|
9807
9965
|
Examples:
|
9808
9966
|
self.assert_elements("h1", "h2", "h3")
|
9809
9967
|
OR
|
@@ -9817,7 +9975,7 @@ class BaseCase(unittest.TestCase):
|
|
9817
9975
|
timeout = kwargs["timeout"]
|
9818
9976
|
elif kwarg == "by":
|
9819
9977
|
by = kwargs["by"]
|
9820
|
-
elif kwarg == "selector":
|
9978
|
+
elif kwarg == "selector" or kwarg == "selectors":
|
9821
9979
|
selector = kwargs["selector"]
|
9822
9980
|
if isinstance(selector, str):
|
9823
9981
|
selectors.append(selector)
|
@@ -16747,7 +16905,11 @@ class BaseCase(unittest.TestCase):
|
|
16747
16905
|
self._last_page_url = "(Error: Unknown URL)"
|
16748
16906
|
if hasattr(self, "is_behave") and self.is_behave and has_exception:
|
16749
16907
|
if hasattr(sb_config, "pdb_option") and sb_config.pdb_option:
|
16750
|
-
|
16908
|
+
if (
|
16909
|
+
hasattr(sb_config, "behave_step")
|
16910
|
+
and hasattr(sb_config.behave_step, "exc_traceback")
|
16911
|
+
):
|
16912
|
+
self.__activate_behave_post_mortem_debug_mode()
|
16751
16913
|
if self._final_debug:
|
16752
16914
|
self.__activate_debug_mode_in_teardown()
|
16753
16915
|
elif (
|
@@ -751,6 +751,155 @@ def wait_for_exact_text_visible(
|
|
751
751
|
return element
|
752
752
|
|
753
753
|
|
754
|
+
def wait_for_any_of_elements_visible(
|
755
|
+
driver,
|
756
|
+
selectors,
|
757
|
+
timeout=settings.LARGE_TIMEOUT,
|
758
|
+
original_selectors=[],
|
759
|
+
ignore_test_time_limit=False,
|
760
|
+
):
|
761
|
+
"""
|
762
|
+
Waits for at least one of the elements in the selector list to be visible.
|
763
|
+
Returns the first element that is found.
|
764
|
+
Raises NoSuchElementException if none of the elements exist in the HTML
|
765
|
+
within the specified timeout.
|
766
|
+
Raises ElementNotVisibleException if the element exists in the HTML,
|
767
|
+
but is not visible (eg. opacity is "0") within the specified timeout.
|
768
|
+
@Params
|
769
|
+
driver - the webdriver object (required)
|
770
|
+
selectors - the list of selectors for identifying page elements (required)
|
771
|
+
timeout - the time to wait for elements in seconds
|
772
|
+
original_selectors - handle pre-converted ":contains(TEXT)" selectors
|
773
|
+
ignore_test_time_limit - ignore test time limit (NOT related to timeout)
|
774
|
+
@Returns
|
775
|
+
A web element object
|
776
|
+
"""
|
777
|
+
if not isinstance(selectors, (list, tuple)):
|
778
|
+
raise Exception("`selectors` must be a list or tuple!")
|
779
|
+
if not selectors:
|
780
|
+
raise Exception("`selectors` cannot be an empty list!")
|
781
|
+
_reconnect_if_disconnected(driver)
|
782
|
+
element = None
|
783
|
+
any_present = False
|
784
|
+
start_ms = time.time() * 1000.0
|
785
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
786
|
+
for x in range(int(timeout * 10)):
|
787
|
+
if not ignore_test_time_limit:
|
788
|
+
shared_utils.check_if_time_limit_exceeded()
|
789
|
+
try:
|
790
|
+
for selector in selectors:
|
791
|
+
by = "css selector"
|
792
|
+
if page_utils.is_xpath_selector(selector):
|
793
|
+
by = "xpath"
|
794
|
+
try:
|
795
|
+
element = driver.find_element(by=by, value=selector)
|
796
|
+
any_present = True
|
797
|
+
if element.is_displayed():
|
798
|
+
return element
|
799
|
+
element = None
|
800
|
+
except Exception:
|
801
|
+
pass
|
802
|
+
raise Exception("Nothing found yet!")
|
803
|
+
except Exception:
|
804
|
+
now_ms = time.time() * 1000.0
|
805
|
+
if now_ms >= stop_ms:
|
806
|
+
break
|
807
|
+
time.sleep(0.1)
|
808
|
+
plural = "s"
|
809
|
+
if timeout == 1:
|
810
|
+
plural = ""
|
811
|
+
if original_selectors:
|
812
|
+
selectors = original_selectors
|
813
|
+
if not element:
|
814
|
+
if not any_present:
|
815
|
+
# None of the elements exist in the HTML
|
816
|
+
message = (
|
817
|
+
"None of the elements {%s} were present after %s second%s!" % (
|
818
|
+
str(selectors),
|
819
|
+
timeout,
|
820
|
+
plural,
|
821
|
+
)
|
822
|
+
)
|
823
|
+
timeout_exception(NoSuchElementException, message)
|
824
|
+
# At least one element exists in the HTML, but none are visible
|
825
|
+
message = "None of the elements %s were visible after %s second%s!" % (
|
826
|
+
str(selectors),
|
827
|
+
timeout,
|
828
|
+
plural,
|
829
|
+
)
|
830
|
+
timeout_exception(ElementNotVisibleException, message)
|
831
|
+
else:
|
832
|
+
return element
|
833
|
+
|
834
|
+
|
835
|
+
def wait_for_any_of_elements_present(
|
836
|
+
driver,
|
837
|
+
selectors,
|
838
|
+
timeout=settings.LARGE_TIMEOUT,
|
839
|
+
original_selectors=[],
|
840
|
+
ignore_test_time_limit=False,
|
841
|
+
):
|
842
|
+
"""
|
843
|
+
Waits for at least one of the elements in the selector list to be present.
|
844
|
+
Visibility not required. (Eg. <head> hidden in the HTML)
|
845
|
+
Returns the first element that is found.
|
846
|
+
Raises NoSuchElementException if none of the elements exist in the HTML
|
847
|
+
within the specified timeout.
|
848
|
+
@Params
|
849
|
+
driver - the webdriver object (required)
|
850
|
+
selectors - the list of selectors for identifying page elements (required)
|
851
|
+
timeout - the time to wait for elements in seconds
|
852
|
+
original_selectors - handle pre-converted ":contains(TEXT)" selectors
|
853
|
+
ignore_test_time_limit - ignore test time limit (NOT related to timeout)
|
854
|
+
@Returns
|
855
|
+
A web element object
|
856
|
+
"""
|
857
|
+
if not isinstance(selectors, (list, tuple)):
|
858
|
+
raise Exception("`selectors` must be a list or tuple!")
|
859
|
+
if not selectors:
|
860
|
+
raise Exception("`selectors` cannot be an empty list!")
|
861
|
+
_reconnect_if_disconnected(driver)
|
862
|
+
element = None
|
863
|
+
start_ms = time.time() * 1000.0
|
864
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
865
|
+
for x in range(int(timeout * 10)):
|
866
|
+
if not ignore_test_time_limit:
|
867
|
+
shared_utils.check_if_time_limit_exceeded()
|
868
|
+
try:
|
869
|
+
for selector in selectors:
|
870
|
+
by = "css selector"
|
871
|
+
if page_utils.is_xpath_selector(selector):
|
872
|
+
by = "xpath"
|
873
|
+
try:
|
874
|
+
element = driver.find_element(by=by, value=selector)
|
875
|
+
return element
|
876
|
+
except Exception:
|
877
|
+
pass
|
878
|
+
raise Exception("Nothing found yet!")
|
879
|
+
except Exception:
|
880
|
+
now_ms = time.time() * 1000.0
|
881
|
+
if now_ms >= stop_ms:
|
882
|
+
break
|
883
|
+
time.sleep(0.1)
|
884
|
+
plural = "s"
|
885
|
+
if timeout == 1:
|
886
|
+
plural = ""
|
887
|
+
if original_selectors:
|
888
|
+
selectors = original_selectors
|
889
|
+
if not element:
|
890
|
+
# None of the elements exist in the HTML
|
891
|
+
message = (
|
892
|
+
"None of the elements %s were present after %s second%s!" % (
|
893
|
+
str(selectors),
|
894
|
+
timeout,
|
895
|
+
plural,
|
896
|
+
)
|
897
|
+
)
|
898
|
+
timeout_exception(NoSuchElementException, message)
|
899
|
+
else:
|
900
|
+
return element
|
901
|
+
|
902
|
+
|
754
903
|
def wait_for_attribute(
|
755
904
|
driver,
|
756
905
|
selector,
|
@@ -28,6 +28,8 @@ def pytest_addoption(parser):
|
|
28
28
|
--edge (Shortcut for "--browser=edge".)
|
29
29
|
--firefox (Shortcut for "--browser=firefox".)
|
30
30
|
--safari (Shortcut for "--browser=safari".)
|
31
|
+
--cft (Shortcut for using `Chrome for Testing`)
|
32
|
+
--chs (Shortcut for using `Chrome-Headless-Shell`)
|
31
33
|
--settings-file=FILE (Override default SeleniumBase settings.)
|
32
34
|
--env=ENV (Set the test env. Access with "self.env" in tests.)
|
33
35
|
--account=STR (Set account. Access with "self.account" in tests.)
|
@@ -16,6 +16,8 @@ class SeleniumBrowser(Plugin):
|
|
16
16
|
--edge (Shortcut for "--browser=edge".)
|
17
17
|
--firefox (Shortcut for "--browser=firefox".)
|
18
18
|
--safari (Shortcut for "--browser=safari".)
|
19
|
+
--cft (Shortcut for using `Chrome for Testing`)
|
20
|
+
--chs (Shortcut for using `Chrome-Headless-Shell`)
|
19
21
|
--user-data-dir=DIR (Set the Chrome user data directory to use.)
|
20
22
|
--protocol=PROTOCOL (The Selenium Grid protocol: http|https.)
|
21
23
|
--server=SERVER (The Selenium Grid server/IP used for tests.)
|
@@ -1221,6 +1223,7 @@ class SeleniumBrowser(Plugin):
|
|
1221
1223
|
test.test.binary_location = "cft"
|
1222
1224
|
elif self.options.use_chs and not test.test.binary_location:
|
1223
1225
|
test.test.binary_location = "chs"
|
1226
|
+
sb_config.binary_location = test.test.binary_location
|
1224
1227
|
if (
|
1225
1228
|
test.test.binary_location
|
1226
1229
|
and test.test.binary_location.lower() == "chs"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.40.0
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
6
6
|
Author: Michael Mintz
|
@@ -108,7 +108,7 @@ Requires-Dist: wsproto==1.2.0
|
|
108
108
|
Requires-Dist: websocket-client==1.8.0
|
109
109
|
Requires-Dist: selenium==4.27.1; python_version < "3.9"
|
110
110
|
Requires-Dist: selenium==4.32.0; python_version >= "3.9" and python_version < "3.10"
|
111
|
-
Requires-Dist: selenium==4.
|
111
|
+
Requires-Dist: selenium==4.34.0; python_version >= "3.10"
|
112
112
|
Requires-Dist: cssselect==1.2.0; python_version < "3.9"
|
113
113
|
Requires-Dist: cssselect==1.3.0; python_version >= "3.9"
|
114
114
|
Requires-Dist: sortedcontainers==2.4.0
|
@@ -124,7 +124,7 @@ Requires-Dist: pytest-ordering==0.6
|
|
124
124
|
Requires-Dist: pytest-rerunfailures==14.0; python_version < "3.9"
|
125
125
|
Requires-Dist: pytest-rerunfailures==15.1; python_version >= "3.9"
|
126
126
|
Requires-Dist: pytest-xdist==3.6.1; python_version < "3.9"
|
127
|
-
Requires-Dist: pytest-xdist==3.
|
127
|
+
Requires-Dist: pytest-xdist==3.8.0; python_version >= "3.9"
|
128
128
|
Requires-Dist: parameterized==0.9.0
|
129
129
|
Requires-Dist: behave==1.2.6
|
130
130
|
Requires-Dist: soupsieve==2.7
|
@@ -140,7 +140,7 @@ Requires-Dist: allure-python-commons>=2.13.5; extra == "allure"
|
|
140
140
|
Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
141
141
|
Provides-Extra: coverage
|
142
142
|
Requires-Dist: coverage>=7.6.1; python_version < "3.9" and extra == "coverage"
|
143
|
-
Requires-Dist: coverage>=7.9.
|
143
|
+
Requires-Dist: coverage>=7.9.2; python_version >= "3.9" and extra == "coverage"
|
144
144
|
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
145
145
|
Requires-Dist: pytest-cov>=6.2.1; python_version >= "3.9" and extra == "coverage"
|
146
146
|
Provides-Extra: flake8
|
@@ -161,12 +161,12 @@ Provides-Extra: pdfminer
|
|
161
161
|
Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
|
162
162
|
Requires-Dist: pdfminer.six==20250506; python_version >= "3.9" and extra == "pdfminer"
|
163
163
|
Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
|
164
|
-
Requires-Dist: cryptography==45.0.
|
164
|
+
Requires-Dist: cryptography==45.0.5; python_version >= "3.9" and extra == "pdfminer"
|
165
165
|
Requires-Dist: cffi==1.17.1; extra == "pdfminer"
|
166
166
|
Requires-Dist: pycparser==2.22; extra == "pdfminer"
|
167
167
|
Provides-Extra: pillow
|
168
168
|
Requires-Dist: Pillow>=10.4.0; python_version < "3.9" and extra == "pillow"
|
169
|
-
Requires-Dist: Pillow>=11.
|
169
|
+
Requires-Dist: Pillow>=11.3.0; python_version >= "3.9" and extra == "pillow"
|
170
170
|
Provides-Extra: pip-system-certs
|
171
171
|
Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra == "pip-system-certs"
|
172
172
|
Provides-Extra: proxy
|