From fc684c3698193e8bc048d5197f712cb0136fcb55 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:50:11 -0500 Subject: [PATCH 1/8] Fix bugs related to `driver.capabilities["browserName"]` --- seleniumbase/fixtures/base_case.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 33f17c10041..956aa3d4ebb 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -7007,13 +7007,13 @@ def get_browser_downloads_folder(self): # Can't change the system [Downloads Folder] on Safari or IE return os.path.join(os.path.expanduser("~"), "downloads") elif ( - self.driver.capabilities["browserName"].lower() == "chrome" + "chrome" in self.driver.capabilities and int(self.get_chromedriver_version().split(".")[0]) < 73 and self.headless ): return os.path.join(os.path.expanduser("~"), "downloads") elif ( - self.driver.capabilities["browserName"].lower() == "chrome" + "chrome" in self.driver.capabilities and int(self.get_chromedriver_version().split(".")[0]) >= 110 and int(self.get_chromedriver_version().split(".")[0]) <= 112 and self.headless @@ -7711,17 +7711,19 @@ def is_chromium(self): """Return True if the browser is Chrome or Edge.""" self.__check_scope() chromium = False - browser_name = self.driver.capabilities["browserName"] - if browser_name.lower() in ("chrome", "edge", "msedge"): + if ( + "chrome" in self.driver.capabilities + or "msedge" in self.driver.capabilities + ): chromium = True return chromium def __fail_if_not_using_chrome(self, method): chrome = False - browser_name = self.driver.capabilities["browserName"] - if browser_name.lower() == "chrome": + if "chrome" in self.driver.capabilities: chrome = True if not chrome: + browser_name = self.driver.capabilities["browserName"] message = ( 'Error: "%s" should only be called by tests ' 'running with "--browser=chrome" / "--chrome"! ' @@ -7732,8 +7734,8 @@ def __fail_if_not_using_chrome(self, method): raise NotUsingChromeException(message) def __fail_if_not_using_chromium(self, method): - browser_name = self.driver.capabilities["browserName"] if not self.is_chromium(): + browser_name = self.driver.capabilities["browserName"] message = ( 'Error: "%s" should only be called by tests ' 'running with a Chromium browser! (Chrome or Edge) ' @@ -15578,12 +15580,12 @@ def _get_driver_name_and_version(self): else: return None driver = self.driver - if driver.capabilities["browserName"].lower() == "chrome": + if "chrome" in self.driver.capabilities: cap_dict = driver.capabilities["chrome"] return ( "chromedriver", cap_dict["chromedriverVersion"].split(" ")[0] ) - elif driver.capabilities["browserName"].lower() == "msedge": + elif "msedge" in self.driver.capabilities: cap_dict = driver.capabilities["msedge"] return ( "msedgedriver", cap_dict["msedgedriverVersion"].split(" ")[0] From 001088b5f00e9191eba8e22b92536d9d13090654 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:50:55 -0500 Subject: [PATCH 2/8] Do some refactoring --- seleniumbase/core/proxy_helper.py | 6 +++++- seleniumbase/fixtures/base_case.py | 26 ++++++-------------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/seleniumbase/core/proxy_helper.py b/seleniumbase/core/proxy_helper.py index a97e4a829d0..a205f8b6474 100644 --- a/seleniumbase/core/proxy_helper.py +++ b/seleniumbase/core/proxy_helper.py @@ -27,7 +27,11 @@ def create_proxy_ext( if not bypass_list: bypass_list = "" if proxy_string: - proxy_host = proxy_string.split(":")[0] + proxy_protocol = "" + if proxy_string.count("://") == 1: + proxy_protocol = proxy_string.split("://")[0] + "://" + proxy_string = proxy_string.split("://")[1] + proxy_host = proxy_protocol + proxy_string.split(":")[0] proxy_port = proxy_string.split(":")[1] background_js = ( """var config = {\n""" diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 956aa3d4ebb..5c8935d1f08 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -199,22 +199,17 @@ def test_example(self): Eg. "python my_test.py" instead of "pytest my_test.py".""" if name == "__main__": # Test called with "python" import subprocess - from pytest import main as pytest_main all_args = [] for arg in args: all_args.append(arg) for arg in sys.argv[1:]: all_args.append(arg) - multi = False - for arg in all_args: - if arg.startswith("-n") or arg.startswith("--numprocesses"): - multi = True - if multi: - subprocess.call( - [sys.executable, "-m", "pytest", file, "-s", *all_args] - ) - else: - pytest_main([file, "-s", *all_args]) + # See: https://stackoverflow.com/a/54666289/7058266 + # from pytest import main as pytest_main + # pytest_main([file, "-s", *all_args]) + subprocess.call( + [sys.executable, "-m", "pytest", file, "-s", *all_args] + ) def open(self, url): """Navigates the current browser window to the specified page.""" @@ -13586,15 +13581,6 @@ def __disable_beforeunload_as_needed(self): ############ - @decorators.deprecated("The Driver Manager prevents old drivers.") - def is_chromedriver_too_old(self): - """Before chromedriver 73, there was no version check, which - means it's possible to run a new Chrome with old drivers.""" - self.__fail_if_not_using_chrome("is_chromedriver_too_old()") - if int(self.get_chromedriver_version().split(".")[0]) < 73: - return True # chromedriver is too old! Please upgrade! - return False - @decorators.deprecated("You should use re.escape() instead.") def jq_format(self, code): # DEPRECATED - re.escape() already performs this action. From 93502760d237234ce386bd9cb88c9d222b817fa0 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:51:21 -0500 Subject: [PATCH 3/8] Refresh mkdocs dependencies --- mkdocs_build/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index db3a668051f..681859b7e8a 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -7,7 +7,7 @@ pymdown-extensions>=10.5 pipdeptree>=2.13.1 python-dateutil>=2.8.2 Markdown==3.5.1 -markdown2==2.4.10 +markdown2==2.4.11 MarkupSafe==2.1.3 Jinja2==3.1.2 click==8.1.7 @@ -20,7 +20,7 @@ paginate==0.5.6 pyquery==2.0.0 readtime==3.0.0 mkdocs==1.5.3 -mkdocs-material==9.4.14 -mkdocs-exclude-search==0.6.5 +mkdocs-material==9.5.0 +mkdocs-exclude-search==0.6.6 mkdocs-simple-hooks==0.1.5 mkdocs-material-extensions==1.3.1 From 070b807abcebbb80aaf4b1a707b01b1503487d0d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:51:58 -0500 Subject: [PATCH 4/8] Refresh optional Python dependencies --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 1ce7bfe83de..e87552178b8 100755 --- a/setup.py +++ b/setup.py @@ -249,14 +249,14 @@ # pip install -e .[selenium-wire] "selenium-wire": [ 'selenium-wire==5.1.0', - 'Brotli==1.0.9', - 'blinker==1.6.2', + 'Brotli==1.1.0', + 'blinker==1.7.0', 'h2==4.1.0', 'hpack==4.0.0', 'hyperframe==6.0.1', 'kaitaistruct==0.10', - 'pyasn1==0.5.0', - 'zstandard==0.21.0', + 'pyasn1==0.5.1', + 'zstandard==0.22.0', ], }, packages=[ From 9fabde06ef07031d3c5843839d35f6aa10f0266e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:52:30 -0500 Subject: [PATCH 5/8] Refresh Python dependencies --- requirements.txt | 4 ++-- setup.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1f1134f802b..b31b96bfe29 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ attrs>=23.1.0 certifi>=2023.11.17 filelock>=3.12.2;python_version<"3.8" filelock>=3.13.1;python_version>="3.8" -platformdirs>=4.0.0 +platformdirs>=4.1.0 parse>=1.20.0 parse-type>=0.6.2 six==1.16.0 @@ -26,7 +26,7 @@ trio==0.23.1;python_version>="3.8" trio-websocket==0.11.1 wsproto==1.2.0 selenium==4.11.2;python_version<"3.8" -selenium==4.15.2;python_version>="3.8" +selenium==4.16.0;python_version>="3.8" cssselect==1.2.0 sortedcontainers==2.4.0 fasteners==0.19 diff --git a/setup.py b/setup.py index e87552178b8..21cc90390fb 100755 --- a/setup.py +++ b/setup.py @@ -140,7 +140,7 @@ "certifi>=2023.11.17", 'filelock>=3.12.2;python_version<"3.8"', 'filelock>=3.13.1;python_version>="3.8"', - 'platformdirs>=4.0.0', + 'platformdirs>=4.1.0', 'parse>=1.20.0', 'parse-type>=0.6.2', "six==1.16.0", @@ -159,7 +159,7 @@ 'trio-websocket==0.11.1', 'wsproto==1.2.0', 'selenium==4.11.2;python_version<"3.8"', - 'selenium==4.15.2;python_version>="3.8"', + 'selenium==4.16.0;python_version>="3.8"', 'cssselect==1.2.0', "sortedcontainers==2.4.0", 'fasteners==0.19', From 04aacbb9591b19c6ffac0c7714b7eae3179b83c2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 22:56:00 -0500 Subject: [PATCH 6/8] Update example tests --- examples/github_test.py | 4 ++-- examples/presenter/uc_presentation.py | 11 +++++++---- examples/raw_uc_mode.py | 2 +- examples/test_hack_search.py | 4 ++-- examples/test_shadow_dom.py | 2 +- examples/youtube_search_test.py | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/github_test.py b/examples/github_test.py index 0462b16f0cd..036e0bb911c 100644 --- a/examples/github_test.py +++ b/examples/github_test.py @@ -17,5 +17,5 @@ def test_github(self): self.assert_element("div.repository-content") self.assert_text("SeleniumBase", "strong a") self.click('a[title="seleniumbase"]') - self.slow_click('a[aria-describedby="item-type-fixtures"]') - self.assert_element('a[aria-describedby="item-type-base_case.py"]') + self.slow_click('td[class*="large"] a[title="fixtures"]') + self.assert_element('td[class*="large"] a[title="base_case.py"]') diff --git a/examples/presenter/uc_presentation.py b/examples/presenter/uc_presentation.py index fd98fb46bed..d8cb4b082f5 100644 --- a/examples/presenter/uc_presentation.py +++ b/examples/presenter/uc_presentation.py @@ -29,13 +29,17 @@ def test_presentation(self): self.get_new_driver(undetectable=True) try: - self.driver.uc_open_with_tab("https://nowsecure.nl/#relax") + self.driver.uc_open_with_reconnect( + "https://nowsecure.nl/#relax", reconnect_time=3 + ) try: self.assert_text("OH YEAH, you passed!", "h1", timeout=4) self.post_message("Selenium wasn't detected!", duration=4) except Exception: self.clear_all_cookies() - self.driver.uc_open_with_tab("https://nowsecure.nl/#relax") + self.driver.uc_open_with_reconnect( + "https://nowsecure.nl/#relax", reconnect_time=3 + ) self.assert_text("OH YEAH, you passed!", "h1", timeout=4) self.post_message("Selenium wasn't detected!", duration=4) finally: @@ -51,8 +55,7 @@ def test_presentation(self): "

