Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update UC Mode, JS methods, and dependencies #1992

Merged
merged 8 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/translations/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class 我的测试类(硒测试用例):
self.输入文本('input[name="search"]', "舞龍")
self.单击('button:contains("搜索")')
self.断言文本("舞龍", "#firstHeading")
self.断言元素('img[src*="Chinese_draak.jpg"]')
```

Here's another example:
Expand All @@ -36,6 +37,9 @@ class 私のテストクラス(セレニウムテストケース):
self.クリックして("#searchform button")
self.テキストを確認する("アニメ", "#firstHeading")
self.JS入力('input[name="search"]', "寿司")
self.クリックして("#searchform button")
self.テキストを確認する("寿司", "#firstHeading")
self.要素を確認する('img[alt="握り寿司"]')
```

<a id="translation_api"></a>
Expand Down
2 changes: 2 additions & 0 deletions examples/translations/chinese_test_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ def test_例子1(self):
self.单击('button:contains("搜索")')
self.断言文本("舞龍", "#firstHeading")
self.断言元素('img[src*="Chinese_draak.jpg"]')
self.回去()
self.输入文本('input[name="search"]', "麻婆豆腐")
self.单击('button:contains("搜索")')
self.断言文本("麻婆豆腐", "#firstHeading")
self.断言元素('figure:contains("一家中餐館的麻婆豆腐")')
self.回去()
self.输入文本('input[name="search"]', "精武英雄")
self.单击('button:contains("搜索")')
self.断言元素('img[src*="Fist_of_legend.jpg"]')
Expand Down
8 changes: 3 additions & 5 deletions examples/uc_cdp_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

if __name__ == "__main__":
from pytest import main
main([__file__, "--uc", "--uc-cdp", "--incognito", "-s"])
main([__file__, "--uc", "--uc-cdp", "-s"])


class CDPTests(BaseCase):
Expand All @@ -23,10 +23,8 @@ def fail_me(self):
self.fail('Selenium was detected! Try using: "pytest --uc"')

def test_display_cdp_events(self):
if not (self.undetectable and self.uc_cdp_events and self.incognito):
self.get_new_driver(
undetectable=True, uc_cdp_events=True, incognito=True
)
if not (self.undetectable and self.uc_cdp_events):
self.get_new_driver(undetectable=True, uc_cdp_events=True)
self.open("https://nowsecure.nl/#relax")
try:
self.verify_success()
Expand Down
8 changes: 4 additions & 4 deletions help_docs/method_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,17 +383,17 @@ self.scroll_to_bottom()

self.click_xpath(xpath)

self.js_click(selector, by="css selector", all_matches=False, scroll=True)
self.js_click(selector, by="css selector", all_matches=False, timeout=None, scroll=True)

self.js_click_if_present(selector, by="css selector", timeout=0)

self.js_click_if_visible(selector, by="css selector", timeout=0)

self.js_click_all(selector, by="css selector")
self.js_click_all(selector, by="css selector", timeout=None)

self.jquery_click(selector, by="css selector")
self.jquery_click(selector, by="css selector", timeout=None)

self.jquery_click_all(selector, by="css selector")
self.jquery_click_all(selector, by="css selector", timeout=None)

self.hide_element(selector, by="css selector")

Expand Down
2 changes: 2 additions & 0 deletions help_docs/syntax_formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,12 @@ class 我的测试类(硒测试用例):
self.单击('button:contains("搜索")')
self.断言文本("舞龍", "#firstHeading")
self.断言元素('img[src*="Chinese_draak.jpg"]')
self.回去()
self.输入文本('input[name="search"]', "麻婆豆腐")
self.单击('button:contains("搜索")')
self.断言文本("麻婆豆腐", "#firstHeading")
self.断言元素('figure:contains("一家中餐館的麻婆豆腐")')
self.回去()
self.输入文本('input[name="search"]', "精武英雄")
self.单击('button:contains("搜索")')
self.断言元素('img[src*="Fist_of_legend.jpg"]')
Expand Down
4 changes: 4 additions & 0 deletions help_docs/translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class 我的测试类(硒测试用例):
self.输入文本('input[name="search"]', "舞龍")
self.单击('button:contains("搜索")')
self.断言文本("舞龍", "#firstHeading")
self.断言元素('img[src*="Chinese_draak.jpg"]')
```

Here's another example:
Expand All @@ -38,6 +39,9 @@ class 私のテストクラス(セレニウムテストケース):
self.クリックして("#searchform button")
self.テキストを確認する("アニメ", "#firstHeading")
self.JS入力('input[name="search"]', "寿司")
self.クリックして("#searchform button")
self.テキストを確認する("寿司", "#firstHeading")
self.要素を確認する('img[alt="握り寿司"]')
```

