Skip to content

Fix issue with UC Mode #2667

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

Merged
merged 5 commits into from
Apr 5, 2024
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
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@

<h1>SeleniumBase</h1>

<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_gs.png" alt="SeleniumBase" title="SeleniumBase" width="500" /></a></p>
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_i.png" alt="SeleniumBase" title="SeleniumBase" width="400" /></a></p>

<h3 align="center" class="hero__title"><b>End-to-end testing for the next generation.</b></h3>

<h4 align="center"><b>Overcome your greatest browser automation challenges.</b></h4>
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Testing / Scraping / Stealth</b></p>

<p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/releases" target="_blank"><img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=22AAEE" alt="GitHub version" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://img.shields.io/gitter/room/seleniumbase/SeleniumBase.svg" alt="Gitter chat"/></a></p>

Expand Down Expand Up @@ -57,15 +56,19 @@

--------

📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder.
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).

👤 Note that <span translate="no">SeleniumBase</span> <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode / Stealth Mode has its own ReadMe</a>.

ℹ️ Scripts can be called via <code translate="no"><b>python</b></code>, although some <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover & collect tests automatically).

<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>, which tests login, shopping, and checkout:</p>

```bash
pytest my_first_test.py
```

<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="550" /></a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="520" /></a>

> ``pytest`` uses ``--chrome`` by default unless set differently.

Expand All @@ -77,7 +80,7 @@ pytest my_first_test.py
pytest test_coffee_cart.py --demo
```

<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="550" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="520" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>

> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>

Expand All @@ -91,7 +94,7 @@ pytest test_coffee_cart.py --demo
pytest test_demo_site.py
```

<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="550" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="520" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>

> Easy to type, click, select, toggle, drag & drop, and more.

Expand Down Expand Up @@ -394,7 +397,7 @@ cd examples/
pytest my_first_test.py
```

<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="550" /></a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="520" /></a>

<p align="left"><b>Here's the code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>

Expand Down Expand Up @@ -835,7 +838,7 @@ python -m http.server 1948
pytest test_suite.py test_image_saving.py --dashboard --rs --headless
```

<img src="https://seleniumbase.github.io/cdn/img/dashboard_2.png" alt="The SeleniumBase Dashboard" title="The SeleniumBase Dashboard" width="550" />
<img src="https://seleniumbase.github.io/cdn/img/dashboard_2.png" alt="The SeleniumBase Dashboard" title="The SeleniumBase Dashboard" width="520" />

--------