" ) self.begin_presentation(filename="uc_presentation.html") - subprocess.Popen("pytest multi_uc.py --uc -q -n3", shell=True) - self.sleep(6) + subprocess.Popen("pytest multi_uc.py --uc -n3", shell=True).wait() self.create_presentation(theme="serif", transition="fade") self.add_slide( "

Not just an army of bots, but an army of bots
" diff --git a/examples/raw_uc_mode.py b/examples/raw_uc_mode.py index 1e61db4d4fa..11ccd34b4a2 100644 --- a/examples/raw_uc_mode.py +++ b/examples/raw_uc_mode.py @@ -1,7 +1,7 @@ """SB Manager using UC Mode for evading bot-detection.""" from seleniumbase import SB -with SB(uc=True) as sb: +with SB(uc=True, test=True) as sb: sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax") sb.sleep(1.2) if not sb.is_text_visible("OH YEAH, you passed!", "h1"): diff --git a/examples/test_hack_search.py b/examples/test_hack_search.py index 8ac61aea30a..a16d8a7925f 100644 --- a/examples/test_hack_search.py +++ b/examples/test_hack_search.py @@ -26,7 +26,7 @@ def test_hack_search(self): self.highlight_click('[href="/seleniumbase/SeleniumBase"]') self.highlight_click('a[title="examples"]') self.assert_text("examples", "#file-name-id-wide") - self.highlight('a[aria-describedby="item-type-test_hack_search.py"]') - self.click('a[aria-describedby="item-type-test_hack_search.py"]') + self.highlight('td[class*="large"] a[title="test_hack_search.py"]') + self.click('td[class*="large"] a[title="test_hack_search.py"]') self.assert_text("test_hack_search.py", "#file-name-id-wide") self.highlight("#file-name-id-wide") diff --git a/examples/test_shadow_dom.py b/examples/test_shadow_dom.py index ab36f40617b..2fc5c9285ab 100644 --- a/examples/test_shadow_dom.py +++ b/examples/test_shadow_dom.py @@ -63,7 +63,7 @@ def test_shadow_dom(self): ) remove_button = ( "downloads-manager::shadow #downloadsList" - " downloads-item::shadow #remove" + " downloads-item::shadow #remove-old" ) no_downloads_area = "downloads-manager::shadow #no-downloads" diff --git a/examples/youtube_search_test.py b/examples/youtube_search_test.py index a384daea813..cf7c1457f60 100644 --- a/examples/youtube_search_test.py +++ b/examples/youtube_search_test.py @@ -32,4 +32,4 @@ def test_youtube_autocomplete_results(self): 'Actual text was "%s"!' % (search_term, top_result), ) self.click(result_selector) - self.assert_element_present('a[aria-label*="SeleniumBase"]') + self.sleep(1) From d4f508344153cf10227fa43594ca49c2e0867efd Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 23:07:44 -0500 Subject: [PATCH 7/8] Refresh Python dependencies --- requirements.txt | 3 ++- setup.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index b31b96bfe29..b569e4d02a5 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,8 @@ attrs>=23.1.0 certifi>=2023.11.17 filelock>=3.12.2;python_version<"3.8" filelock>=3.13.1;python_version>="3.8" -platformdirs>=4.1.0 +platformdirs>=4.0.0;python_version<"3.8" +platformdirs>=4.1.0;python_version>="3.8" parse>=1.20.0 parse-type>=0.6.2 six==1.16.0 diff --git a/setup.py b/setup.py index 21cc90390fb..9f80b8a5eb6 100755 --- a/setup.py +++ b/setup.py @@ -140,7 +140,8 @@ "certifi>=2023.11.17", 'filelock>=3.12.2;python_version<"3.8"', 'filelock>=3.13.1;python_version>="3.8"', - 'platformdirs>=4.1.0', + 'platformdirs>=4.0.0;python_version<"3.8"', + 'platformdirs>=4.1.0;python_version>="3.8"', 'parse>=1.20.0', 'parse-type>=0.6.2', "six==1.16.0", From 144d536a7ebfc8c61483175b87bb97e37ed35668 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 7 Dec 2023 23:08:22 -0500 Subject: [PATCH 8/8] Version 4.22.0 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index f3666f36221..c7d839a1241 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.21.7" +__version__ = "4.22.0"