<a id="translation_api"></a>
Expand Down
5 changes: 3 additions & 2 deletions mkdocs_build/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# mkdocs dependencies for generating the seleniumbase.io website
# Minimum Python version: 3.8 (for generating docs only)

regex>=2023.6.3
regex>=2023.8.8
pkginfo>=1.9.6
PyYAML>=6.0.1
readme-renderer>=40.0
Expand All @@ -11,6 +11,8 @@ pipdeptree>=2.12.0
bleach>=6.0.0
docutils>=0.20.1
python-dateutil>=2.8.2
tqdm>=4.65.2
nltk>=3.8.1
livereload==2.6.3
joblib==1.3.1
Markdown==3.4.4
Expand All @@ -19,7 +21,6 @@ Jinja2==3.1.2
click==8.1.6
ghp-import==2.1.0
lunr==0.6.2
nltk==3.8.1
tornado==6.3.2
watchdog==3.0.0
cairocffi==1.6.1
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ urllib3>=1.26.16,<2;python_version>="3.7" and python_version<"3.10"
urllib3>=1.26.16,<2.1.0;python_version>="3.10"
requests==2.27.1;python_version<"3.7"
requests==2.31.0;python_version>="3.7"
pynose==1.4.7
pynose==1.4.8
sniffio==1.3.0;python_version>="3.7"
h11==0.14.0;python_version>="3.7"
outcome==1.2.0;python_version>="3.7"
Expand Down Expand Up @@ -67,10 +67,10 @@ soupsieve==2.3.2.post1;python_version<"3.7"
soupsieve==2.4.1;python_version>="3.7"
beautifulsoup4==4.12.2
pygments==2.14.0;python_version<"3.7"
pygments==2.15.1;python_version>="3.7"
pygments==2.16.1;python_version>="3.7"
pyreadline3==3.4.1;platform_system=="Windows"
tabcompleter==1.2.1
pdbp==1.4.3
pdbp==1.4.4
colorama==0.4.5;python_version<"3.7"
colorama==0.4.6;python_version>="3.7"
exceptiongroup==1.1.2;python_version>="3.7"
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.17.1"
__version__ = "4.17.2"
47 changes: 29 additions & 18 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -5687,13 +5687,22 @@ def click_xpath(self, xpath):
self.click(xpath, by="xpath")

