From ffa64b8ef810c14a3bc3b0b61759376cd215f2c6 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 17 Oct 2025 18:35:31 -0400 Subject: [PATCH 1/5] Update CDP Mode --- seleniumbase/core/sb_cdp.py | 55 ++++++------------- seleniumbase/fixtures/base_case.py | 4 +- seleniumbase/undetected/cdp_driver/browser.py | 3 +- 3 files changed, 21 insertions(+), 41 deletions(-) diff --git a/seleniumbase/core/sb_cdp.py b/seleniumbase/core/sb_cdp.py index 835c82fba66..80755b5b5c8 100644 --- a/seleniumbase/core/sb_cdp.py +++ b/seleniumbase/core/sb_cdp.py @@ -187,46 +187,23 @@ def find_element_by_text(self, text, tag_name=None, timeout=None): element with the given tag. (Eg: a, button, div, script, span)""" if not timeout: timeout = settings.SMALL_TIMEOUT - self.__add_light_pause() - time_now = time.time() - self.assert_text(text, timeout=timeout) - spent = int(time.time() - time_now) - remaining = 1 + timeout - spent - if tag_name: - self.assert_element(tag_name, timeout=remaining) - elements = self.loop.run_until_complete( - self.page.find_elements_by_text(text=text) - ) if tag_name: - tag_name = tag_name.lower().strip() - for element in elements: - if element and not tag_name: - element = self.__add_sync_methods(element) - return self.__add_sync_methods(element) - elif ( - element - and tag_name in element.tag_name.lower() - and text.strip() in element.text - ): - element = self.__add_sync_methods(element) - return self.__add_sync_methods(element) - elif ( - element - and element.parent - and tag_name in element.parent.tag_name.lower() - and text.strip() in element.parent.text - ): - element = self.__add_sync_methods(element.parent) - return self.__add_sync_methods(element) - elif ( - element - and element.parent - and element.parent.parent - and tag_name in element.parent.parent.tag_name.lower() - and text.strip() in element.parent.parent.text - ): - element = self.__add_sync_methods(element.parent.parent) - return self.__add_sync_methods(element) + try: + return self.find_element( + '%s:contains("%s")' % (tag_name, text), timeout=timeout + ) + except Exception: + pass # The exception will be raised later + else: + self.__add_light_pause() + self.assert_text(text, timeout=timeout) + elements = self.loop.run_until_complete( + self.page.find_elements_by_text(text=text) + ) + for element in elements: + if element: + element = self.__add_sync_methods(element) + return self.__add_sync_methods(element) plural = "s" if timeout == 1: plural = "" diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index f8017249cf7..a75ee6e0a01 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -10173,7 +10173,7 @@ def wait_for_text_visible( text = self.__get_type_checked_text(text) selector, by = self.__recalculate_selector(selector, by) if self.__is_cdp_swap_needed(): - return self.cdp.find_element(selector, timeout=timeout) + return self.cdp.wait_for_text(text, selector, timeout=timeout) elif self.__is_shadow_selector(selector): return self.__wait_for_shadow_text_visible(text, selector, timeout) return page_actions.wait_for_text_visible( @@ -10530,6 +10530,8 @@ def wait_for_link_text_visible(self, link_text, timeout=None): timeout = settings.LARGE_TIMEOUT if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: timeout = self.__get_new_timeout(timeout) + if self.__is_cdp_swap_needed(): + return self.cdp.find_element_by_text(text=link_text, tag_name="a") return self.wait_for_element_visible( link_text, by="link text", timeout=timeout ) diff --git a/seleniumbase/undetected/cdp_driver/browser.py b/seleniumbase/undetected/cdp_driver/browser.py index f048087f920..7623df7ff7e 100644 --- a/seleniumbase/undetected/cdp_driver/browser.py +++ b/seleniumbase/undetected/cdp_driver/browser.py @@ -369,7 +369,8 @@ async def get( proxy_user = username_and_password.split(":")[0] proxy_pass = username_and_password.split(":")[1] await connection.set_auth(proxy_user, proxy_pass, self.tabs[0]) - time.sleep(0.25) + time.sleep(0.22) + await connection.sleep(0.05) frame_id, loader_id, *_ = await connection.send( cdp.page.navigate(url) ) From 5184699e8b3ab7e11a7d3421f1813d03212ed9c8 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 17 Oct 2025 18:36:11 -0400 Subject: [PATCH 2/5] Update the example-generator script --- seleniumbase/console_scripts/sb_mkdir.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/seleniumbase/console_scripts/sb_mkdir.py b/seleniumbase/console_scripts/sb_mkdir.py index 84620456495..83fc045dc0f 100644 --- a/seleniumbase/console_scripts/sb_mkdir.py +++ b/seleniumbase/console_scripts/sb_mkdir.py @@ -636,17 +636,12 @@ def main(): data.append("") data.append("class GoogleTests(BaseCase):") data.append(" def test_google_dot_com(self):") + data.append(" if self.headless:") + data.append(' self.skip("Skipping test in headless mode.")') data.append(" if not self.undetectable:") data.append(" self.get_new_driver(undetectable=True)") data.append(' self.open("https://google.com/ncr")') data.append(' self.assert_title_contains("Google")') - data.append(" self.sleep(0.05)") - data.append(" self.save_screenshot_to_logs()") - data.append( - " self.wait_for_element('iframe[role=\"presentation\"]')" - ) - data.append(" self.hide_elements('iframe')") - data.append(" self.sleep(0.05)") data.append(" self.save_screenshot_to_logs()") data.append(' self.type(HomePage.search_box, "github.com")') data.append(" self.assert_element(HomePage.search_button)") From 2aca64f1d57fddb666563309d00e3cb815a38566 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 17 Oct 2025 18:36:43 -0400 Subject: [PATCH 3/5] Refresh Python dependencies --- requirements.txt | 2 +- setup.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 3ba928a114e..80a446ecd49 100755 --- a/requirements.txt +++ b/requirements.txt @@ -52,7 +52,7 @@ websocket-client~=1.8.0;python_version<"3.9" websocket-client~=1.9.0;python_version>="3.9" selenium==4.27.1;python_version<"3.9" selenium==4.32.0;python_version>="3.9" and python_version<"3.10" -selenium==4.36.0;python_version>="3.10" +selenium==4.37.0;python_version>="3.10" cssselect==1.2.0;python_version<"3.9" cssselect==1.3.0;python_version>="3.9" sortedcontainers==2.4.0 diff --git a/setup.py b/setup.py index f19d8a62b76..5bafac5dfdc 100755 --- a/setup.py +++ b/setup.py @@ -199,7 +199,7 @@ 'websocket-client~=1.9.0;python_version>="3.9"', 'selenium==4.27.1;python_version<"3.9"', 'selenium==4.32.0;python_version>="3.9" and python_version<"3.10"', - 'selenium==4.36.0;python_version>="3.10"', + 'selenium==4.37.0;python_version>="3.10"', 'cssselect==1.2.0;python_version<"3.9"', 'cssselect==1.3.0;python_version>="3.9"', "sortedcontainers==2.4.0", @@ -277,7 +277,7 @@ 'pdfminer.six==20250324;python_version<"3.9"', 'pdfminer.six==20250506;python_version>="3.9"', 'cryptography==39.0.2;python_version<"3.9"', - 'cryptography==46.0.2;python_version>="3.9"', + 'cryptography==46.0.3;python_version>="3.9"', 'cffi==1.17.1;python_version<"3.9"', 'cffi==2.0.0;python_version>="3.9"', 'pycparser==2.22;python_version<"3.9"', From 872354fd38e68c89fe736d249df1b4c648a8e701 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 17 Oct 2025 18:36:51 -0400 Subject: [PATCH 4/5] Update the ReadMe --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8bd290efeee..604050a08bf 100755 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@

Automate, test, and scrape the web — on your own terms.

PyPI version GitHub version SeleniumBase Docs

-

SeleniumBase GitHub Actions

+

SeleniumBase GitHub Actions SeleniumBase PyPI downloads

🚀 Start | @@ -54,7 +54,7 @@

-

SeleniumBase is a browser automation framework for the modern web. Whether you're new or experienced in Python, SeleniumBase makes it easy to get started. With special features like Stealth Mode (UC Mode / CDP Mode), you'll be evading bot-detection and bypassing CAPTCHAs in minutes.

+

SeleniumBase is a browser automation framework for the modern web. Both new and experienced Python users alike can easily get started. With special stealth features like UC Mode and CDP Mode, you'll be evading bot-detection and bypassing CAPTCHAs in minutes.

-------- From 504a42b9bfb91faf5f3ec04d479c052f25638e32 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 17 Oct 2025 18:37:19 -0400 Subject: [PATCH 5/5] Version 4.43.0 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 2984fa9fe87..ae8ed88c79c 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.42.6" +__version__ = "4.43.0"