diff --git a/README.md b/README.md index ae3ed78cbf1..5a3cb531f4b 100755 --- a/README.md +++ b/README.md @@ -9,11 +9,10 @@

SeleniumBase

-

SeleniumBase

+

SeleniumBase

-

End-to-end testing for the next generation.

-

Overcome your greatest browser automation challenges.

+

All-in-one Browser Automation Framework:
Web Crawling / Testing / Scraping / Stealth

PyPI version GitHub version SeleniumBase Docs SeleniumBase GitHub Actions Gitter chat

@@ -57,7 +56,11 @@ -------- -📚 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 SeleniumBase UC Mode / Stealth Mode has its own ReadMe. + +ℹī¸ Scripts can be called via python, although some Syntax Formats expect pytest (a Python unit-testing framework included with SeleniumBase that can discover & collect tests automatically).

📗 Here's my_first_test.py, which tests login, shopping, and checkout:

@@ -65,7 +68,7 @@ pytest my_first_test.py ``` -SeleniumBase Test +SeleniumBase Test > ``pytest`` uses ``--chrome`` by default unless set differently. @@ -77,7 +80,7 @@ pytest my_first_test.py pytest test_coffee_cart.py --demo ``` -

SeleniumBase Coffee Cart Test

+

SeleniumBase Coffee Cart Test

>

(--demo mode slows down tests and highlights actions)

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

SeleniumBase Example

+

SeleniumBase Example

> Easy to type, click, select, toggle, drag & drop, and more. @@ -394,7 +397,7 @@ cd examples/ pytest my_first_test.py ``` -SeleniumBase Test +SeleniumBase Test

Here's the code for my_first_test.py:

@@ -835,7 +838,7 @@ python -m http.server 1948 pytest test_suite.py test_image_saving.py --dashboard --rs --headless ``` -The SeleniumBase Dashboard +The SeleniumBase Dashboard -------- @@ -890,7 +893,7 @@ pynose test_suite.py --report behave behave_bdd/features/ -D dashboard -D headless ``` - + You can also use ``--junit`` to get ``.xml`` reports for each behave feature. Jenkins can use these files to display better reporting for your tests. diff --git a/examples/raw_nopecha.py b/examples/raw_nopecha.py index 07fc5543066..0d193fe7b68 100644 --- a/examples/raw_nopecha.py +++ b/examples/raw_nopecha.py @@ -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) diff --git a/help_docs/uc_mode.md b/help_docs/uc_mode.md index a6a61a9f47f..20ba73f61cd 100644 --- a/help_docs/uc_mode.md +++ b/help_docs/uc_mode.md @@ -7,15 +7,11 @@

(Watch the UC Mode tutorial on YouTube! â–ļī¸)

-👤 UC Mode 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: +👤 UC Mode 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 Driver manager: @@ -83,6 +79,10 @@ with SB(uc=True, test=True) as sb: -------- +👤 In UC Mode, driver.get(url) has been modified from its original version: If anti-bot services are detected from a requests.get(url) call that's made before navigating to the website, then driver.uc_open_with_reconnect(url) will be used instead. To open a URL normally in UC Mode, use driver.default_get(url). + +-------- + ### 👤 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) @@ -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) ``` diff --git a/requirements.txt b/requirements.txt index 7e2e6c34d31..b473116c878 100755 --- a/requirements.txt +++ b/requirements.txt @@ -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 diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 31f9b4d0c0a..c827c4659c4 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.25.1" +__version__ = "4.25.2" diff --git a/seleniumbase/undetected/webelement.py b/seleniumbase/undetected/webelement.py index f45fd6507ae..6b540f0c52d 100644 --- a/seleniumbase/undetected/webelement.py +++ b/seleniumbase/undetected/webelement.py @@ -1,3 +1,4 @@ +import re import selenium.webdriver.remote.webelement from seleniumbase.fixtures import js_utils @@ -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: diff --git a/setup.py b/setup.py index dea3610ec67..a9c95df0e02 100755 --- a/setup.py +++ b/setup.py @@ -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',