def js_click(
self, selector, by="css selector", all_matches=False, scroll=True
self,
selector,
by="css selector",
all_matches=False,
timeout=None,
scroll=True,
):
"""Clicks an element using JavaScript.
Can be used to click hidden / invisible elements.
If "all_matches" is False, only the first match is clicked.
If "scroll" is False, won't scroll unless running in Demo Mode."""
self.wait_for_ready_state_complete()
if not timeout or timeout is True:
timeout = settings.SMALL_TIMEOUT
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
if by == By.LINK_TEXT:
message = (
Expand All @@ -5706,7 +5715,7 @@ def js_click(
self.click(selector, by=by)
return
element = self.wait_for_element_present(
selector, by=by, timeout=settings.SMALL_TIMEOUT
selector, by=by, timeout=timeout
)
if not page_actions.is_element_clickable(self.driver, selector, by):
self.wait_for_ready_state_complete()
Expand Down Expand Up @@ -5818,9 +5827,7 @@ def js_click_if_present(self, selector, by="css selector", timeout=0):
self.js_click(selector, by=by)
elif timeout > 0:
try:
self.wait_for_element_present(
selector, by=by, timeout=timeout
)
self.wait_for_element_present(selector, by=by, timeout=timeout)
except Exception:
pass
if self.is_element_present(selector, by=by):
Expand All @@ -5836,27 +5843,29 @@ def js_click_if_visible(self, selector, by="css selector", timeout=0):
self.js_click(selector, by=by)
elif timeout > 0:
try:
self.wait_for_element_visible(
selector, by=by, timeout=timeout
)
self.wait_for_element_visible(selector, by=by, timeout=timeout)
except Exception:
pass
if self.is_element_visible(selector, by=by):
self.js_click(selector, by=by)

def js_click_all(self, selector, by="css selector"):
def js_click_all(self, selector, by="css selector", timeout=None):
"""Clicks all matching elements using pure JS. (No jQuery)"""
self.js_click(selector, by="css selector", all_matches=True)
self.js_click(
selector, by="css selector", all_matches=True, timeout=timeout
)

def jquery_click(self, selector, by="css selector"):
def jquery_click(self, selector, by="css selector", timeout=None):
"""Clicks an element using jQuery. (Different from using pure JS.)
Can be used to click hidden / invisible elements."""
self.__check_scope()
if not timeout or timeout is True:
timeout = settings.SMALL_TIMEOUT
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
original_selector = selector
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
self.wait_for_element_present(
selector, by=by, timeout=settings.SMALL_TIMEOUT
)
self.wait_for_element_present(selector, by=by, timeout=timeout)
if self.is_element_visible(selector, by=by):
self.__demo_mode_highlight_if_active(selector, by)
selector = self.convert_to_css_selector(selector, by=by)
Expand Down Expand Up @@ -5887,14 +5896,16 @@ def jquery_click(self, selector, by="css selector"):
self.safe_execute_script(click_script)
self.__demo_mode_pause_if_active()

def jquery_click_all(self, selector, by="css selector"):
def jquery_click_all(self, selector, by="css selector", timeout=None):
"""Clicks all matching elements using jQuery."""
self.__check_scope()
if not timeout or timeout is True:
timeout = settings.SMALL_TIMEOUT
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
original_selector = selector
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
self.wait_for_element_present(
selector, by=by, timeout=settings.SMALL_TIMEOUT
)
self.wait_for_element_present(selector, by=by, timeout=timeout)
if self.is_element_visible(selector, by=by):
self.__demo_mode_highlight_if_active(selector, by)
css_selector = self.convert_to_css_selector(selector, by=by)
Expand Down
19 changes: 10 additions & 9 deletions seleniumbase/undetected/patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ def gen_random_cdc():
def is_binary_patched(self, executable_path=None):
executable_path = executable_path or self.executable_path
with io.open(executable_path, "rb") as fh:
if b"window.cdc_adoQpoasnfa76pfcZLmcfl_" in fh.read():
if re.search(
b"window.cdc_adoQpoasnfa76pfcZLmcfl_"
b"(Array|Promise|Symbol|Object|Proxy)",
fh.read()
):
return False
return True

Expand All @@ -198,21 +202,18 @@ def gen_call_function_js_cache_name(match):
with io.open(self.executable_path, "r+b") as fh:
file_bin = fh.read()
file_bin = re.sub(
b"window\\.cdc_[a-zA-Z0-9]{22}_(Array|Promise|Symbol)"
b" = window\\.(Array|Promise|Symbol);",
b"window\\.cdc_[a-zA-Z0-9]{22}_"
b"(Array|Promise|Symbol|Object|Proxy)"
b" = window\\.(Array|Promise|Symbol|Object|Proxy);",
gen_js_whitespaces,
file_bin,
)
file_bin = re.sub(
b"window\\.cdc_[a-zA-Z0-9]{22}_(Array|Promise|Symbol) \\|\\|",
b"window\\.cdc_[a-zA-Z0-9]{22}_"
b"(Array|Promise|Symbol|Object|Proxy) \\|\\|",
gen_js_whitespaces,
file_bin,
)
file_bin = re.sub(
b"window\\.cdc_[a-zA-Z0-9]{22}_(Array|Promise|Symbol)",
b"window\\.ccd_adoQpoasnaf67pfcZLmcfl_(Array|Promise|Symbol)",
file_bin,
)
file_bin = re.sub(
b"'\\$cdc_[a-zA-Z0-9]{22}_';",
gen_call_function_js_cache_name,
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
'urllib3>=1.26.16,<2.1.0;python_version>="3.10"',
'requests==2.27.1;python_version<"3.7"',
'requests==2.31.0;python_version>="3.7"',
"pynose==1.4.7",
"pynose==1.4.8",
'sniffio==1.3.0;python_version>="3.7"',
'h11==0.14.0;python_version>="3.7"',
'outcome==1.2.0;python_version>="3.7"',
Expand Down Expand Up @@ -201,10 +201,10 @@
'soupsieve==2.4.1;python_version>="3.7"',
"beautifulsoup4==4.12.2",
'pygments==2.14.0;python_version<"3.7"',
'pygments==2.15.1;python_version>="3.7"',
'pygments==2.16.1;python_version>="3.7"',
'pyreadline3==3.4.1;platform_system=="Windows"',
"tabcompleter==1.2.1",
"pdbp==1.4.3",
"pdbp==1.4.4",
'colorama==0.4.5;python_version<"3.7"',
'colorama==0.4.6;python_version>="3.7"',
'exceptiongroup==1.1.2;python_version>="3.7"',
Expand Down