Merge pull request #2257 from seleniumbase/some-improvements
Some improvements
This commit is contained in:
commit
62e7a04363
|
@ -1,10 +1,18 @@
|
|||
"""google.com example test that uses page objects"""
|
||||
from seleniumbase import BaseCase
|
||||
from .google_objects import HomePage, ResultsPage
|
||||
try:
|
||||
from .google_objects import HomePage, ResultsPage
|
||||
except Exception:
|
||||
from google_objects import HomePage, ResultsPage
|
||||
BaseCase.main(__name__, __file__)
|
||||
|
||||
|
||||
class GoogleTests(BaseCase):
|
||||
def test_google_dot_com(self):
|
||||
if self.headless and self._multithreaded:
|
||||
self.open_if_not_url("about:blank")
|
||||
print("Skipping test in headless multi-threaded mode.")
|
||||
self.skip("Skipping test in headless multi-threaded mode.")
|
||||
self.open("https://google.com/ncr")
|
||||
self.assert_title_contains("Google")
|
||||
self.sleep(0.05)
|
||||
|
|
|
@ -33,6 +33,10 @@ class SeleniumBaseIOPage:
|
|||
|
||||
class MyTests(BaseCase):
|
||||
def test_page_objects(self):
|
||||
if self.headless and self._multithreaded:
|
||||
self.open_if_not_url("about:blank")
|
||||
print("Skipping test in headless multi-threaded mode.")
|
||||
self.skip("Skipping test in headless multi-threaded mode.")
|
||||
search_term = "SeleniumBase.io Docs"
|
||||
expected_text = "SeleniumBase"
|
||||
GooglePage().go_to_google(self)
|
||||
|
|
|
@ -4,9 +4,18 @@ BaseCase.main(__name__, __file__)
|
|||
|
||||
class LocaleCodeTests(BaseCase):
|
||||
def test_locale_code(self):
|
||||
self.open("https://localeplanet.com/support/browser.html")
|
||||
locale_code = self.get_locale_code()
|
||||
self.open("about:blank")
|
||||
locale_code = self.get_locale_code() # navigator.language
|
||||
print("\nYour Browser's Locale Code: %s" % locale_code)
|
||||
expected_text = "navigator.language: %s" % locale_code
|
||||
self.demo_mode = True # Display test actions
|
||||
self.assert_text(expected_text, "pre")
|
||||
if self.browser == "chrome" and not self.headless:
|
||||
self.open("chrome://settings/languages")
|
||||
language_info = self.get_text(
|
||||
"settings-ui::shadow "
|
||||
"settings-main::shadow "
|
||||
"settings-basic-page::shadow "
|
||||
"settings-languages-page::shadow "
|
||||
"#languagesSection div.start div"
|
||||
)
|
||||
print("Language info (chrome://settings/languages):")
|
||||
print(language_info)
|
||||
self.sleep(1)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
from seleniumbase import SB
|
||||
|
||||
|
||||
def click_turnstile_and_verify(sb):
|
||||
sb.driver.reconnect(0.1)
|
||||
iframe = sb.driver.find_element("iframe")
|
||||
sb.driver.reconnect(0.5)
|
||||
sb.driver.switch_to.frame(iframe)
|
||||
sb.driver.uc_click("span.mark")
|
||||
sb.highlight("img#captcha-success", timeout=3.33)
|
||||
|
||||
|
||||
with SB(uc=True, test=True) as sb:
|
||||
sb.driver.uc_open_with_reconnect(
|
||||
"https://seleniumbase.io/apps/form_turnstile",
|
||||
reconnect_time=2.33,
|
||||
)
|
||||
try:
|
||||
click_turnstile_and_verify(sb)
|
||||
except Exception:
|
||||
sb.driver.uc_open_with_reconnect(
|
||||
"https://seleniumbase.io/apps/form_turnstile",
|
||||
reconnect_time=2.33,
|
||||
)
|
||||
click_turnstile_and_verify(sb)
|
||||
sb.press_keys("#name", "SeleniumBase")
|
||||
sb.press_keys("#email", "test@test.test")
|
||||
sb.press_keys("#phone", "1-555-555-5555")
|
||||
sb.click('[for="date"]')
|
||||
sb.click("td.is-today button")
|
||||
sb.click('div[class="select-wrapper"] input')
|
||||
sb.click('span:contains("9:00 PM")')
|
||||
sb.highlight_click('input[value="AR"] + span')
|
||||
sb.click('input[value="cc"] + span')
|
||||
sb.highlight_click('button:contains("Request & Pay")')
|
||||
sb.highlight("img#submit-success")
|
||||
sb.highlight('button:contains("Success!")')
|
|
@ -0,0 +1,16 @@
|
|||
from seleniumbase import SB
|
||||
|
||||
with SB(uc=True, test=True) as sb:
|
||||
sb.driver.uc_open_with_reconnect(
|
||||
"https://seleniumbase.io/apps/turnstile",
|
||||
reconnect_time=2.33,
|
||||
)
|
||||
sb.driver.reconnect(0.1)
|
||||
iframe = sb.driver.find_element("iframe")
|
||||
sb.driver.reconnect(0.5)
|
||||
sb.driver.switch_to.frame(iframe)
|
||||
sb.driver.uc_click("span.mark")
|
||||
sb.switch_to_default_content()
|
||||
sb.assert_element("img#captcha-success", timeout=3.33)
|
||||
sb.set_messenger_theme(location="top_left")
|
||||
sb.post_message("Selenium wasn't detected!", duration=3)
|
|
@ -0,0 +1,28 @@
|
|||
from seleniumbase import BaseCase
|
||||
BaseCase.main(__name__, __file__)
|
||||
|
||||
|
||||
class CDPNetworkBlockingTests(BaseCase):
|
||||
def test_cdp_network_blocking(self):
|
||||
if not self.is_chromium:
|
||||
self.skip("This test is only for Chromium browsers!")
|
||||
self.execute_cdp_cmd(
|
||||
'Network.setBlockedURLs', {"urls": [
|
||||
"*googlesyndication.com*",
|
||||
"*doubleclick.net*",
|
||||
"*adsafeprotected.com*",
|
||||
"*2mdn.net*",
|
||||
"*googletagmanager.com*",
|
||||
"*adsafeprotected.com*",
|
||||
"*snigelweb.com*",
|
||||
"*fastclick.net*",
|
||||
"*amazon-adsystem.com*",
|
||||
"*google-analytics.com*",
|
||||
]})
|
||||
self.execute_cdp_cmd('Network.enable', {})
|
||||
self.open('https://www.w3schools.com/jquery/default.asp')
|
||||
source = self.get_page_source()
|
||||
self.assert_true("doubleclick.net" not in source)
|
||||
self.assert_true("google-analytics.com" not in source)
|
||||
if self.demo_mode:
|
||||
self.post_message("Blocking was successful!")
|
|
@ -5,6 +5,7 @@
|
|||
import pytest
|
||||
from parameterized import parameterized
|
||||
from seleniumbase import BaseCase
|
||||
BaseCase.main(__name__, __file__, "-n6")
|
||||
|
||||
url = "data:text/html,<h2>Hello</h2><p><input /> <button>OK!</button></p>"
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ class 我的测试类(硒测试用例):
|
|||
self.开启("https://zh.wikipedia.org/wiki/")
|
||||
self.断言标题("维基百科,自由的百科全书")
|
||||
self.断言元素('a[title="Wikipedia:关于"]')
|
||||
self.断言元素('span:contains("创建账号")')
|
||||
self.断言元素('span:contains("登录")')
|
||||
self.断言文本("新闻动态", "span#新闻动态")
|
||||
self.输入文本('input[name="search"]', "舞龍")
|
||||
self.单击('button:contains("搜索")')
|
||||
|
|
|
@ -8,6 +8,8 @@ class 我的测试类(硒测试用例):
|
|||
self.开启("https://zh.wikipedia.org/wiki/")
|
||||
self.断言标题("维基百科,自由的百科全书")
|
||||
self.断言元素('a[title="Wikipedia:关于"]')
|
||||
self.断言元素('span:contains("创建账号")')
|
||||
self.断言元素('span:contains("登录")')
|
||||
self.断言文本("新闻动态", "span#新闻动态")
|
||||
self.输入文本('input[name="search"]', "舞龍")
|
||||
self.单击('button:contains("搜索")')
|
||||
|
|
|
@ -363,13 +363,14 @@ self.bring_active_window_to_front()
|
|||
|
||||
self.bring_to_front(selector, by="css selector")
|
||||
|
||||
self.highlight_click(selector, by="css selector", loops=3, scroll=True)
|
||||
self.highlight_click(selector, by="css selector", loops=3, scroll=True, timeout=None)
|
||||
|
||||
self.highlight_type(selector, text, by="css selector", loops=3, scroll=True)
|
||||
self.highlight_type(selector, text, by="css selector", loops=3, scroll=True, timeout=None)
|
||||
# Duplicates:
|
||||
# self.highlight_update_text(selector, text, by="css selector", loops=3, scroll=True)
|
||||
# self.highlight_update_text(
|
||||
# selector, text, by="css selector", loops=3, scroll=True, timeout=None)
|
||||
|
||||
self.highlight(selector, by="css selector", loops=4, scroll=True)
|
||||
self.highlight(selector, by="css selector", loops=4, scroll=True, timeout=None)
|
||||
|
||||
self.press_up_arrow(selector="html", times=1, by="css selector")
|
||||
|
||||
|
@ -1025,6 +1026,7 @@ driver.uc_click(selector)
|
|||
* [test_login.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_login.py)
|
||||
* [test_markers.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_markers.py)
|
||||
* [test_swag_labs.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_swag_labs.py)
|
||||
* [test_simple_login.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_simple_login.py)
|
||||
* [test_suite.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_suite.py)
|
||||
* [test_tinymce.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_tinymce.py)
|
||||
* And many more...
|
||||
|
|
|
@ -450,6 +450,8 @@ class 我的测试类(硒测试用例):
|
|||
self.开启("https://zh.wikipedia.org/wiki/")
|
||||
self.断言标题("维基百科,自由的百科全书")
|
||||
self.断言元素('a[title="Wikipedia:关于"]')
|
||||
self.断言元素('span:contains("创建账号")')
|
||||
self.断言元素('span:contains("登录")')
|
||||
self.断言文本("新闻动态", "span#新闻动态")
|
||||
self.输入文本('input[name="search"]', "舞龍")
|
||||
self.单击('button:contains("搜索")')
|
||||
|
@ -973,6 +975,8 @@ finally:
|
|||
|
||||
The ``Driver()`` manager format can be used as a drop-in replacement for virtually every Python/selenium framework, as it uses the raw ``driver`` instance for handling commands. The ``Driver()`` method simplifies the work of managing drivers with optimal settings, and it can be configured with multiple args. The ``Driver()`` also accepts command-line options (such as ``python --headless``) so that you don't need to modify your tests directly to use different settings. These command-line options only take effect if the associated method args remain unset (or set to ``None``) for the specified options.
|
||||
|
||||
When using the ``Driver()`` format, you may need to activate a Virtual Display on your own if you want to run headed tests in a headless Linux environment. (See https://github.com/mdmintz/sbVirtualDisplay for details.) One such example of this is using an authenticated proxy, which is configured via a Chrome extension that is generated at runtime. (Note that regular headless mode in Chrome doesn't support extensions.)
|
||||
|
||||
--------
|
||||
|
||||
<h3 align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/img/sb_logo_10.png" title="SeleniumBase" width="280" /></a></h3>
|
||||
|
|
|
@ -17,6 +17,8 @@ class 我的测试类(硒测试用例):
|
|||
self.开启("https://zh.wikipedia.org/wiki/")
|
||||
self.断言标题("维基百科,自由的百科全书")
|
||||
self.断言元素('a[title="Wikipedia:关于"]')
|
||||
self.断言元素('span:contains("创建账号")')
|
||||
self.断言元素('span:contains("登录")')
|
||||
self.断言文本("新闻动态", "span#新闻动态")
|
||||
self.输入文本('input[name="search"]', "舞龍")
|
||||
self.单击('button:contains("搜索")')
|
||||
|
|
|
@ -152,6 +152,11 @@ nav:
|
|||
- ↔️ W3Schools drag & drop: https://seleniumbase.io/w3schools/drag_drop
|
||||
- ☑️ W3Schools checkboxes: https://seleniumbase.io/w3schools/checkboxes
|
||||
- 🔘 W3Schools radio buttons: https://seleniumbase.io/w3schools/radio_buttons
|
||||
- Pages with CAPTCHAs:
|
||||
- 🔑 CF Turnstile Test: https://seleniumbase.io/apps/turnstile
|
||||
- 🔑 CF Turnstile on Form: https://seleniumbase.io/apps/form_turnstile
|
||||
- 🔐 reCAPTCHA v2 Test: https://seleniumbase.io/apps/recaptcha
|
||||
- 🔐 reCAPTCHA v2 on Form: https://seleniumbase.io/apps/form_recaptcha
|
||||
- Additional Help Docs:
|
||||
- 📑 Table of Contents: help_docs/ReadMe.md
|
||||
- 🖼️ How to handle iframes: help_docs/handling_iframes.md
|
||||
|
|
|
@ -20,7 +20,7 @@ paginate==0.5.6
|
|||
pyquery==2.0.0
|
||||
readtime==3.0.0
|
||||
mkdocs==1.5.3
|
||||
mkdocs-material==9.4.7
|
||||
mkdocs-material==9.4.8
|
||||
mkdocs-exclude-search==0.6.5
|
||||
mkdocs-simple-hooks==0.1.5
|
||||
mkdocs-material-extensions==1.3
|
||||
|
|
|
@ -21,11 +21,12 @@ pynose==1.4.8
|
|||
sniffio==1.3.0
|
||||
h11==0.14.0
|
||||
outcome==1.3.0.post0
|
||||
trio==0.22.2
|
||||
trio==0.22.2;python_version<"3.8"
|
||||
trio==0.23.1;python_version>="3.8"
|
||||
trio-websocket==0.11.1
|
||||
wsproto==1.2.0
|
||||
selenium==4.11.2;python_version<"3.8"
|
||||
selenium==4.14.0;python_version>="3.8"
|
||||
selenium==4.15.2;python_version>="3.8"
|
||||
cssselect==1.2.0
|
||||
sortedcontainers==2.4.0
|
||||
fasteners==0.19
|
||||
|
@ -41,7 +42,7 @@ pytest-ordering==0.6
|
|||
pytest-rerunfailures==12.0
|
||||
pytest-xdist==3.3.1
|
||||
parameterized==0.9.0
|
||||
sbvirtualdisplay==1.2.0
|
||||
sbvirtualdisplay==1.3.0
|
||||
behave==1.2.6
|
||||
soupsieve==2.4.1;python_version<"3.8"
|
||||
soupsieve==2.5;python_version>="3.8"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "4.20.9"
|
||||
__version__ = "4.21.0"
|
||||
|
|
|
@ -308,14 +308,18 @@ def find_edgedriver_version_to_use(use_version, driver_version):
|
|||
|
||||
def has_cf(text):
|
||||
if (
|
||||
"<title>Just a moment...</title>" in text
|
||||
or "<title>403 Forbidden</title>" in text
|
||||
"<title>403 Forbidden</title>" in text
|
||||
or "Permission Denied</title>" in text
|
||||
or 'id="challenge-error-text"' in text
|
||||
or "<title>Just a moment..." in text
|
||||
or 'action="/?__cf_chl_f_tk' in text
|
||||
or 'src="chromedriver.js"' in text
|
||||
or 'class="g-recaptcha"' in text
|
||||
or 'content="Pixelscan"' in text
|
||||
or 'id="challenge-form"' in text
|
||||
or "window._cf_chl_opt" in text
|
||||
or "/recaptcha/api.js" in text
|
||||
or "/turnstile/" in text
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
@ -427,11 +431,24 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None):
|
|||
|
||||
|
||||
def uc_click(
|
||||
driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
|
||||
driver,
|
||||
selector,
|
||||
by="css selector",
|
||||
timeout=settings.SMALL_TIMEOUT,
|
||||
reconnect_time=None,
|
||||
):
|
||||
try:
|
||||
rct = float(by) # Add shortcut: driver.uc_click(selector, RCT)
|
||||
if not reconnect_time:
|
||||
reconnect_time = rct
|
||||
by = "css selector"
|
||||
except Exception:
|
||||
pass
|
||||
element = driver.wait_for_element(selector, by=by, timeout=timeout)
|
||||
try:
|
||||
element.uc_click()
|
||||
element.uc_click(
|
||||
driver, selector, by=by, reconnect_time=reconnect_time
|
||||
)
|
||||
except ElementClickInterceptedException:
|
||||
driver.js_click(selector, by=by, timeout=timeout)
|
||||
|
||||
|
@ -2876,7 +2893,7 @@ def get_local_driver(
|
|||
disable_build_check = True
|
||||
uc_driver_version = None
|
||||
if is_using_uc(undetectable, browser_name):
|
||||
if use_br_version_for_uc:
|
||||
if use_br_version_for_uc or driver_version == "mlatest":
|
||||
uc_driver_version = get_uc_driver_version(full=True)
|
||||
full_ch_driver_version = uc_driver_version
|
||||
else:
|
||||
|
|
|
@ -315,6 +315,10 @@ class BaseCase(unittest.TestCase):
|
|||
self.driver.get(url)
|
||||
else:
|
||||
pass # Odd issue where the open did happen. Continue.
|
||||
elif "invalid session id" in e.msg:
|
||||
logging.debug("Invalid session id. Will open new browser.")
|
||||
self.driver = self.get_new_driver()
|
||||
self.driver.get(url)
|
||||
else:
|
||||
raise
|
||||
if (
|
||||
|
@ -625,22 +629,22 @@ class BaseCase(unittest.TestCase):
|
|||
except Exception:
|
||||
pass
|
||||
if self.__needs_minimum_wait() or self.browser == "safari":
|
||||
time.sleep(0.04)
|
||||
time.sleep(0.045)
|
||||
try:
|
||||
if self.driver.current_url != pre_action_url:
|
||||
self.__ad_block_as_needed()
|
||||
self.__disable_beforeunload_as_needed()
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.06)
|
||||
time.sleep(0.075)
|
||||
except Exception:
|
||||
try:
|
||||
self.wait_for_ready_state_complete()
|
||||
except Exception:
|
||||
pass
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.04)
|
||||
time.sleep(0.05)
|
||||
else:
|
||||
time.sleep(0.08)
|
||||
time.sleep(0.085)
|
||||
if self.demo_mode:
|
||||
if self.driver.current_url != pre_action_url:
|
||||
if not js_utils.is_jquery_activated(self.driver):
|
||||
|
@ -900,7 +904,7 @@ class BaseCase(unittest.TestCase):
|
|||
if not self.demo_mode and not self.slow_mode:
|
||||
self.__scroll_to_element(element, selector, by)
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.02)
|
||||
time.sleep(0.04)
|
||||
try:
|
||||
element.clear() # May need https://stackoverflow.com/a/50691625
|
||||
backspaces = Keys.BACK_SPACE * 42 # Is the answer to everything
|
||||
|
@ -1580,6 +1584,9 @@ class BaseCase(unittest.TestCase):
|
|||
return
|
||||
if not self.is_link_text_present(link_text):
|
||||
self.wait_for_link_text_present(link_text, timeout=timeout)
|
||||
if not self.demo_mode and not self.slow_mode:
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.04)
|
||||
pre_action_url = None
|
||||
try:
|
||||
pre_action_url = self.driver.current_url
|
||||
|
@ -1668,6 +1675,8 @@ class BaseCase(unittest.TestCase):
|
|||
self.__demo_mode_pause_if_active(tiny=True)
|
||||
elif self.slow_mode:
|
||||
self.__slow_mode_pause_if_active()
|
||||
elif self.__needs_minimum_wait():
|
||||
time.sleep(0.04)
|
||||
|
||||
def click_partial_link_text(self, partial_link_text, timeout=None):
|
||||
"""This method clicks the partial link text on a page."""
|
||||
|
@ -5499,29 +5508,50 @@ class BaseCase(unittest.TestCase):
|
|||
self.execute_script(script)
|
||||
|
||||
def highlight_click(
|
||||
self, selector, by="css selector", loops=3, scroll=True
|
||||
self, selector, by="css selector", loops=3, scroll=True, timeout=None,
|
||||
):
|
||||
"""Highlights the element and then clicks it."""
|
||||
self.__check_scope()
|
||||
if not timeout:
|
||||
timeout = settings.SMALL_TIMEOUT
|
||||
self.wait_for_element_visible(selector, by=by, timeout=timeout)
|
||||
if not self.demo_mode:
|
||||
self.__highlight(selector, by=by, loops=loops, scroll=scroll)
|
||||
self.click(selector, by=by)
|
||||
|
||||
def highlight_update_text(
|
||||
self, selector, text, by="css selector", loops=3, scroll=True
|
||||
self,
|
||||
selector,
|
||||
text,
|
||||
by="css selector",
|
||||
loops=3,
|
||||
scroll=True,
|
||||
timeout=None,
|
||||
):
|
||||
"""Highlights the element and then types text into the field."""
|
||||
self.__check_scope()
|
||||
if not timeout:
|
||||
timeout = settings.SMALL_TIMEOUT
|
||||
self.wait_for_element_visible(selector, by=by, timeout=timeout)
|
||||
if not self.demo_mode:
|
||||
self.__highlight(selector, by=by, loops=loops, scroll=scroll)
|
||||
self.update_text(selector, text, by=by)
|
||||
|
||||
def highlight_type(
|
||||
self, selector, text, by="css selector", loops=3, scroll=True
|
||||
self,
|
||||
selector,
|
||||
text,
|
||||
by="css selector",
|
||||
loops=3,
|
||||
scroll=True,
|
||||
timeout=None,
|
||||
):
|
||||
"""Same as self.highlight_update_text()
|
||||
As above, highlights the element and then types text into the field."""
|
||||
self.__check_scope()
|
||||
if not timeout:
|
||||
timeout = settings.SMALL_TIMEOUT
|
||||
self.wait_for_element_visible(selector, by=by, timeout=timeout)
|
||||
if not self.demo_mode:
|
||||
self.__highlight(selector, by=by, loops=loops, scroll=scroll)
|
||||
self.update_text(selector, text, by=by)
|
||||
|
@ -5604,15 +5634,26 @@ class BaseCase(unittest.TestCase):
|
|||
pass # JQuery probably couldn't load. Skip highlighting.
|
||||
time.sleep(0.065)
|
||||
|
||||
def highlight(self, selector, by="css selector", loops=None, scroll=True):
|
||||
def highlight(
|
||||
self,
|
||||
selector,
|
||||
by="css selector",
|
||||
loops=None,
|
||||
scroll=True,
|
||||
timeout=None,
|
||||
):
|
||||
"""This method uses fancy JavaScript to highlight an element.
|
||||
@Params
|
||||
selector - the selector of the element to find
|
||||
by - the type of selector to search by (Default: CSS)
|
||||
loops - # of times to repeat the highlight animation
|
||||
(Default: 4. Each loop lasts for about 0.2s)
|
||||
scroll - the option to scroll to the element first (Default: True) """
|
||||
scroll - the option to scroll to the element first (Default: True)
|
||||
timeout - the time to wait for the element to appear """
|
||||
self.__check_scope()
|
||||
if not timeout:
|
||||
timeout = settings.SMALL_TIMEOUT
|
||||
self.wait_for_element_visible(selector, by=by, timeout=timeout)
|
||||
self.__highlight(selector=selector, by=by, loops=loops, scroll=scroll)
|
||||
if self.recorder_mode and self.__current_url_is_recordable():
|
||||
if self.get_session_storage_item("pause_recorder") == "no":
|
||||
|
@ -7827,6 +7868,11 @@ class BaseCase(unittest.TestCase):
|
|||
self.__demo_mode_highlight_if_active(original_selector, by)
|
||||
if scroll and not self.demo_mode and not self.slow_mode:
|
||||
self.scroll_to(original_selector, by=by, timeout=timeout)
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.04)
|
||||
if not scroll and not self.demo_mode and not self.slow_mode:
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.06)
|
||||
text = self.__get_type_checked_text(text)
|
||||
value = re.escape(text)
|
||||
value = self.__escape_quotes_if_needed(value)
|
||||
|
@ -7895,6 +7941,9 @@ class BaseCase(unittest.TestCase):
|
|||
except Exception:
|
||||
pass
|
||||
self.__demo_mode_pause_if_active()
|
||||
if not self.demo_mode and not self.slow_mode:
|
||||
if self.__needs_minimum_wait():
|
||||
time.sleep(0.04)
|
||||
|
||||
def js_update_text(self, selector, text, by="css selector", timeout=None):
|
||||
"""JavaScript + send_keys are used to update a text field.
|
||||
|
|
|
@ -10,6 +10,7 @@ class Environment:
|
|||
DEVELOP = "develop"
|
||||
PRODUCTION = "production"
|
||||
PERFORMANCE = "performance"
|
||||
REPLICA = "replica"
|
||||
FEDRAMP = "fedramp"
|
||||
OFFLINE = "offline"
|
||||
ONLINE = "online"
|
||||
|
@ -37,6 +38,7 @@ class ValidEnvs:
|
|||
"develop",
|
||||
"production",
|
||||
"performance",
|
||||
"replica",
|
||||
"fedramp",
|
||||
"offline",
|
||||
"online",
|
||||
|
|
|
@ -863,14 +863,15 @@ def set_messenger_theme(
|
|||
try:
|
||||
driver.execute_script(msg_style)
|
||||
except Exception:
|
||||
time.sleep(0.05)
|
||||
time.sleep(0.03)
|
||||
activate_messenger(driver)
|
||||
time.sleep(0.05)
|
||||
time.sleep(0.15)
|
||||
try:
|
||||
driver.execute_script(msg_style)
|
||||
time.sleep(0.02)
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def post_message(driver, message, msg_dur=None, style="info"):
|
||||
|
|
|
@ -51,6 +51,7 @@ class Base(Plugin):
|
|||
constants.Environment.DEVELOP,
|
||||
constants.Environment.PRODUCTION,
|
||||
constants.Environment.PERFORMANCE,
|
||||
constants.Environment.REPLICA,
|
||||
constants.Environment.FEDRAMP,
|
||||
constants.Environment.OFFLINE,
|
||||
constants.Environment.ONLINE,
|
||||
|
|
|
@ -33,6 +33,7 @@ class DBReporting(Plugin):
|
|||
constants.Environment.DEVELOP,
|
||||
constants.Environment.PRODUCTION,
|
||||
constants.Environment.PERFORMANCE,
|
||||
constants.Environment.REPLICA,
|
||||
constants.Environment.FEDRAMP,
|
||||
constants.Environment.OFFLINE,
|
||||
constants.Environment.ONLINE,
|
||||
|
|
|
@ -88,7 +88,7 @@ def Driver(
|
|||
undetectable=None, # Use undetected-chromedriver to evade bot-detection.
|
||||
uc_cdp_events=None, # Capture CDP events in undetected-chromedriver mode.
|
||||
uc_subprocess=None, # Use undetected-chromedriver as a subprocess.
|
||||
log_cdp_events=None, # capture {"performance": "ALL", "browser": "ALL"})
|
||||
log_cdp_events=None, # Capture {"performance": "ALL", "browser": "ALL"}
|
||||
no_sandbox=None, # (DEPRECATED) - "--no-sandbox" is always used now.
|
||||
disable_gpu=None, # (DEPRECATED) - GPU is disabled if not "swiftshader".
|
||||
incognito=None, # Enable Chromium's Incognito mode.
|
||||
|
@ -105,8 +105,8 @@ def Driver(
|
|||
firefox_arg=None, # "ARG=N,ARG2" (Set Firefox args, comma-separated.)
|
||||
firefox_pref=None, # SET (Set Firefox PREFERENCE:VALUE set, ","-separated)
|
||||
user_data_dir=None, # Set the Chrome user data directory to use.
|
||||
extension_zip=None, # Load a Chrome Extension .zip|.crx, comma-separated.)
|
||||
extension_dir=None, # Load a Chrome Extension directory, comma-separated.)
|
||||
extension_zip=None, # Load a Chrome Extension .zip|.crx, comma-separated.
|
||||
extension_dir=None, # Load a Chrome Extension directory, comma-separated.
|
||||
binary_location=None, # Set path of the Chromium browser binary to use.
|
||||
driver_version=None, # Set the chromedriver or uc_driver version to use.
|
||||
page_load_strategy=None, # Set Chrome PLS to "normal", "eager", or "none".
|
||||
|
|
|
@ -372,6 +372,7 @@ def pytest_addoption(parser):
|
|||
constants.Environment.DEVELOP,
|
||||
constants.Environment.PRODUCTION,
|
||||
constants.Environment.PERFORMANCE,
|
||||
constants.Environment.REPLICA,
|
||||
constants.Environment.FEDRAMP,
|
||||
constants.Environment.OFFLINE,
|
||||
constants.Environment.ONLINE,
|
||||
|
|
|
@ -54,7 +54,7 @@ def SB(
|
|||
undetectable=None, # Use undetected-chromedriver to evade bot-detection.
|
||||
uc_cdp_events=None, # Capture CDP events in undetected-chromedriver mode.
|
||||
uc_subprocess=None, # Use undetected-chromedriver as a subprocess.
|
||||
log_cdp_events=None, # capture {"performance": "ALL", "browser": "ALL"})
|
||||
log_cdp_events=None, # Capture {"performance": "ALL", "browser": "ALL"}
|
||||
incognito=None, # Enable Chromium's Incognito mode.
|
||||
guest_mode=None, # Enable Chromium's Guest mode.
|
||||
dark_mode=None, # Enable Chromium's Dark mode.
|
||||
|
|
|
@ -330,18 +330,23 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
return object.__dir__(self)
|
||||
|
||||
def _get_cdc_props(self):
|
||||
return self.execute_script(
|
||||
"""
|
||||
let objectToInspect = window,
|
||||
result = [];
|
||||
while(objectToInspect !== null)
|
||||
{ result = result.concat(
|
||||
Object.getOwnPropertyNames(objectToInspect)
|
||||
);
|
||||
objectToInspect = Object.getPrototypeOf(objectToInspect); }
|
||||
return result.filter(i => i.match(/^[a-z]{3}_[a-z]{22}_.*/i))
|
||||
"""
|
||||
)
|
||||
cdc_props = []
|
||||
try:
|
||||
cdc_props = self.execute_script(
|
||||
"""
|
||||
let objectToInspect = window,
|
||||
result = [];
|
||||
while(objectToInspect !== null)
|
||||
{ result = result.concat(
|
||||
Object.getOwnPropertyNames(objectToInspect)
|
||||
);
|
||||
objectToInspect = Object.getPrototypeOf(objectToInspect); }
|
||||
return result.filter(i => i.match(/^[a-z]{3}_[a-z]{22}_.*/i))
|
||||
"""
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
return cdc_props
|
||||
|
||||
def _hook_remove_cdc_props(self, cdc_props):
|
||||
if len(cdc_props) < 1:
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
import selenium.webdriver.remote.webelement
|
||||
from seleniumbase.config import settings
|
||||
|
||||
|
||||
class WebElement(selenium.webdriver.remote.webelement.WebElement):
|
||||
def uc_click(self):
|
||||
super().click()
|
||||
if (
|
||||
hasattr(settings, "PAGE_LOAD_STRATEGY")
|
||||
and settings.PAGE_LOAD_STRATEGY == "none"
|
||||
):
|
||||
pass
|
||||
def uc_click(
|
||||
self,
|
||||
driver=None,
|
||||
selector=None,
|
||||
by=None,
|
||||
reconnect_time=None,
|
||||
):
|
||||
if driver and selector and by:
|
||||
driver.js_click(selector, by=by, timeout=1)
|
||||
else:
|
||||
super().click()
|
||||
if not reconnect_time:
|
||||
self._parent.reconnect(0.1)
|
||||
else:
|
||||
self._parent.reconnect(reconnect_time)
|
||||
|
||||
def uc_reconnect(self, reconnect_time=None):
|
||||
if not reconnect_time:
|
||||
self._parent.reconnect(0.1)
|
||||
else:
|
||||
self._parent.reconnect(reconnect_time)
|
||||
|
|
7
setup.py
7
setup.py
|
@ -154,11 +154,12 @@ setup(
|
|||
'sniffio==1.3.0',
|
||||
'h11==0.14.0',
|
||||
'outcome==1.3.0.post0',
|
||||
'trio==0.22.2',
|
||||
'trio==0.22.2;python_version<"3.8"',
|
||||
'trio==0.23.1;python_version>="3.8"',
|
||||
'trio-websocket==0.11.1',
|
||||
'wsproto==1.2.0',
|
||||
'selenium==4.11.2;python_version<"3.8"',
|
||||
'selenium==4.14.0;python_version>="3.8"',
|
||||
'selenium==4.15.2;python_version>="3.8"',
|
||||
'cssselect==1.2.0',
|
||||
"sortedcontainers==2.4.0",
|
||||
'fasteners==0.19',
|
||||
|
@ -174,7 +175,7 @@ setup(
|
|||
'pytest-rerunfailures==12.0',
|
||||
'pytest-xdist==3.3.1',
|
||||
'parameterized==0.9.0',
|
||||
"sbvirtualdisplay==1.2.0",
|
||||
"sbvirtualdisplay==1.3.0",
|
||||
"behave==1.2.6",
|
||||
'soupsieve==2.4.1;python_version<"3.8"',
|
||||
'soupsieve==2.5;python_version>="3.8"',
|
||||
|
|
Loading…
Reference in New Issue