diff --git a/examples/boilerplates/samples/google_test.py b/examples/boilerplates/samples/google_test.py index 7164c3860ca..e01b5fc36e9 100644 --- a/examples/boilerplates/samples/google_test.py +++ b/examples/boilerplates/samples/google_test.py @@ -17,7 +17,8 @@ def test_google_dot_com(self): self.assert_title_contains("Google") self.sleep(0.05) self.save_screenshot_to_logs() # ("./latest_logs" folder) - self.wait_for_element('iframe[role="presentation"]') + if not self.is_element_visible("iframe"): + self.sleep(1.5) # A slow pop-up might appear self.hide_elements('iframe') # Hide "Sign in" pop-up self.sleep(0.05) self.save_screenshot_to_logs() diff --git a/examples/boilerplates/samples/test_page_objects.py b/examples/boilerplates/samples/test_page_objects.py index 07e0a99b6db..6757c834e6e 100644 --- a/examples/boilerplates/samples/test_page_objects.py +++ b/examples/boilerplates/samples/test_page_objects.py @@ -11,7 +11,8 @@ def assert_google_title(self, sb): sb.assert_title_contains("Google") def hide_sign_in_pop_up(self, sb): - sb.wait_for_element('iframe[role="presentation"]') + if not sb.is_element_visible("iframe"): + sb.sleep(1.5) # A slow pop-up might appear sb.hide_elements('iframe') sb.sleep(0.05) diff --git a/examples/github_test.py b/examples/github_test.py index 036e0bb911c..bb54e3b569c 100644 --- a/examples/github_test.py +++ b/examples/github_test.py @@ -9,8 +9,7 @@ def test_github(self): message = "Unsupported mode for this test." print("\n " + message) self.skip(message) - self.open("https://github.com/search?q=SeleniumBase") - self.slow_click('a[href="/seleniumbase/SeleniumBase"]') + self.open("https://github.com/seleniumbase/SeleniumBase") self.click_if_visible('[data-action="click:signup-prompt#dismiss"]') self.highlight("div.Layout-main") self.highlight("div.Layout-sidebar") diff --git a/examples/test_geolocation.py b/examples/test_geolocation.py index f849fb8b60e..eb0618096a1 100644 --- a/examples/test_geolocation.py +++ b/examples/test_geolocation.py @@ -7,8 +7,12 @@ def tearDown(self): self.save_teardown_screenshot() # If test fails, or if "--screenshot" if self.is_chromium() and not self._multithreaded: # Reset Permissions and GeolocationOverride - self.execute_cdp_cmd("Browser.resetPermissions", {}) - self.execute_cdp_cmd("Emulation.setGeolocationOverride", {}) + try: + self.open("about:blank") + self.execute_cdp_cmd("Emulation.setGeolocationOverride", {}) + self.execute_cdp_cmd("Browser.resetPermissions", {}) + except Exception: + pass super().tearDown() def test_geolocation(self): diff --git a/examples/test_scrape_bing.py b/examples/test_scrape_bing.py index 611a61b0150..9fd1dbfdd29 100644 --- a/examples/test_scrape_bing.py +++ b/examples/test_scrape_bing.py @@ -4,6 +4,9 @@ class ScrapeBingTests(BaseCase): def test_scrape_bing(self): + if self._multithreaded: + self.open_if_not_url("about:blank") + self.skip("Skipping test in multi-threaded mode.") self.open("www.bing.com/search?q=SeleniumBase+GitHub&qs=n&form=QBRE") self.wait_for_element("main h2 a") soup = self.get_beautiful_soup() diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index 681859b7e8a..56c36af0f86 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -7,20 +7,21 @@ pymdown-extensions>=10.5 pipdeptree>=2.13.1 python-dateutil>=2.8.2 Markdown==3.5.1 -markdown2==2.4.11 +markdown2==2.4.12 MarkupSafe==2.1.3 Jinja2==3.1.2 click==8.1.7 ghp-import==2.1.0 watchdog==3.0.0 cairocffi==1.6.1 -pathspec==0.11.2 -Babel==2.13.1 +pathspec==0.12.1 +Babel==2.14.0 paginate==0.5.6 +lxml==4.9.4 pyquery==2.0.0 readtime==3.0.0 mkdocs==1.5.3 -mkdocs-material==9.5.0 +mkdocs-material==9.5.2 mkdocs-exclude-search==0.6.6 mkdocs-simple-hooks==0.1.5 mkdocs-material-extensions==1.3.1 diff --git a/requirements.txt b/requirements.txt index b569e4d02a5..ac509591f42 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pip>=23.3.1 +pip>=23.3.2 packaging>=23.2 setuptools>=68.0.0;python_version<"3.8" setuptools>=69.0.2;python_version>="3.8" @@ -23,7 +23,7 @@ sniffio==1.3.0 h11==0.14.0 outcome==1.3.0.post0 trio==0.22.2;python_version<"3.8" -trio==0.23.1;python_version>="3.8" +trio==0.23.2;python_version>="3.8" trio-websocket==0.11.1 wsproto==1.2.0 selenium==4.11.2;python_version<"3.8" @@ -65,7 +65,7 @@ rich==13.7.0 coverage==6.2;python_version<"3.7" coverage==7.2.7;python_version>="3.7" and python_version<"3.8" -coverage==7.3.2;python_version>="3.8" +coverage==7.3.3;python_version>="3.8" pytest-cov==4.0.0;python_version<"3.7" pytest-cov==4.1.0;python_version>="3.7" flake8==5.0.4;python_version<"3.9" diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index c7d839a1241..267856135b7 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.22.0" +__version__ = "4.22.1" diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 5c8935d1f08..f8bc8aefaf7 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -251,7 +251,15 @@ def open(self, url): try: self.driver.get(url) except Exception as e: - if ( + if not hasattr(e, "msg") and hasattr(self.driver, "default_get"): + try: + self._check_browser() + time.sleep(0.4) + except Exception: + logging.debug("Browser crashed! Will open new browser!") + self.driver = self.get_new_driver() + self.driver.default_get(url) + elif ( "ERR_CONNECTION_TIMED_OUT" in e.msg or "ERR_CONNECTION_CLOSED" in e.msg or "ERR_CONNECTION_RESET" in e.msg @@ -1018,7 +1026,7 @@ def add_text(self, selector, text, by="css selector", timeout=None): # Use after "\t" or Keys.TAB to cycle through elements first. self.click_active_element() return - element = self.wait_for_element_visible( + element = self.wait_for_element_present( selector, by=by, timeout=timeout ) if ( @@ -1113,7 +1121,7 @@ def send_keys(self, selector, text, by="css selector", timeout=None): def press_keys(self, selector, text, by="css selector", timeout=None): """Use send_keys() to press one key at a time.""" self.wait_for_ready_state_complete() - element = self.wait_for_element_clickable( + element = self.wait_for_element_present( selector, by=by, timeout=timeout ) if self.demo_mode: diff --git a/seleniumbase/fixtures/constants.py b/seleniumbase/fixtures/constants.py index f2b84a37ee6..00e93c9b7d6 100644 --- a/seleniumbase/fixtures/constants.py +++ b/seleniumbase/fixtures/constants.py @@ -362,7 +362,7 @@ class Mobile: class UC: - RECONNECT_TIME = 2.27 # Seconds + RECONNECT_TIME = 2.28 # Seconds class ValidBrowsers: @@ -390,12 +390,14 @@ class ValidBinaries: "brave-browser-stable", "opera", "opera-stable", + "chrome.exe", # WSL (Windows Subsystem for Linux) ] valid_edge_binaries_on_linux = [ "microsoft-edge", "microsoft-edge-stable", "microsoft-edge-beta", "microsoft-edge-dev", + "msedge.exe", # WSL (Windows Subsystem for Linux) ] valid_chrome_binaries_on_macos = [ "Google Chrome", diff --git a/seleniumbase/fixtures/page_actions.py b/seleniumbase/fixtures/page_actions.py index 24b5f6a531d..56633e45e13 100644 --- a/seleniumbase/fixtures/page_actions.py +++ b/seleniumbase/fixtures/page_actions.py @@ -1583,7 +1583,7 @@ def send_keys( driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT ): selector, by = page_utils.recalculate_selector(selector, by) - element = wait_for_element_clickable( + element = wait_for_element_present( driver, selector, by=by, timeout=timeout ) if not text.endswith("\n"): @@ -1597,7 +1597,7 @@ def press_keys( driver, selector, text, by="css selector", timeout=settings.LARGE_TIMEOUT ): selector, by = page_utils.recalculate_selector(selector, by) - element = wait_for_element_clickable( + element = wait_for_element_present( driver, selector, by=by, timeout=timeout ) if not text.endswith("\n"): diff --git a/seleniumbase/undetected/__init__.py b/seleniumbase/undetected/__init__.py index f45769f65d4..611b84d8259 100644 --- a/seleniumbase/undetected/__init__.py +++ b/seleniumbase/undetected/__init__.py @@ -446,12 +446,13 @@ def quit(self): try: logger.debug("Terminating the UC browser") os.kill(self.browser_pid, 15) - if IS_POSIX: + if "linux" in sys.platform: os.waitpid(self.browser_pid, 0) + time.sleep(0.02) else: - time.sleep(0.05) + time.sleep(0.04) except (AttributeError, ChildProcessError, RuntimeError, OSError): - pass + time.sleep(0.05) except TimeoutError as e: logger.debug(e, exc_info=True) except Exception: diff --git a/setup.py b/setup.py index 9f80b8a5eb6..44fc1a55faf 100755 --- a/setup.py +++ b/setup.py @@ -131,7 +131,7 @@ ], python_requires=">=3.7", install_requires=[ - 'pip>=23.3.1', + 'pip>=23.3.2', 'packaging>=23.2', 'setuptools>=68.0.0;python_version<"3.8"', 'setuptools>=69.0.2;python_version>="3.8"', @@ -156,7 +156,7 @@ 'h11==0.14.0', 'outcome==1.3.0.post0', 'trio==0.22.2;python_version<"3.8"', - 'trio==0.23.1;python_version>="3.8"', + 'trio==0.23.2;python_version>="3.8"', 'trio-websocket==0.11.1', 'wsproto==1.2.0', 'selenium==4.11.2;python_version<"3.8"', @@ -206,7 +206,7 @@ # Usage: coverage run -m pytest; coverage html; coverage report "coverage": [ 'coverage==7.2.7;python_version<"3.8"', - 'coverage==7.3.2;python_version>="3.8"', + 'coverage==7.3.3;python_version>="3.8"', 'pytest-cov==4.1.0', ], # pip install -e .[flake8]