Expand Down Expand Up @@ -890,7 +893,7 @@ pynose test_suite.py --report
behave behave_bdd/features/ -D dashboard -D headless
```

<img src="https://seleniumbase.github.io/cdn/img/sb_behave_dashboard.png" title="SeleniumBase" width="550">
<img src="https://seleniumbase.github.io/cdn/img/sb_behave_dashboard.png" title="SeleniumBase" width="520">

You can also use ``--junit`` to get ``.xml`` reports for each <code translate="no">behave</code> feature. Jenkins can use these files to display better reporting for your tests.

Expand Down
16 changes: 10 additions & 6 deletions examples/raw_nopecha.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
from seleniumbase import SB

with SB(uc=True, test=True) as sb:
sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 4.5)
sb.switch_to_frame("#example-container5 iframe")
sb.driver.uc_click("span.mark", reconnect_time=3)

sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 3.4)
if sb.is_element_visible("#example-container0 iframe"):
sb.switch_to_frame("#example-container0 iframe")
if not sb.is_element_visible("circle.success-circle"):
sb.driver.uc_click("span.mark", reconnect_time=3)
sb.switch_to_frame("#example-container0 iframe")
sb.assert_element("circle.success-circle")
sb.switch_to_parent_frame()
sb.switch_to_default_content()

sb.switch_to_frame("#example-container5 iframe")
sb.driver.uc_click("span.mark", reconnect_time=2.5)
sb.switch_to_frame("#example-container5 iframe")
sb.assert_element("svg#success-icon", timeout=3)
sb.switch_to_parent_frame()

if sb.is_element_visible("#example-container0 iframe"):
sb.switch_to_frame("#example-container0 iframe")
sb.assert_element("circle.success-circle")
sb.switch_to_parent_frame()

sb.set_messenger_theme(location="top_center")
sb.post_message("SeleniumBase wasn't detected!", duration=3)
32 changes: 18 additions & 14 deletions help_docs/uc_mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@
<!-- YouTube View --><a href="https://www.youtube.com/watch?v=5dMFI3e85ig"><img src="http://img.youtube.com/vi/5dMFI3e85ig/0.jpg" title="SeleniumBase on YouTube" width="400" /></a>
<!-- GitHub Only --><p>(<b><a href="https://www.youtube.com/watch?v=5dMFI3e85ig">Watch the UC Mode tutorial on YouTube! ▶️</a></b>)</p>

👤 <b translate="no">UC Mode</b> is based on [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver), but includes multiple updates, fixes, and improvements to support a wider range of features and edge cases:
👤 <b translate="no">UC Mode</b> is based on [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver), but includes multiple updates, fixes, and improvements, such as:

* Automatically changes the user agent to prevent detection.
* Supports multithreaded tests in parallel via `pytest-xdist`.
* Adjusts some configuration based on the environment.
* Includes driver version-detection and management.
* Has options for setting proxy and proxy-with-auth.
* Has args for adjusting timings from default values.
* Includes multiple ways of structuring test scripts.
* Automatically changing user agents to prevent detection.
* Automatically setting various chromium args as needed.
* Has special methods. Eg. `driver.uc_click(selector)`

👤 Here's an example with the <b><code translate="no">Driver</code></b> manager:

Expand Down Expand Up @@ -83,6 +79,10 @@ with SB(uc=True, test=True) as sb:

--------

👤 In <b translate="no">UC Mode</b>, <code translate="no">driver.get(url)</code> has been modified from its original version: If anti-bot services are detected from a <code translate="no">requests.get(url)</code> call that's made before navigating to the website, then <code translate="no">driver.uc_open_with_reconnect(url)</code> will be used instead. To open a URL normally in <b translate="no">UC Mode</b>, use <code translate="no">driver.default_get(url)</code>.

--------

### 👤 Here are some examples that use UC Mode:
* [SeleniumBase/examples/verify_undetected.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/verify_undetected.py)
* [SeleniumBase/examples/raw_bing_captcha.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_bing_captcha.py)
Expand Down Expand Up @@ -212,21 +212,25 @@ with ThreadPoolExecutor(max_workers=len(urls)) as executor:
from seleniumbase import SB

with SB(uc=True, test=True) as sb:
sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 4.5)
sb.switch_to_frame("#example-container5 iframe")
sb.driver.uc_click("span.mark", reconnect_time=3)

sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 3.4)
if sb.is_element_visible("#example-container0 iframe"):
sb.switch_to_frame("#example-container0 iframe")
if not sb.is_element_visible("circle.success-circle"):
sb.driver.uc_click("span.mark", reconnect_time=3)
sb.switch_to_frame("#example-container0 iframe")
sb.assert_element("circle.success-circle")
sb.switch_to_parent_frame()
sb.switch_to_default_content()

sb.switch_to_frame("#example-container5 iframe")
sb.driver.uc_click("span.mark", reconnect_time=2.5)
sb.switch_to_frame("#example-container5 iframe")
sb.assert_element("svg#success-icon", timeout=3)
sb.switch_to_parent_frame()

if sb.is_element_visible("#example-container0 iframe"):
sb.switch_to_frame("#example-container0 iframe")
sb.assert_element("circle.success-circle")
sb.switch_to_parent_frame()

sb.set_messenger_theme(location="top_center")
sb.post_message("SeleniumBase wasn't detected!", duration=3)
```
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ filelock>=3.12.2;python_version<"3.8"
filelock>=3.13.3;python_version>="3.8"
platformdirs>=4.0.0;python_version<"3.8"
platformdirs>=4.2.0;python_version>="3.8"
typing-extensions>=4.10.0;python_version>="3.8"
typing-extensions>=4.11.0;python_version>="3.8"
parse>=1.20.1
parse-type>=0.6.2
pyyaml>=6.0.1
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.25.1"
__version__ = "4.25.2"
3 changes: 3 additions & 0 deletions seleniumbase/undetected/webelement.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
import selenium.webdriver.remote.webelement
from seleniumbase.fixtures import js_utils

Expand All @@ -17,6 +18,8 @@ def uc_click(
delayed_click = True
if delayed_click and ":contains" not in selector:
selector = js_utils.convert_to_css_selector(selector, by)
selector = re.escape(selector)
selector = js_utils.escape_quotes_if_needed(selector)
script = 'document.querySelector("%s").click();' % selector
js_utils.call_me_later(driver, script, 111)
else:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
'filelock>=3.13.3;python_version>="3.8"',
'platformdirs>=4.0.0;python_version<"3.8"',
'platformdirs>=4.2.0;python_version>="3.8"',
'typing-extensions>=4.10.0;python_version>="3.8"',
'typing-extensions>=4.11.0;python_version>="3.8"',
'parse>=1.20.1',
'parse-type>=0.6.2',
'pyyaml>=6.0.1',
Expand Down