diff --git a/requirements.txt b/requirements.txt index f2724ab4803..d826085c518 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,92 +1,62 @@ -pip>=21.3.1;python_version<"3.7" -pip>=23.2.1;python_version>="3.7" -packaging>=21.3;python_version<"3.7" -packaging>=23.1;python_version>="3.7" -setuptools>=59.6.0;python_version<"3.7" -setuptools>=68.0.0;python_version>="3.7" and python_version<"3.8" +pip>=23.2.1 +packaging>=23.1 +setuptools>=68.0.0;python_version<"3.8" setuptools>=68.1.2;python_version>="3.8" -wheel>=0.37.1;python_version<"3.7" -wheel>=0.41.2;python_version>="3.7" -attrs==22.1.0;python_version<"3.7" -attrs>=23.1.0;python_version>="3.7" +wheel>=0.41.2 +attrs>=23.1.0 certifi>=2023.7.22 -filelock>=3.4.1;python_version<"3.7" -filelock>=3.12.2;python_version>="3.7" and python_version<"3.8" +filelock>=3.12.2;python_version<"3.8" filelock>=3.12.3;python_version>="3.8" -platformdirs>=2.4.0;python_version<"3.7" -platformdirs>=3.10.0;python_version>="3.7" +platformdirs>=3.10.0 parse>=1.19.1 parse-type>=0.6.2 six==1.16.0 idna==3.4 -chardet==4.0.0;python_version<"3.7" -chardet==5.2.0;python_version>="3.7" -charset-normalizer==2.0.12;python_version<"3.7" -charset-normalizer==3.2.0;python_version>="3.7" -urllib3==1.26.12;python_version<"3.7" -urllib3>=1.26.16,<2;python_version>="3.7" and python_version<"3.10" +chardet==5.2.0 +charset-normalizer==3.2.0 +urllib3>=1.26.16,<2;python_version<"3.10" urllib3>=1.26.16,<2.1.0;python_version>="3.10" -requests==2.27.1;python_version<"3.7" -requests==2.31.0;python_version>="3.7" +requests==2.31.0 pynose==1.4.8 -sniffio==1.3.0;python_version>="3.7" -h11==0.14.0;python_version>="3.7" -outcome==1.2.0;python_version>="3.7" -trio==0.22.2;python_version>="3.7" -trio-websocket==0.10.3;python_version>="3.7" -wsproto==1.2.0;python_version>="3.7" -selenium==3.141.0;python_version<"3.7" -selenium==4.11.2;python_version>="3.7" -msedge-selenium-tools==3.141.3;python_version<"3.7" -cssselect==1.1.0;python_version<"3.7" -cssselect==1.2.0;python_version>="3.7" +sniffio==1.3.0 +h11==0.14.0 +outcome==1.2.0 +trio==0.22.2 +trio-websocket==0.10.3 +wsproto==1.2.0 +selenium==4.11.2;python_version<"3.8" +selenium==4.12.0;python_version>="3.8" +cssselect==1.2.0 sortedcontainers==2.4.0 -fasteners==0.17.3;python_version<"3.7" -fasteners==0.18;python_version>="3.7" -execnet==1.9.0;python_version<"3.7" -execnet==2.0.2;python_version>="3.7" -iniconfig==1.1.1;python_version<"3.7" -iniconfig==2.0.0;python_version>="3.7" -pluggy==1.0.0;python_version<"3.7" -pluggy==1.2.0;python_version>="3.7" and python_version<"3.8" +fasteners==0.18 +execnet==2.0.2 +iniconfig==2.0.0 +pluggy==1.2.0;python_version<"3.8" pluggy==1.3.0;python_version>="3.8" py==1.11.0 -pytest==7.0.1;python_version<"3.7" -pytest==7.4.0;python_version>="3.7" -pytest-forked==1.4.0;python_version<"3.7" +pytest==7.4.0 pytest-html==2.0.1 -pytest-metadata==1.11.0;python_version<"3.7" -pytest-metadata==3.0.0;python_version>="3.7" +pytest-metadata==3.0.0 pytest-ordering==0.6 -pytest-rerunfailures==10.3;python_version<"3.7" -pytest-rerunfailures==12.0;python_version>="3.7" -pytest-xdist==2.5.0;python_version<"3.7" -pytest-xdist==3.3.1;python_version>="3.7" -parameterized==0.8.1;python_version<"3.7" -parameterized==0.9.0;python_version>="3.7" +pytest-rerunfailures==12.0 +pytest-xdist==3.3.1 +parameterized==0.9.0 sbvirtualdisplay==1.2.0 behave==1.2.6 -soupsieve==2.3.2.post1;python_version<"3.7" -soupsieve==2.4.1;python_version>="3.7" +soupsieve==2.4.1 beautifulsoup4==4.12.2 -pygments==2.14.0;python_version<"3.7" -pygments==2.16.1;python_version>="3.7" +pygments==2.16.1 pyreadline3==3.4.1;platform_system=="Windows" tabcompleter==1.2.1 pdbp==1.4.6 -colorama==0.4.5;python_version<"3.7" -colorama==0.4.6;python_version>="3.7" -exceptiongroup==1.1.3;python_version>="3.7" -future-breakpoint==2.0.0;python_version<"3.7" +colorama==0.4.6 +exceptiongroup==1.1.3 importlib-metadata==4.2.0;python_version<"3.8" -pyotp==2.7.0;python_version<"3.7" -pyotp==2.9.0;python_version>="3.7" -typing-extensions==4.1.1;python_version<"3.7" -commonmark==0.9.1;python_version<"3.7" +pyotp==2.9.0 +markdown-it-py==2.2.0;python_version<"3.8" markdown-it-py==3.0.0;python_version>="3.8" -mdurl==0.1.2;python_version>="3.7" -rich==12.6.0;python_version<"3.7" -rich==13.5.2;python_version>="3.7" +mdurl==0.1.2 +rich==13.5.2 # --- Testing Requirements --- # # ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 4b67dc49519..a0fbd556a8e 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.17.14" +__version__ = "4.18.0" diff --git a/seleniumbase/console_scripts/ReadMe.md b/seleniumbase/console_scripts/ReadMe.md index 5b8d1f8f510..8e4fccb9f24 100644 --- a/seleniumbase/console_scripts/ReadMe.md +++ b/seleniumbase/console_scripts/ReadMe.md @@ -70,7 +70,7 @@ sbase get chromedriver -p ``` (Drivers: ``chromedriver``, ``geckodriver``, ``edgedriver``, - ``iedriver``, ``operadriver``, ``uc_driver``) + ``iedriver``, ``uc_driver``) (Options: A specific driver version or major version integer. If not set, the driver version matches the browser. diff --git a/seleniumbase/console_scripts/run.py b/seleniumbase/console_scripts/run.py index 2a22c666ac0..373a43bc376 100644 --- a/seleniumbase/console_scripts/run.py +++ b/seleniumbase/console_scripts/run.py @@ -130,7 +130,7 @@ def show_install_usage(): print(" OR: sbase install [DRIVER_NAME] [OPTIONS]") print(" OR: sbase get [DRIVER_NAME] [OPTIONS]") print(" (Drivers: chromedriver, geckodriver, edgedriver") - print(" iedriver, operadriver, uc_driver)") + print(" iedriver, uc_driver)") print(" Options:") print(" VERSION Specify the version to download.") print(" Tries to detect the needed version.") diff --git a/seleniumbase/console_scripts/sb_install.py b/seleniumbase/console_scripts/sb_install.py index 339556b05ce..7f1e45e651b 100644 --- a/seleniumbase/console_scripts/sb_install.py +++ b/seleniumbase/console_scripts/sb_install.py @@ -3,7 +3,7 @@ Usage: sbase get {chromedriver|geckodriver|edgedriver| - iedriver|operadriver} [OPTIONS] + iedriver|uc_driver} [OPTIONS] Options: VERSION Specify the version. Tries to detect the needed version. @@ -16,6 +16,8 @@ sbase get edgedriver sbase get chromedriver 114 sbase get chromedriver 114.0.5735.90 + sbase get chromedriver stable + sbase get chromedriver beta sbase get chromedriver -p Output: Downloads the webdriver to seleniumbase/drivers/ @@ -50,7 +52,6 @@ DEFAULT_CHROMEDRIVER_VERSION = "114.0.5735.90" # (If can't find LATEST_STABLE) DEFAULT_GECKODRIVER_VERSION = "v0.33.0" DEFAULT_EDGEDRIVER_VERSION = "115.0.1901.183" # (If can't find LATEST_STABLE) -DEFAULT_OPERADRIVER_VERSION = "v.96.0.4664.45" def invalid_run_command(): @@ -61,7 +62,7 @@ def invalid_run_command(): exp += " OR seleniumbase get [DRIVER] [OPTIONS]\n" exp += " OR sbase get [DRIVER] [OPTIONS]\n" exp += " (Drivers: chromedriver, geckodriver, edgedriver,\n" - exp += " iedriver, operadriver, uc_driver)\n" + exp += " iedriver, uc_driver)\n" exp += " Options:\n" exp += " VERSION Specify the version.\n" exp += " Tries to detect the needed version.\n" @@ -287,7 +288,6 @@ def main(override=None, intel_for_uc=None, force_uc=None): downloads_folder = DRIVER_DIR expected_contents = None platform_code = None - inner_folder = None copy_to_path = False latest_version = "" use_version = "" @@ -717,7 +717,7 @@ def main(override=None, intel_for_uc=None, force_uc=None): else: raise Exception( "Sorry! IEDriver is only for " - "Windows-based operating systems!" + "Windows-based systems!" ) download_url = ( "https://selenium-release.storage.googleapis.com/" @@ -736,71 +736,6 @@ def main(override=None, intel_for_uc=None, force_uc=None): msg = c2 + "HeadlessIEDriver to download" + cr p_version = c3 + headless_ie_version + cr log_d("\n*** %s = %s" % (msg, p_version)) - elif name == "operadriver" or name == "operachromiumdriver": - name = "operadriver" - use_version = DEFAULT_OPERADRIVER_VERSION - get_latest = False - if num_args == 4 or num_args == 5: - if "-p" not in sys.argv[3].lower(): - use_version = sys.argv[3] - if use_version.lower() == "latest": - use_version = DEFAULT_OPERADRIVER_VERSION - else: - copy_to_path = True - if num_args == 5: - if "-p" in sys.argv[4].lower(): - copy_to_path = True - else: - invalid_run_command() - if IS_MAC: - file_name = "operadriver_mac64.zip" - platform_code = "mac64" - inner_folder = "operadriver_%s/" % platform_code - expected_contents = [ - "operadriver_mac64/", - "operadriver_mac64/operadriver", - "operadriver_mac64/sha512_sum", - ] - elif IS_LINUX: - file_name = "operadriver_linux64.zip" - platform_code = "linux64" - inner_folder = "operadriver_%s/" % platform_code - expected_contents = [ - "operadriver_linux64/", - "operadriver_linux64/operadriver", - "operadriver_linux64/sha512_sum", - ] - elif IS_WINDOWS and "64" in ARCH: - file_name = "operadriver_win64.zip" - platform_code = "win64" - inner_folder = "operadriver_%s/" % platform_code - expected_contents = [ - "operadriver_win64/", - "operadriver_win64/operadriver.exe", - "operadriver_win64/sha512_sum", - ] - elif IS_WINDOWS: - file_name = "operadriver_win32.zip" - platform_code = "win32" - inner_folder = "operadriver_%s/" % platform_code - expected_contents = [ - "operadriver_win32/", - "operadriver_win32/operadriver.exe", - "operadriver_win32/sha512_sum", - ] - else: - raise Exception( - "Cannot determine which version of Operadriver to download!" - ) - - download_url = ( - "https://github.com/operasoftware/operachromiumdriver/" - "releases/download/" - "%s/%s" % (use_version, file_name) - ) - msg = c2 + "operadriver to download" + cr - p_version = c3 + use_version + cr - log_d("\n*** %s = %s" % (msg, p_version)) else: invalid_run_command() @@ -1095,60 +1030,6 @@ def main(override=None, intel_for_uc=None, force_uc=None): make_executable(path_file) log_d("Also copied to: %s%s%s" % (c3, path_file, cr)) log_d("") - elif name == "operadriver": - if len(contents) > 3: - raise Exception("Unexpected content in OperaDriver Zip file!") - # Zip file is valid. Proceed. - driver_path = None - driver_file = None - for f_name in contents: - # Remove existing version if exists - str_name = str(f_name).split(inner_folder)[1] - new_file = os.path.join(downloads_folder, str_name) - if str_name == "operadriver" or str_name == "operadriver.exe": - driver_file = str_name - driver_path = new_file - if os.path.exists(new_file): - os.remove(new_file) - if not driver_file or not driver_path: - raise Exception("Operadriver missing from Zip file!") - log_d("Extracting %s from %s ..." % (contents, file_name)) - zip_ref.extractall(downloads_folder) - zip_ref.close() - os.remove(zip_file_path) - log_d("%sUnzip Complete!%s\n" % (c2, cr)) - inner_driver = os.path.join( - downloads_folder, inner_folder, driver_file - ) - inner_sha = os.path.join( - downloads_folder, inner_folder, "sha512_sum" - ) - shutil.copyfile(inner_driver, driver_path) - pr_driver_path = c3 + driver_path + cr - log_d( - "The file [%s] was saved to:\n%s\n" - % (driver_file, pr_driver_path) - ) - log_d("Making [%s %s] executable ..." % (driver_file, use_version)) - make_executable(driver_path) - log_d( - "%s[%s %s] is now ready for use!%s" - % (c1, driver_file, use_version, cr) - ) - if copy_to_path and os.path.exists(LOCAL_PATH): - path_file = LOCAL_PATH + driver_file - shutil.copyfile(driver_path, path_file) - make_executable(path_file) - log_d("Also copied to: %s%s%s" % (c3, path_file, cr)) - # Clean up extra files - if os.path.exists(inner_driver): - os.remove(inner_driver) - if os.path.exists(inner_sha): - os.remove(inner_sha) - if os.path.exists(os.path.join(downloads_folder, inner_folder)): - # Only works if the directory is empty - os.rmdir(os.path.join(downloads_folder, inner_folder)) - log_d("") elif len(contents) == 0: raise Exception("Zip file %s is empty!" % zip_file_path) else: diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index c8c84b99aac..132abeea546 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -10,6 +10,7 @@ import warnings from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.common.options import ArgOptions from selenium.webdriver.common.service import utils as service_utils from selenium.webdriver.edge.service import Service as EdgeService from selenium.webdriver.firefox.service import Service as FirefoxService @@ -25,11 +26,6 @@ from seleniumbase.fixtures import shared_utils urllib3.disable_warnings() -selenium4_or_newer = False -if sys.version_info >= (3, 7): - selenium4_or_newer = True - from selenium.webdriver.common.options import ArgOptions - DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__)) # Make sure that the SeleniumBase DRIVER_DIR is at the top of the System PATH # (Changes to the System PATH with os.environ only last during the test run) @@ -57,7 +53,6 @@ LOCAL_EDGEDRIVER = None LOCAL_IEDRIVER = None LOCAL_HEADLESS_IEDRIVER = None -LOCAL_OPERADRIVER = None LOCAL_UC_DRIVER = None IS_ARM_MAC = shared_utils.is_arm_mac() IS_MAC = shared_utils.is_mac() @@ -67,7 +62,6 @@ LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver" LOCAL_GECKODRIVER = DRIVER_DIR + "/geckodriver" LOCAL_EDGEDRIVER = DRIVER_DIR + "/msedgedriver" - LOCAL_OPERADRIVER = DRIVER_DIR + "/operadriver" LOCAL_UC_DRIVER = DRIVER_DIR + "/uc_driver" elif IS_WINDOWS: LOCAL_EDGEDRIVER = DRIVER_DIR + "/msedgedriver.exe" @@ -75,7 +69,6 @@ LOCAL_HEADLESS_IEDRIVER = DRIVER_DIR + "/headless_ie_selenium.exe" LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver.exe" LOCAL_GECKODRIVER = DRIVER_DIR + "/geckodriver.exe" - LOCAL_OPERADRIVER = DRIVER_DIR + "/operadriver.exe" LOCAL_UC_DRIVER = DRIVER_DIR + "/uc_driver.exe" else: # Cannot determine system @@ -361,17 +354,11 @@ def _repair_chromedriver(chrome_options, headless_options, mcv=None): "sbase get chromedriver 72.0.3626.69", shell=True ) try: - if selenium4_or_newer: - service = ChromeService(executable_path=LOCAL_CHROMEDRIVER) - driver = webdriver.Chrome( - service=service, - options=headless_options, - ) - else: - driver = webdriver.Chrome( - executable_path=LOCAL_CHROMEDRIVER, - options=headless_options, - ) + service = ChromeService(executable_path=LOCAL_CHROMEDRIVER) + driver = webdriver.Chrome( + service=service, + options=headless_options, + ) except Exception: subprocess.check_call( "sbase get chromedriver latest-1", shell=True @@ -502,11 +489,7 @@ def _add_chrome_proxy_extension( def is_using_uc(undetectable, browser_name): - if ( - selenium4_or_newer - and undetectable - and browser_name == constants.Browser.GOOGLE_CHROME - ): + if undetectable and browser_name == constants.Browser.GOOGLE_CHROME: return True return False @@ -614,8 +597,6 @@ def _set_chrome_options( from seleniumbase import undetected chrome_options = undetected.ChromeOptions() - elif browser_name == constants.Browser.OPERA: - chrome_options = webdriver.opera.options.Options() elif browser_name == constants.Browser.EDGE: chrome_options = webdriver.edge.options.Options() @@ -647,8 +628,6 @@ def _set_chrome_options( if external_pdf: prefs["plugins.always_open_pdf_externally"] = True chrome_options.add_experimental_option("prefs", prefs) - if not selenium4_or_newer: - chrome_options.add_experimental_option("w3c", True) if enable_sync: chrome_options.add_experimental_option( "excludeSwitches", @@ -660,32 +639,6 @@ def _set_chrome_options( "excludeSwitches", ["enable-automation", "enable-logging", "enable-blink-features"], ) - if browser_name == constants.Browser.OPERA: - # Disable the Blink features - if enable_sync: - chrome_options.add_experimental_option( - "excludeSwitches", - ( - [ - "enable-automation", - "enable-logging", - "disable-sync", - "enable-blink-features", - ] - ), - ) - chrome_options.add_argument("--enable-sync") - else: - chrome_options.add_experimental_option( - "excludeSwitches", - ( - [ - "enable-automation", - "enable-logging", - "enable-blink-features", - ] - ), - ) if mobile_emulator: emulator_settings = {} device_metrics = {} @@ -756,15 +709,13 @@ def _set_chrome_options( abs_path = os.path.abspath(extension_dir) chrome_options = add_chrome_ext_dir(chrome_options, abs_path) if ( - selenium4_or_newer - and page_load_strategy + page_load_strategy and page_load_strategy.lower() in ["eager", "none"] ): # Only change it if not "normal", which is the default. chrome_options.page_load_strategy = page_load_strategy.lower() elif ( - selenium4_or_newer - and not page_load_strategy + not page_load_strategy and hasattr(settings, "PAGE_LOAD_STRATEGY") and settings.PAGE_LOAD_STRATEGY and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"] @@ -851,21 +802,16 @@ def _set_chrome_options( multi_proxy, ) chrome_options.add_argument("--proxy-pac-url=%s" % proxy_pac_url) - if browser_name != constants.Browser.OPERA: - # Opera Chromium doesn't support these switches - if ( - not is_using_uc(undetectable, browser_name) - or not enable_ws - or proxy_string - ): - chrome_options.add_argument("--ignore-certificate-errors") - if not enable_ws: - chrome_options.add_argument("--disable-web-security") - if IS_LINUX or not is_using_uc(undetectable, browser_name): - chrome_options.add_argument("--no-sandbox") - else: - # Opera Chromium only! - chrome_options.add_argument("--allow-elevated-browser") + if ( + not is_using_uc(undetectable, browser_name) + or not enable_ws + or proxy_string + ): + chrome_options.add_argument("--ignore-certificate-errors") + if not enable_ws: + chrome_options.add_argument("--disable-web-security") + if IS_LINUX or not is_using_uc(undetectable, browser_name): + chrome_options.add_argument("--no-sandbox") if remote_debug: # To access the Debugger, go to: chrome://inspect/#devices # while a Chromium driver is running. @@ -1503,7 +1449,7 @@ def get_remote_driver( device_height, device_pixel_ratio, ): - if use_wire and selenium4_or_newer: + if use_wire: pip_find_lock = fasteners.InterProcessLock( constants.PipInstall.FINDLOCK ) @@ -1623,11 +1569,7 @@ def get_remote_driver( device_height, device_pixel_ratio, ) - capabilities = None - if selenium4_or_newer: - capabilities = webdriver.ChromeOptions().to_capabilities() - else: - capabilities = chrome_options.to_capabilities() + capabilities = webdriver.ChromeOptions().to_capabilities() # Set custom desired capabilities selenoid = False selenoid_options = None @@ -1648,34 +1590,27 @@ def get_remote_driver( platform_name = desired_caps[key] elif re.match("[a-zA-Z0-9]*:[a-zA-Z0-9]*", key): extension_capabilities[key] = desired_caps[key] - if selenium4_or_newer: - chrome_options.set_capability("cloud:options", capabilities) - if selenoid: - snops = selenoid_options - chrome_options.set_capability("selenoid:options", snops) - if screen_resolution: - scres = screen_resolution - chrome_options.set_capability("screenResolution", scres) - if browser_version: - br_vers = browser_version - chrome_options.set_capability("browserVersion", br_vers) - if platform_name: - plat_name = platform_name - chrome_options.set_capability("platformName", plat_name) - if extension_capabilities: - for key in extension_capabilities: - ext_caps = extension_capabilities - chrome_options.set_capability(key, ext_caps[key]) - return webdriver.Remote( - command_executor=address, - options=chrome_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) + chrome_options.set_capability("cloud:options", capabilities) + if selenoid: + snops = selenoid_options + chrome_options.set_capability("selenoid:options", snops) + if screen_resolution: + scres = screen_resolution + chrome_options.set_capability("screenResolution", scres) + if browser_version: + br_vers = browser_version + chrome_options.set_capability("browserVersion", br_vers) + if platform_name: + plat_name = platform_name + chrome_options.set_capability("platformName", plat_name) + if extension_capabilities: + for key in extension_capabilities: + ext_caps = extension_capabilities + chrome_options.set_capability(key, ext_caps[key]) + return webdriver.Remote( + command_executor=address, + options=chrome_options, + ) elif browser_name == constants.Browser.FIREFOX: firefox_options = _set_firefox_options( downloads_path, @@ -1690,11 +1625,7 @@ def get_remote_driver( firefox_arg, firefox_pref, ) - capabilities = None - if selenium4_or_newer: - capabilities = webdriver.FirefoxOptions().to_capabilities() - else: - capabilities = firefox_options.to_capabilities() + capabilities = webdriver.FirefoxOptions().to_capabilities() capabilities["marionette"] = True if IS_LINUX and headless: capabilities["moz:firefoxOptions"] = {"args": ["-headless"]} @@ -1718,51 +1649,35 @@ def get_remote_driver( platform_name = desired_caps[key] elif re.match("[a-zA-Z0-9]*:[a-zA-Z0-9]*", key): extension_capabilities[key] = desired_caps[key] - if selenium4_or_newer: - firefox_options.set_capability("cloud:options", capabilities) - if selenoid: - snops = selenoid_options - firefox_options.set_capability("selenoid:options", snops) - if screen_resolution: - scres = screen_resolution - firefox_options.set_capability("screenResolution", scres) - if browser_version: - br_vers = browser_version - firefox_options.set_capability("browserVersion", br_vers) - if platform_name: - plat_name = platform_name - firefox_options.set_capability("platformName", plat_name) - if extension_capabilities: - for key in extension_capabilities: - ext_caps = extension_capabilities - firefox_options.set_capability(key, ext_caps[key]) - return webdriver.Remote( - command_executor=address, - options=firefox_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) + firefox_options.set_capability("cloud:options", capabilities) + if selenoid: + snops = selenoid_options + firefox_options.set_capability("selenoid:options", snops) + if screen_resolution: + scres = screen_resolution + firefox_options.set_capability("screenResolution", scres) + if browser_version: + br_vers = browser_version + firefox_options.set_capability("browserVersion", br_vers) + if platform_name: + plat_name = platform_name + firefox_options.set_capability("platformName", plat_name) + if extension_capabilities: + for key in extension_capabilities: + ext_caps = extension_capabilities + firefox_options.set_capability(key, ext_caps[key]) + return webdriver.Remote( + command_executor=address, + options=firefox_options, + ) elif browser_name == constants.Browser.INTERNET_EXPLORER: capabilities = webdriver.DesiredCapabilities.INTERNETEXPLORER - if selenium4_or_newer: - remote_options = ArgOptions() - remote_options.set_capability("cloud:options", desired_caps) - return webdriver.Remote( - command_executor=address, - options=remote_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - for key in desired_caps.keys(): - capabilities[key] = desired_caps[key] - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) + remote_options = ArgOptions() + remote_options.set_capability("cloud:options", desired_caps) + return webdriver.Remote( + command_executor=address, + options=remote_options, + ) elif browser_name == constants.Browser.EDGE: edge_options = _set_chrome_options( browser_name, @@ -1814,11 +1729,7 @@ def get_remote_driver( device_height, device_pixel_ratio, ) - capabilities = None - if selenium4_or_newer: - capabilities = webdriver.EdgeOptions().to_capabilities() - else: - capabilities = chrome_options.to_capabilities() + capabilities = webdriver.EdgeOptions().to_capabilities() # Set custom desired capabilities selenoid = False selenoid_options = None @@ -1839,173 +1750,43 @@ def get_remote_driver( platform_name = desired_caps[key] elif re.match("[a-zA-Z0-9]*:[a-zA-Z0-9]*", key): extension_capabilities[key] = desired_caps[key] - if selenium4_or_newer: - edge_options.set_capability("cloud:options", capabilities) - if selenoid: - snops = selenoid_options - edge_options.set_capability("selenoid:options", snops) - if screen_resolution: - scres = screen_resolution - edge_options.set_capability("screenResolution", scres) - if browser_version: - br_vers = browser_version - edge_options.set_capability("browserVersion", br_vers) - if platform_name: - plat_name = platform_name - edge_options.set_capability("platformName", plat_name) - if extension_capabilities: - for key in extension_capabilities: - ext_caps = extension_capabilities - edge_options.set_capability(key, ext_caps[key]) - return webdriver.Remote( - command_executor=address, - options=edge_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - for key in desired_caps.keys(): - capabilities[key] = desired_caps[key] - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) + edge_options.set_capability("cloud:options", capabilities) + if selenoid: + snops = selenoid_options + edge_options.set_capability("selenoid:options", snops) + if screen_resolution: + scres = screen_resolution + edge_options.set_capability("screenResolution", scres) + if browser_version: + br_vers = browser_version + edge_options.set_capability("browserVersion", br_vers) + if platform_name: + plat_name = platform_name + edge_options.set_capability("platformName", plat_name) + if extension_capabilities: + for key in extension_capabilities: + ext_caps = extension_capabilities + edge_options.set_capability(key, ext_caps[key]) + return webdriver.Remote( + command_executor=address, + options=edge_options, + ) elif browser_name == constants.Browser.SAFARI: capabilities = webdriver.DesiredCapabilities.SAFARI - if selenium4_or_newer: - remote_options = ArgOptions() - remote_options.set_capability("cloud:options", desired_caps) - return webdriver.Remote( - command_executor=address, - options=remote_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - for key in desired_caps.keys(): - capabilities[key] = desired_caps[key] - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) - elif browser_name == constants.Browser.OPERA: - opera_options = _set_chrome_options( - browser_name, - downloads_path, - headless, - locale_code, - proxy_string, - proxy_auth, - proxy_user, - proxy_pass, - proxy_bypass_list, - proxy_pac_url, - multi_proxy, - user_agent, - recorder_ext, - disable_js, - disable_csp, - enable_ws, - enable_sync, - use_auto_ext, - undetectable, - uc_cdp_events, - uc_subprocess, - no_sandbox, - disable_gpu, - headless2, - incognito, - guest_mode, - dark_mode, - devtools, - remote_debug, - enable_3d_apis, - swiftshader, - ad_block_on, - block_images, - do_not_track, - chromium_arg, - user_data_dir, - extension_zip, - extension_dir, - binary_location, - driver_version, - page_load_strategy, - use_wire, - external_pdf, - servername, - mobile_emulator, - device_width, - device_height, - device_pixel_ratio, + remote_options = ArgOptions() + remote_options.set_capability("cloud:options", desired_caps) + return webdriver.Remote( + command_executor=address, + options=remote_options, ) - capabilities = None - if selenium4_or_newer: - capabilities = webdriver.DesiredCapabilities.OPERA - else: - opera_options = webdriver.opera.options.Options() - capabilities = opera_options.to_capabilities() - # Set custom desired capabilities - selenoid = False - selenoid_options = None - screen_resolution = None - browser_version = None - platform_name = None - extension_capabilities = {} - for key in desired_caps.keys(): - capabilities[key] = desired_caps[key] - if key == "selenoid:options": - selenoid = True - selenoid_options = desired_caps[key] - elif key == "screenResolution": - screen_resolution = desired_caps[key] - elif key == "version" or key == "browserVersion": - browser_version = desired_caps[key] - elif key == "platform" or key == "platformName": - platform_name = desired_caps[key] - elif re.match("[a-zA-Z0-9]*:[a-zA-Z0-9]*", key): - extension_capabilities[key] = desired_caps[key] - if selenium4_or_newer: - opera_options.set_capability("cloud:options", capabilities) - if selenoid: - snops = selenoid_options - opera_options.set_capability("selenoid:options", snops) - if screen_resolution: - scres = screen_resolution - opera_options.set_capability("screenResolution", scres) - if browser_version: - br_vers = browser_version - opera_options.set_capability("browserVersion", br_vers) - if platform_name: - plat_name = platform_name - opera_options.set_capability("platformName", plat_name) - if extension_capabilities: - for key in extension_capabilities: - ext_caps = extension_capabilities - opera_options.set_capability(key, ext_caps[key]) - return webdriver.Remote( - command_executor=address, - options=opera_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - return webdriver.Remote( - command_executor=address, - desired_capabilities=capabilities, - ) elif browser_name == constants.Browser.REMOTE: - if selenium4_or_newer: - remote_options = ArgOptions() - for cap_name, cap_value in desired_caps.items(): - remote_options.set_capability(cap_name, cap_value) - return webdriver.Remote( - command_executor=address, - options=remote_options, - ) - else: - warnings.simplefilter("ignore", category=DeprecationWarning) - return webdriver.Remote( - command_executor=address, - desired_capabilities=desired_caps, - ) + remote_options = ArgOptions() + for cap_name, cap_value in desired_caps.items(): + remote_options.set_capability(cap_name, cap_value) + return webdriver.Remote( + command_executor=address, + options=remote_options, + ) def get_local_driver( @@ -2063,7 +1844,7 @@ def get_local_driver( Can also be used to spin up additional browsers for the same test.""" downloads_path = DOWNLOADS_FOLDER b_path = binary_location - if use_wire and selenium4_or_newer: + if use_wire: driver_fixing_lock = fasteners.InterProcessLock( constants.MultiBrowser.DRIVER_FIXING_LOCK ) @@ -2127,101 +1908,88 @@ def get_local_driver( sys.argv = sys_args # Put back original sys args # Launch Firefox if os.path.exists(LOCAL_GECKODRIVER): - if selenium4_or_newer: - service = FirefoxService( - executable_path=LOCAL_GECKODRIVER, - log_output=os.devnull, + service = FirefoxService( + executable_path=LOCAL_GECKODRIVER, + log_output=os.devnull, + ) + try: + return webdriver.Firefox( + service=service, + options=firefox_options, ) - try: - return webdriver.Firefox( - service=service, - options=firefox_options, + except BaseException as e: + if ( + "geckodriver unexpectedly exited" in str(e) + or "Process unexpectedly closed" in str(e) + or "Failed to read marionette port" in str(e) + or "A connection attempt failed" in str(e) + or hasattr(e, "msg") and ( + "geckodriver unexpectedly exited" in e.msg + or "Process unexpectedly closed" in e.msg + or "Failed to read marionette port" in e.msg + or "A connection attempt failed" in e.msg ) - except BaseException as e: + ): + time.sleep(0.1) if ( - "geckodriver unexpectedly exited" in str(e) - or "Process unexpectedly closed" in str(e) - or "Failed to read marionette port" in str(e) - or "A connection attempt failed" in str(e) - or hasattr(e, "msg") and ( - "geckodriver unexpectedly exited" in e.msg - or "Process unexpectedly closed" in e.msg - or "Failed to read marionette port" in e.msg - or "A connection attempt failed" in e.msg - ) - ): - time.sleep(0.1) - if ( - IS_LINUX - and headless - and ( - "unexpected" in str(e) - or ( - hasattr(e, "msg") and "unexpected" in e.msg - ) + IS_LINUX + and headless + and ( + "unexpected" in str(e) + or ( + hasattr(e, "msg") and "unexpected" in e.msg ) - ): - firefox_options.add_argument("-headless") - return webdriver.Firefox( - service=service, - options=firefox_options, ) - else: - raise # Not an obvious fix. - else: - return webdriver.Firefox( - executable_path=LOCAL_GECKODRIVER, - service_log_path=os.devnull, - options=firefox_options, - ) - else: - if selenium4_or_newer: - service = FirefoxService(log_output=os.devnull) - try: + ): + firefox_options.add_argument("-headless") return webdriver.Firefox( service=service, options=firefox_options, ) - except BaseException as e: - if ( - "geckodriver unexpectedly exited" in str(e) - or "Process unexpectedly closed" in str(e) - or "Failed to read marionette port" in str(e) - or "A connection attempt failed" in str(e) - or hasattr(e, "msg") and ( - "geckodriver unexpectedly exited" in e.msg - or "Process unexpectedly closed" in e.msg - or "Failed to read marionette port" in e.msg - or "A connection attempt failed" in e.msg - ) - ): - time.sleep(0.1) - if ( - IS_LINUX - and headless - and ( - "unexpected" in str(e) - or ( - hasattr(e, "msg") and "unexpected" in e.msg - ) - ) - ): - firefox_options.add_argument("-headless") - return webdriver.Firefox( - service=service, - options=firefox_options, - ) - else: - raise # Not an obvious fix. - else: + else: + raise # Not an obvious fix. + else: + service = FirefoxService(log_output=os.devnull) + try: return webdriver.Firefox( - service_log_path=os.devnull, + service=service, options=firefox_options, ) + except BaseException as e: + if ( + "geckodriver unexpectedly exited" in str(e) + or "Process unexpectedly closed" in str(e) + or "Failed to read marionette port" in str(e) + or "A connection attempt failed" in str(e) + or hasattr(e, "msg") and ( + "geckodriver unexpectedly exited" in e.msg + or "Process unexpectedly closed" in e.msg + or "Failed to read marionette port" in e.msg + or "A connection attempt failed" in e.msg + ) + ): + time.sleep(0.1) + if ( + IS_LINUX + and headless + and ( + "unexpected" in str(e) + or ( + hasattr(e, "msg") and "unexpected" in e.msg + ) + ) + ): + firefox_options.add_argument("-headless") + return webdriver.Firefox( + service=service, + options=firefox_options, + ) + else: + raise # Not an obvious fix. elif browser_name == constants.Browser.INTERNET_EXPLORER: if not IS_WINDOWS: raise Exception( - "IE Browser is for Windows-based operating systems only!" + "IE Browser is for Windows-based systems only!" ) from selenium.webdriver.ie.options import Options @@ -2393,12 +2161,8 @@ def get_local_driver( sys.argv = sys_args # Put back the original sys args # For Microsoft Edge (Chromium) version 80 or higher - if selenium4_or_newer: - Edge = webdriver.edge.webdriver.WebDriver - EdgeOptions = webdriver.edge.webdriver.Options - else: - from msedge.selenium_tools import Edge, EdgeOptions - + Edge = webdriver.edge.webdriver.WebDriver + EdgeOptions = webdriver.edge.webdriver.Options if LOCAL_EDGEDRIVER and os.path.exists(LOCAL_EDGEDRIVER): try: make_driver_executable_if_not(LOCAL_EDGEDRIVER) @@ -2420,8 +2184,6 @@ def get_local_driver( if external_pdf: prefs["plugins.always_open_pdf_externally"] = True edge_options.add_experimental_option("prefs", prefs) - if not selenium4_or_newer: - edge_options.add_experimental_option("w3c", True) edge_options.add_argument( "--disable-blink-features=AutomationControlled" ) @@ -2431,8 +2193,7 @@ def get_local_driver( if not enable_sync: edge_options.add_argument("--disable-sync") if ( - (guest_mode or IS_WINDOWS or selenium4_or_newer) - and not recorder_ext and not disable_csp and not proxy_auth + not recorder_ext and not disable_csp and not proxy_auth ): edge_options.add_argument("--guest") if dark_mode: @@ -2536,15 +2297,13 @@ def get_local_driver( edge_options.add_argument("--disable-renderer-backgrounding") edge_options.add_argument("--disable-backgrounding-occluded-windows") if ( - selenium4_or_newer - and page_load_strategy + page_load_strategy and page_load_strategy.lower() in ["eager", "none"] ): # Only change it if not "normal", which is the default. edge_options.page_load_strategy = page_load_strategy.lower() elif ( - selenium4_or_newer - and not page_load_strategy + not page_load_strategy and hasattr(settings, "PAGE_LOAD_STRATEGY") and settings.PAGE_LOAD_STRATEGY and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"] @@ -2634,168 +2393,94 @@ def get_local_driver( edge_options.add_argument(chromium_arg_item) if binary_location: edge_options.binary_location = binary_location - if selenium4_or_newer: - try: + try: + service = EdgeService( + executable_path=LOCAL_EDGEDRIVER, + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + driver = Edge(service=service, options=edge_options) + except Exception as e: + if not hasattr(e, "msg"): + raise + auto_upgrade_edgedriver = False + edge_version = None + if ( + "This version of MSEdgeDriver only supports" in e.msg + or "This version of Microsoft Edge WebDriver" in e.msg + ): + if "Current browser version is " in e.msg: + auto_upgrade_edgedriver = True + edge_version = e.msg.split( + "Current browser version is " + )[1].split(" ")[0] + elif "only supports MSEdge version " in e.msg: + auto_upgrade_edgedriver = True + edge_version = e.msg.split( + "only supports MSEdge version " + )[1].split(" ")[0] + elif "DevToolsActivePort file doesn't exist" in e.msg: service = EdgeService( executable_path=LOCAL_EDGEDRIVER, log_output=os.devnull, service_args=["--disable-build-check"], ) - driver = Edge(service=service, options=edge_options) - except Exception as e: - if not hasattr(e, "msg"): - raise - auto_upgrade_edgedriver = False - edge_version = None - if ( - "This version of MSEdgeDriver only supports" in e.msg - or "This version of Microsoft Edge WebDriver" in e.msg - ): - if "Current browser version is " in e.msg: - auto_upgrade_edgedriver = True - edge_version = e.msg.split( - "Current browser version is " - )[1].split(" ")[0] - elif "only supports MSEdge version " in e.msg: - auto_upgrade_edgedriver = True - edge_version = e.msg.split( - "only supports MSEdge version " - )[1].split(" ")[0] - elif "DevToolsActivePort file doesn't exist" in e.msg: - service = EdgeService( - executable_path=LOCAL_EDGEDRIVER, - log_output=os.devnull, - service_args=["--disable-build-check"], - ) - # https://stackoverflow.com/a/56638103/7058266 - args = " ".join(sys.argv) - free_port = 9222 - if ("-n" in sys.argv or " -n=" in args or args == "-c"): - free_port = service_utils.free_port() - edge_options.add_argument( - "--remote-debugging-port=%s" % free_port - ) - return Edge(service=service, options=edge_options) - if not auto_upgrade_edgedriver: - raise # Not an obvious fix. - else: - pass # Try upgrading EdgeDriver to match Edge. + # https://stackoverflow.com/a/56638103/7058266 args = " ".join(sys.argv) - if "-n" in sys.argv or " -n=" in args or args == "-c": - edgedriver_fixing_lock = fasteners.InterProcessLock( - constants.MultiBrowser.DRIVER_FIXING_LOCK - ) - with edgedriver_fixing_lock: - try: - if not _was_driver_repaired(): - _repair_edgedriver(edge_version) - _mark_driver_repaired() - except Exception: - pass - else: - try: - if not _was_driver_repaired(): - _repair_edgedriver(edge_version) - _mark_driver_repaired() - except Exception: - pass - service = EdgeService( - executable_path=LOCAL_EDGEDRIVER, - log_output=os.devnull, - service_args=["--disable-build-check"], + free_port = 9222 + if ("-n" in sys.argv or " -n=" in args or args == "-c"): + free_port = service_utils.free_port() + edge_options.add_argument( + "--remote-debugging-port=%s" % free_port ) - driver = Edge(service=service, options=edge_options) - return driver - else: - capabilities = edge_options.to_capabilities() - capabilities["platform"] = "" - try: - driver = Edge( - executable_path=LOCAL_EDGEDRIVER, - service_log_path=os.devnull, - capabilities=capabilities, + return Edge(service=service, options=edge_options) + if not auto_upgrade_edgedriver: + raise # Not an obvious fix. + else: + pass # Try upgrading EdgeDriver to match Edge. + args = " ".join(sys.argv) + if "-n" in sys.argv or " -n=" in args or args == "-c": + edgedriver_fixing_lock = fasteners.InterProcessLock( + constants.MultiBrowser.DRIVER_FIXING_LOCK ) - except Exception as e: - if not hasattr(e, "msg"): - raise - auto_upgrade_edgedriver = False - edge_version = None - if ( - "This version of MSEdgeDriver only supports" in e.msg - or "This version of Microsoft Edge WebDriver" in e.msg - ): - if "Current browser version is " in e.msg: - auto_upgrade_edgedriver = True - edge_version = e.msg.split( - "Current browser version is " - )[1].split(" ")[0] - elif "only supports MSEdge version " in e.msg: - auto_upgrade_edgedriver = True - edge_version = e.msg.split( - "only supports MSEdge version " - )[1].split(" ")[0] - elif "DevToolsActivePort file doesn't exist" in e.msg: - service = EdgeService( - executable_path=LOCAL_EDGEDRIVER, - log_output=os.devnull, - service_args=["--disable-build-check"], - ) - # https://stackoverflow.com/a/56638103/7058266 - args = " ".join(sys.argv) - free_port = 9222 - if ("-n" in sys.argv or " -n=" in args or args == "-c"): - free_port = service_utils.free_port() - edge_options.add_argument( - "--remote-debugging-port=%s" % free_port - ) - return Edge(service=service, options=edge_options) - if not auto_upgrade_edgedriver: - raise # Not an obvious fix. - else: - pass # Try upgrading EdgeDriver to match Edge. - args = " ".join(sys.argv) - if "-n" in sys.argv or " -n=" in args or args == "-c": - edgedriver_fixing_lock = fasteners.InterProcessLock( - constants.MultiBrowser.DRIVER_FIXING_LOCK - ) - with edgedriver_fixing_lock: + with edgedriver_fixing_lock: + try: if not _was_driver_repaired(): _repair_edgedriver(edge_version) _mark_driver_repaired() - else: + except Exception: + pass + else: + try: if not _was_driver_repaired(): _repair_edgedriver(edge_version) _mark_driver_repaired() - driver = Edge( - executable_path=LOCAL_EDGEDRIVER, - service_log_path=os.devnull, - service_args=["--disable-build-check"], - capabilities=capabilities, - ) - return driver + except Exception: + pass + service = EdgeService( + executable_path=LOCAL_EDGEDRIVER, + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + driver = Edge(service=service, options=edge_options) + return driver elif browser_name == constants.Browser.SAFARI: args = " ".join(sys.argv) if ("-n" in sys.argv or " -n=" in args or args == "-c"): # Skip if multithreaded raise Exception("Can't run Safari tests in multithreaded mode!") warnings.simplefilter("ignore", category=DeprecationWarning) - if not selenium4_or_newer: - return webdriver.safari.webdriver.WebDriver() - from selenium.webdriver.safari.options import Options as SafariOptions - service = SafariService(quiet=False) options = SafariOptions() if ( - selenium4_or_newer - and page_load_strategy + page_load_strategy and page_load_strategy.lower() in ["eager", "none"] ): # Only change it if not "normal", which is the default. options.page_load_strategy = page_load_strategy.lower() elif ( - selenium4_or_newer - and not page_load_strategy + not page_load_strategy and hasattr(settings, "PAGE_LOAD_STRATEGY") and settings.PAGE_LOAD_STRATEGY and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"] @@ -2805,74 +2490,6 @@ def get_local_driver( return webdriver.safari.webdriver.WebDriver( service=service, options=options ) - elif browser_name == constants.Browser.OPERA: - try: - if LOCAL_OPERADRIVER and os.path.exists(LOCAL_OPERADRIVER): - try: - make_driver_executable_if_not(LOCAL_OPERADRIVER) - except Exception as e: - logging.debug( - "\nWarning: Could not make operadriver" - " executable: %s" % e - ) - # Opera Chromium doesn't support headless mode. - # https://github.com/operasoftware/operachromiumdriver/issues/62 - headless = False - opera_options = _set_chrome_options( - browser_name, - downloads_path, - headless, - locale_code, - proxy_string, - proxy_auth, - proxy_user, - proxy_pass, - proxy_bypass_list, - proxy_pac_url, - multi_proxy, - user_agent, - recorder_ext, - disable_js, - disable_csp, - enable_ws, - enable_sync, - use_auto_ext, - undetectable, - uc_cdp_events, - uc_subprocess, - no_sandbox, - disable_gpu, - headless2, - incognito, - guest_mode, - dark_mode, - devtools, - remote_debug, - enable_3d_apis, - swiftshader, - ad_block_on, - block_images, - do_not_track, - chromium_arg, - user_data_dir, - extension_zip, - extension_dir, - binary_location, - driver_version, - page_load_strategy, - use_wire, - external_pdf, - servername, - mobile_emulator, - device_width, - device_height, - device_pixel_ratio, - ) - warnings.simplefilter("ignore", category=DeprecationWarning) - return webdriver.Opera(options=opera_options) - except Exception: - # Opera support was dropped! Downgrade to Python 3.6 to use it! - return webdriver.Opera() elif browser_name == constants.Browser.GOOGLE_CHROME: try: chrome_options = _set_chrome_options( @@ -3279,111 +2896,93 @@ def get_local_driver( os.path.exists(LOCAL_CHROMEDRIVER) or is_using_uc(undetectable, browser_name) ): - if selenium4_or_newer: - if headless and not IS_LINUX: - undetectable = False # No support for headless - if is_using_uc(undetectable, browser_name): - from seleniumbase import undetected - from urllib.error import URLError - - if IS_LINUX: - if "--headless" in ( - chrome_options.arguments - ): - chrome_options.arguments.remove( - "--headless" - ) - uc_chrome_version = None - if ( - use_version.isnumeric() - and int(use_version) >= 72 - ): - uc_chrome_version = int(use_version) - cdp_events = uc_cdp_events - cert = "unable to get local issuer certificate" - mac_certificate_error = False - if ( - use_version.isnumeric() - and int(use_version) <= 74 - ): - chrome_options.add_experimental_option( - "w3c", True - ) - try: - uc_path = None - if os.path.exists(LOCAL_UC_DRIVER): - uc_path = LOCAL_UC_DRIVER - uc_path = os.path.realpath(uc_path) - driver = undetected.Chrome( - options=chrome_options, - user_data_dir=user_data_dir, - driver_executable_path=uc_path, - browser_executable_path=b_path, - enable_cdp_events=cdp_events, - headless=False, # Xvfb needed! - version_main=uc_chrome_version, - use_subprocess=True, # Always! - ) - uc_activated = True - except URLError as e: - if cert in e.args[0] and IS_MAC: - mac_certificate_error = True - else: - raise - if mac_certificate_error: - cf_lock_path = ( - constants.MultiBrowser.CERT_FIXING_LOCK - ) - cf_lock = fasteners.InterProcessLock( - constants.MultiBrowser.CERT_FIXING_LOCK - ) - if not os.path.exists(cf_lock_path): - # Avoid multithreaded issues - with cf_lock: - # Install Python Certificates (MAC) - os.system( - r"bash /Applications/Python*/" - r"Install\ " - r"Certificates.command" - ) - driver = undetected.Chrome( - options=chrome_options, - user_data_dir=user_data_dir, - driver_executable_path=uc_path, - browser_executable_path=b_path, - enable_cdp_events=cdp_events, - headless=False, # Xvfb needed! - version_main=uc_chrome_version, - use_subprocess=True, # Always! - ) - uc_activated = True - else: - if ( - use_version.isnumeric() - and int(use_version) <= 74 + if headless and not IS_LINUX: + undetectable = False # No support for headless + if is_using_uc(undetectable, browser_name): + from seleniumbase import undetected + from urllib.error import URLError + + if IS_LINUX: + if "--headless" in ( + chrome_options.arguments ): - chrome_options.add_experimental_option( - "w3c", True + chrome_options.arguments.remove( + "--headless" ) - service = ChromeService( - executable_path=LOCAL_CHROMEDRIVER, - log_output=os.devnull, - service_args=service_args, + uc_chrome_version = None + if ( + use_version.isnumeric() + and int(use_version) >= 72 + ): + uc_chrome_version = int(use_version) + cdp_events = uc_cdp_events + cert = "unable to get local issuer certificate" + mac_certificate_error = False + if ( + use_version.isnumeric() + and int(use_version) <= 74 + ): + chrome_options.add_experimental_option( + "w3c", True ) - driver = webdriver.Chrome( - service=service, + try: + uc_path = None + if os.path.exists(LOCAL_UC_DRIVER): + uc_path = LOCAL_UC_DRIVER + uc_path = os.path.realpath(uc_path) + driver = undetected.Chrome( options=chrome_options, + user_data_dir=user_data_dir, + driver_executable_path=uc_path, + browser_executable_path=b_path, + enable_cdp_events=cdp_events, + headless=False, # Xvfb needed! + version_main=uc_chrome_version, + use_subprocess=True, # Always! + ) + uc_activated = True + except URLError as e: + if cert in e.args[0] and IS_MAC: + mac_certificate_error = True + else: + raise + if mac_certificate_error: + cf_lock_path = ( + constants.MultiBrowser.CERT_FIXING_LOCK + ) + cf_lock = fasteners.InterProcessLock( + constants.MultiBrowser.CERT_FIXING_LOCK ) + if not os.path.exists(cf_lock_path): + # Avoid multithreaded issues + with cf_lock: + # Install Python Certificates (MAC) + os.system( + r"bash /Applications/Python*/" + r"Install\ " + r"Certificates.command" + ) + driver = undetected.Chrome( + options=chrome_options, + user_data_dir=user_data_dir, + driver_executable_path=uc_path, + browser_executable_path=b_path, + enable_cdp_events=cdp_events, + headless=False, # Xvfb needed! + version_main=uc_chrome_version, + use_subprocess=True, # Always! + ) + uc_activated = True else: - driver = webdriver.Chrome( - executable_path=LOCAL_CHROMEDRIVER, - service_log_path=os.devnull, - service_args=service_args, - options=chrome_options, - ) - else: - if selenium4_or_newer: + if ( + use_version.isnumeric() + and int(use_version) <= 74 + ): + chrome_options.add_experimental_option( + "w3c", True + ) service = ChromeService( + executable_path=LOCAL_CHROMEDRIVER, log_output=os.devnull, service_args=service_args, ) @@ -3391,12 +2990,15 @@ def get_local_driver( service=service, options=chrome_options, ) - else: - driver = webdriver.Chrome( - service_log_path=os.devnull, - service_args=service_args, - options=chrome_options, - ) + else: + service = ChromeService( + log_output=os.devnull, + service_args=service_args, + ) + driver = webdriver.Chrome( + service=service, + options=chrome_options, + ) except Exception as e: if not hasattr(e, "msg"): raise @@ -3406,21 +3008,18 @@ def get_local_driver( elif "Chrome version must be between" in e.msg: auto_upgrade_chromedriver = True elif "Missing or invalid capabilities" in e.msg: - if selenium4_or_newer: - chrome_options.add_experimental_option("w3c", True) - service = ChromeService( - log_output=os.devnull, - service_args=service_args, + chrome_options.add_experimental_option("w3c", True) + service = ChromeService( + log_output=os.devnull, + service_args=service_args, + ) + with warnings.catch_warnings(): + warnings.simplefilter( + "ignore", category=DeprecationWarning + ) + return webdriver.Chrome( + service=service, options=chrome_options ) - with warnings.catch_warnings(): - warnings.simplefilter( - "ignore", category=DeprecationWarning - ) - return webdriver.Chrome( - service=service, options=chrome_options - ) - else: - raise if not auto_upgrade_chromedriver: raise # Not an obvious fix. else: @@ -3507,37 +3106,24 @@ def get_local_driver( ) _mark_driver_repaired() if os.path.exists(LOCAL_CHROMEDRIVER): - if selenium4_or_newer: - service = ChromeService( - executable_path=LOCAL_CHROMEDRIVER, - log_output=os.devnull, - service_args=["--disable-build-check"], - ) - driver = webdriver.Chrome( - service=service, - options=chrome_options, - ) - else: - driver = webdriver.Chrome( - executable_path=LOCAL_CHROMEDRIVER, - service_args=["--disable-build-check"], - options=chrome_options, - ) + service = ChromeService( + executable_path=LOCAL_CHROMEDRIVER, + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + driver = webdriver.Chrome( + service=service, + options=chrome_options, + ) else: - if selenium4_or_newer: - service = ChromeService( - log_output=os.devnull, - service_args=["--disable-build-check"], - ) - driver = webdriver.Chrome( - service=service, - options=chrome_options, - ) - else: - driver = webdriver.Chrome( - service_args=["--disable-build-check"], - options=chrome_options, - ) + service = ChromeService( + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + driver = webdriver.Chrome( + service=service, + options=chrome_options, + ) driver.default_get = driver.get # Save copy of original if uc_activated: driver.get = lambda url: uc_special_open_if_cf( @@ -3564,21 +3150,18 @@ def get_local_driver( elif "Chrome version must be between" in e.msg: auto_upgrade_chromedriver = True elif "Missing or invalid capabilities" in e.msg: - if selenium4_or_newer: - chrome_options.add_experimental_option("w3c", True) - service = ChromeService( - log_output=os.devnull, - service_args=["--disable-build-check"], + chrome_options.add_experimental_option("w3c", True) + service = ChromeService( + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + with warnings.catch_warnings(): + warnings.simplefilter( + "ignore", category=DeprecationWarning + ) + return webdriver.Chrome( + service=service, options=chrome_options ) - with warnings.catch_warnings(): - warnings.simplefilter( - "ignore", category=DeprecationWarning - ) - return webdriver.Chrome( - service=service, options=chrome_options - ) - else: - raise mcv = None # Major Chrome Version if "Current browser version is " in e.msg: line = e.msg.split("Current browser version is ")[1] @@ -3614,20 +3197,14 @@ def get_local_driver( pass _mark_driver_repaired() try: - if selenium4_or_newer: - service = ChromeService( - log_output=os.devnull, - service_args=["--disable-build-check"], - ) - return webdriver.Chrome( - service=service, - options=chrome_options, - ) - else: - return webdriver.Chrome( - service_args=["--disable-build-check"], - options=chrome_options, - ) + service = ChromeService( + log_output=os.devnull, + service_args=["--disable-build-check"], + ) + return webdriver.Chrome( + service=service, + options=chrome_options, + ) except Exception: pass # Use the virtual display on Linux during headless errors diff --git a/seleniumbase/core/log_helper.py b/seleniumbase/core/log_helper.py index 96a84bb6218..854e14ba2ab 100644 --- a/seleniumbase/core/log_helper.py +++ b/seleniumbase/core/log_helper.py @@ -103,9 +103,6 @@ def get_driver_name_and_version(driver, browser): elif driver.capabilities["browserName"].lower() == "msedge": cap_dict = driver.capabilities["msedge"] return ("msedgedriver", cap_dict["msedgedriverVersion"].split(" ")[0]) - elif driver.capabilities["browserName"].lower() == "opera": - cap_dict = driver.capabilities["opera"] - return ("operadriver", cap_dict["operadriverVersion"].split(" ")[0]) elif driver.capabilities["browserName"].lower() == "firefox": return ("geckodriver", driver.capabilities["moz:geckodriverVersion"]) elif browser == "safari": diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 2c18c8c0524..1e3e13fcdb2 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -95,9 +95,6 @@ def test_anything(self): if sys.version_info >= (3, 11): python3_11_or_newer = True py311_patch2 = constants.PatchPy311.PATCH -selenium4_or_newer = False -if sys.version_info >= (3, 7): - selenium4_or_newer = True class BaseCase(unittest.TestCase): @@ -226,7 +223,7 @@ def open(self, url): if not self.__looks_like_a_page_url(url): # url should start with one of the following: # "http:", "https:", "://", "data:", "file:", - # "about:", "chrome:", "opera:", or "edge:". + # "about:", "chrome:", or "edge:". if page_utils.is_valid_url("https://" + url): url = "https://" + url else: @@ -286,14 +283,7 @@ def open(self, url): else: raise elif "Timed out receiving message from renderer" in e.msg: - page_load_timeout = None - if selenium4_or_newer: - page_load_timeout = self.driver.timeouts.page_load - else: - if hasattr(settings, "PAGE_LOAD_TIMEOUT"): - page_load_timeout = settings.PAGE_LOAD_TIMEOUT - else: - page_load_timeout = 120 + page_load_timeout = self.driver.timeouts.page_load logging.info( "The page load timed out after %s seconds! Will retry..." % page_load_timeout @@ -3556,18 +3546,13 @@ def set_content_to_parent_frame(self): def open_new_window(self, switch_to=True): """Opens a new browser tab/window and switches to it by default.""" self.wait_for_ready_state_complete() - if selenium4_or_newer and switch_to: + if switch_to: self.driver.switch_to.new_window("tab") else: self.driver.execute_script("window.open('');") time.sleep(0.01) if self.browser == "safari": self.wait_for_ready_state_complete() - if switch_to and not selenium4_or_newer: - self.switch_to_newest_window() - time.sleep(0.01) - if self.browser == "safari": - self.wait_for_ready_state_complete() def switch_to_window(self, window, timeout=None): """Switches control of the browser to the specified window. @@ -3953,18 +3938,6 @@ def get_new_driver( self.driver.set_window_rect(10, 20, width, height) except Exception: pass - elif self.browser == "opera": - if self.maximize_option: - try: - self.driver.maximize_window() - self.wait_for_ready_state_complete() - except Exception: - pass # Keep existing browser resolution - else: - try: - self.driver.set_window_rect(10, 20, width, height) - except Exception: - pass if self.start_page and len(self.start_page) >= 4: if page_utils.is_valid_url(self.start_page): self.open(self.start_page) @@ -7345,11 +7318,11 @@ def is_online(self): return online def is_chromium(self): - """Return True if the browser is Chrome, Edge, or Opera.""" + """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", "opera"): + if browser_name.lower() in ("chrome", "edge", "msedge"): chromium = True return chromium @@ -12635,23 +12608,12 @@ def __click_with_offset( if self.__needs_minimum_wait(): time.sleep(0.05) try: - if selenium4_or_newer and not center: + if not center: element_rect = element.rect left_offset = element_rect["width"] / 2 top_offset = element_rect["height"] / 2 x = -left_offset + (math.ceil(float(x)) or 0) y = -top_offset + (math.ceil(float(y)) or 0) - elif selenium4_or_newer and center: - pass - elif not selenium4_or_newer and not center: - pass - else: - # not selenium4_or_newer and center: - element_rect = element.rect - left_offset = element_rect["width"] / 2 - top_offset = element_rect["height"] / 2 - x = left_offset + x - y = top_offset + y action_chains = ActionChains(self.driver) action_chains.move_to_element_with_offset(element, x, y) if not double: @@ -12931,7 +12893,6 @@ def __looks_like_a_page_url(self, url): or url.startswith("data:") or url.startswith("edge:") or url.startswith("file:") - or url.startswith("opera:") or url.startswith("view-source:") ): return True @@ -13219,8 +13180,7 @@ def __get_shadow_element( for selector_part in selectors[1:]: shadow_root = None if ( - selenium4_or_newer - and (self.is_chromium() or self.browser == "firefox") + (self.is_chromium() or self.browser == "firefox") and int(self.__get_major_browser_version()) >= 96 ): try: @@ -13289,8 +13249,7 @@ def __get_shadow_element( selector_chain += selector_part try: if ( - selenium4_or_newer - and (self.is_chromium() or self.browser == "firefox") + (self.is_chromium() or self.browser == "firefox") and int(self.__get_major_browser_version()) >= 96 ): if timeout == 0.1: @@ -14123,7 +14082,7 @@ def setUp(self, masterqa_mode=False): "Chrome/89.0.4389.105 Mobile Safari/537.36" ) - if self.browser in ["firefox", "ie", "safari", "opera"]: + if self.browser in ["firefox", "ie", "safari"]: # The Recorder Mode browser extension is only for Chrome/Edge. if self.recorder_mode: message = ( @@ -14255,9 +14214,7 @@ def setUp(self, masterqa_mode=False): d_height=self.__device_height, d_p_r=self.__device_pixel_ratio, ) - if selenium4_or_newer and self.driver.timeouts.implicit_wait > 0: - self.driver.implicitly_wait(0) - elif not selenium4_or_newer: + if self.driver.timeouts.implicit_wait > 0: self.driver.implicitly_wait(0) self._default_driver = self.driver if self._reuse_session: @@ -14268,7 +14225,7 @@ def setUp(self, masterqa_mode=False): self._drivers_list.append(self.driver) self._drivers_browser_map[self.driver] = self.browser - if self.browser in ["firefox", "ie", "safari", "opera"]: + if self.browser in ["firefox", "ie", "safari"]: # Only Chrome and Edge browsers have the mobile emulator. # Some actions such as hover-clicking are different on mobile. self.mobile_emulator = False @@ -15174,11 +15131,6 @@ def _get_driver_name_and_version(self): return ( "msedgedriver", cap_dict["msedgedriverVersion"].split(" ")[0] ) - elif driver.capabilities["browserName"].lower() == "opera": - cap_dict = driver.capabilities["opera"] - return ( - "operadriver", cap_dict["operadriverVersion"].split(" ")[0] - ) elif driver.capabilities["browserName"].lower() == "firefox": return ( "geckodriver", driver.capabilities["moz:geckodriverVersion"] diff --git a/seleniumbase/fixtures/constants.py b/seleniumbase/fixtures/constants.py index ec9909754af..1122042277a 100644 --- a/seleniumbase/fixtures/constants.py +++ b/seleniumbase/fixtures/constants.py @@ -352,7 +352,6 @@ class ValidBrowsers: "edge", "firefox", "ie", - "opera", "safari", "remote", ] @@ -397,7 +396,6 @@ class Browser: EDGE = "edge" FIREFOX = "firefox" INTERNET_EXPLORER = "ie" - OPERA = "opera" SAFARI = "safari" REMOTE = "remote" @@ -406,7 +404,6 @@ class Browser: "edge": None, "firefox": None, "ie": None, - "opera": None, "safari": None, "remote": None, } @@ -416,7 +413,6 @@ class Browser: "edge": None, "firefox": None, "ie": None, - "opera": None, "safari": None, "remote": None, } diff --git a/seleniumbase/fixtures/page_utils.py b/seleniumbase/fixtures/page_utils.py index 03a1e46f7d4..29ca5254d4d 100644 --- a/seleniumbase/fixtures/page_utils.py +++ b/seleniumbase/fixtures/page_utils.py @@ -122,7 +122,6 @@ def is_valid_url(url): or url.startswith("data:") or url.startswith("edge:") or url.startswith("file:") - or url.startswith("opera:") ): return True else: diff --git a/seleniumbase/plugins/driver_manager.py b/seleniumbase/plugins/driver_manager.py index 48987a3a63a..3c27b2db1f0 100644 --- a/seleniumbase/plugins/driver_manager.py +++ b/seleniumbase/plugins/driver_manager.py @@ -145,10 +145,6 @@ def Driver( browser_changes += 1 browser_set = "firefox" browser_list.append("--browser=firefox") - if "--browser=opera" in sys_argv or "--browser opera" in sys_argv: - browser_changes += 1 - browser_set = "opera" - browser_list.append("--browser=opera") if "--browser=safari" in sys_argv or "--browser safari" in sys_argv: browser_changes += 1 browser_set = "safari" @@ -178,10 +174,6 @@ def Driver( browser_changes += 1 browser_text = "ie" browser_list.append("--ie") - if "--opera" in sys_argv and not browser_set == "opera": - browser_changes += 1 - browser_text = "opera" - browser_list.append("--opera") if "--safari" in sys_argv and not browser_set == "safari": browser_changes += 1 browser_text = "safari" diff --git a/seleniumbase/plugins/pytest_plugin.py b/seleniumbase/plugins/pytest_plugin.py index efb8c8fa51f..86f5e66369e 100644 --- a/seleniumbase/plugins/pytest_plugin.py +++ b/seleniumbase/plugins/pytest_plugin.py @@ -166,13 +166,6 @@ def pytest_addoption(parser): default=False, help="""Shortcut for --browser=ie""", ) - parser.addoption( - "--opera", - action="store_true", - dest="use_opera", - default=False, - help="""Shortcut for --browser=opera""", - ) parser.addoption( "--safari", action="store_true", @@ -1315,10 +1308,6 @@ def pytest_addoption(parser): browser_changes += 1 browser_set = "firefox" browser_list.append("--browser=firefox") - if "--browser=opera" in sys_argv or "--browser opera" in sys_argv: - browser_changes += 1 - browser_set = "opera" - browser_list.append("--browser=opera") if "--browser=safari" in sys_argv or "--browser safari" in sys_argv: browser_changes += 1 browser_set = "safari" @@ -1352,11 +1341,6 @@ def pytest_addoption(parser): browser_text = "ie" sb_config._browser_shortcut = "ie" browser_list.append("--ie") - if "--opera" in sys_argv and not browser_set == "opera": - browser_changes += 1 - browser_text = "opera" - sb_config._browser_shortcut = "opera" - browser_list.append("--opera") if "--safari" in sys_argv and not browser_set == "safari": browser_changes += 1 browser_text = "safari" @@ -1670,8 +1654,6 @@ def pytest_configure(config): sb_config.browser = "firefox" elif config.getoption("use_ie"): sb_config.browser = "ie" - elif config.getoption("use_opera"): - sb_config.browser = "opera" elif config.getoption("use_safari"): sb_config.browser = "safari" else: diff --git a/seleniumbase/plugins/sb_manager.py b/seleniumbase/plugins/sb_manager.py index 391a4682742..d60527a7695 100644 --- a/seleniumbase/plugins/sb_manager.py +++ b/seleniumbase/plugins/sb_manager.py @@ -201,10 +201,6 @@ def SB( browser_changes += 1 browser_set = "firefox" browser_list.append("--browser=firefox") - if "--browser=opera" in sys_argv or "--browser opera" in sys_argv: - browser_changes += 1 - browser_set = "opera" - browser_list.append("--browser=opera") if "--browser=safari" in sys_argv or "--browser safari" in sys_argv: browser_changes += 1 browser_set = "safari" @@ -238,11 +234,6 @@ def SB( browser_text = "ie" sb_config._browser_shortcut = "ie" browser_list.append("--ie") - if "--opera" in sys_argv and not browser_set == "opera": - browser_changes += 1 - browser_text = "opera" - sb_config._browser_shortcut = "opera" - browser_list.append("--opera") if "--safari" in sys_argv and not browser_set == "safari": browser_changes += 1 browser_text = "safari" diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index bd8f252bae8..0b03faf8f27 100644 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -128,13 +128,6 @@ def options(self, parser, env): default=False, help="""Shortcut for --browser=ie""", ) - parser.addoption( - "--opera", - action="store_true", - dest="use_opera", - default=False, - help="""Shortcut for --browser=opera""", - ) parser.addoption( "--safari", action="store_true", @@ -958,10 +951,6 @@ def beforeTest(self, test): browser_changes += 1 browser_set = "firefox" browser_list.append("--browser=firefox") - if "--browser=opera" in sys_argv or "--browser opera" in sys_argv: - browser_changes += 1 - browser_set = "opera" - browser_list.append("--browser=opera") if "--browser=safari" in sys_argv or "--browser safari" in sys_argv: browser_changes += 1 browser_set = "safari" @@ -995,11 +984,6 @@ def beforeTest(self, test): browser_text = "ie" sb_config._browser_shortcut = "ie" browser_list.append("--ie") - if "--opera" in sys_argv and not browser_set == "opera": - browser_changes += 1 - browser_text = "opera" - sb_config._browser_shortcut = "opera" - browser_list.append("--opera") if "--safari" in sys_argv and not browser_set == "safari": browser_changes += 1 browser_text = "safari" diff --git a/setup.py b/setup.py index d5165f8b520..7f86a87832c 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ """Setup steps for installing SeleniumBase dependencies and plugins. -(Uses selenium 4.x and is compatible with Python 3.6+)""" +(Uses selenium 4.x and is compatible with Python 3.7+)""" from setuptools import setup, find_packages # noqa: F401 import os import sys @@ -108,7 +108,6 @@ "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -130,118 +129,83 @@ "Topic :: Software Development :: Testing :: Traffic Generation", "Topic :: Utilities", ], - python_requires=">=3.6", + python_requires=">=3.7", install_requires=[ - 'pip>=21.3.1;python_version<"3.7"', - 'pip>=23.2.1;python_version>="3.7"', - 'packaging>=21.3;python_version<"3.7"', - 'packaging>=23.1;python_version>="3.7"', - 'setuptools>=59.6.0;python_version<"3.7"', - 'setuptools>=68.0.0;python_version>="3.7" and python_version<"3.8"', + 'pip>=23.2.1', + 'packaging>=23.1', + 'setuptools>=68.0.0;python_version<"3.8"', 'setuptools>=68.1.2;python_version>="3.8"', - 'wheel>=0.37.1;python_version<"3.7"', - 'wheel>=0.41.2;python_version>="3.7"', - 'attrs==22.1.0;python_version<"3.7"', - 'attrs>=23.1.0;python_version>="3.7"', + 'wheel>=0.41.2', + 'attrs>=23.1.0', "certifi>=2023.7.22", - 'filelock>=3.4.1;python_version<"3.7"', - 'filelock>=3.12.2;python_version>="3.7" and python_version<"3.8"', + 'filelock>=3.12.2;python_version<"3.8"', 'filelock>=3.12.3;python_version>="3.8"', - 'platformdirs>=2.4.0;python_version<"3.7"', - 'platformdirs>=3.10.0;python_version>="3.7"', + 'platformdirs>=3.10.0', 'parse>=1.19.1', 'parse-type>=0.6.2', "six==1.16.0", "idna==3.4", - 'chardet==4.0.0;python_version<"3.7"', - 'chardet==5.2.0;python_version>="3.7"', - 'charset-normalizer==2.0.12;python_version<"3.7"', - 'charset-normalizer==3.2.0;python_version>="3.7"', - 'urllib3==1.26.12;python_version<"3.7"', - 'urllib3>=1.26.16,<2;python_version>="3.7" and python_version<"3.10"', # noqa: E501 + 'chardet==5.2.0', + 'charset-normalizer==3.2.0', + 'urllib3>=1.26.16,<2;python_version<"3.10"', 'urllib3>=1.26.16,<2.1.0;python_version>="3.10"', - 'requests==2.27.1;python_version<"3.7"', - 'requests==2.31.0;python_version>="3.7"', + 'requests==2.31.0', "pynose==1.4.8", - 'sniffio==1.3.0;python_version>="3.7"', - 'h11==0.14.0;python_version>="3.7"', - 'outcome==1.2.0;python_version>="3.7"', - 'trio==0.22.2;python_version>="3.7"', - 'trio-websocket==0.10.3;python_version>="3.7"', - 'wsproto==1.2.0;python_version>="3.7"', - 'selenium==3.141.0;python_version<"3.7"', - 'selenium==4.11.2;python_version>="3.7"', - 'msedge-selenium-tools==3.141.3;python_version<"3.7"', - 'cssselect==1.1.0;python_version<"3.7"', - 'cssselect==1.2.0;python_version>="3.7"', + 'sniffio==1.3.0', + 'h11==0.14.0', + 'outcome==1.2.0', + 'trio==0.22.2', + 'trio-websocket==0.10.3', + 'wsproto==1.2.0', + 'selenium==4.11.2;python_version<"3.8"', + 'selenium==4.12.0;python_version>="3.8"', + 'cssselect==1.2.0', "sortedcontainers==2.4.0", - 'fasteners==0.17.3;python_version<"3.7"', - 'fasteners==0.18;python_version>="3.7"', - 'execnet==1.9.0;python_version<"3.7"', - 'execnet==2.0.2;python_version>="3.7"', - 'iniconfig==1.1.1;python_version<"3.7"', - 'iniconfig==2.0.0;python_version>="3.7"', - 'pluggy==1.0.0;python_version<"3.7"', - 'pluggy==1.2.0;python_version>="3.7" and python_version<"3.8"', + 'fasteners==0.18', + 'execnet==2.0.2', + 'iniconfig==2.0.0', + 'pluggy==1.2.0;python_version<"3.8"', 'pluggy==1.3.0;python_version>="3.8"', "py==1.11.0", - 'pytest==7.0.1;python_version<"3.7"', - 'pytest==7.4.0;python_version>="3.7"', - 'pytest-forked==1.4.0;python_version<"3.7"', + 'pytest==7.4.0', "pytest-html==2.0.1", # Newer ones had issues - 'pytest-metadata==1.11.0;python_version<"3.7"', - 'pytest-metadata==3.0.0;python_version>="3.7"', + 'pytest-metadata==3.0.0', "pytest-ordering==0.6", - 'pytest-rerunfailures==10.3;python_version<"3.7"', - 'pytest-rerunfailures==12.0;python_version>="3.7"', - 'pytest-xdist==2.5.0;python_version<"3.7"', - 'pytest-xdist==3.3.1;python_version>="3.7"', - 'parameterized==0.8.1;python_version<"3.7"', - 'parameterized==0.9.0;python_version>="3.7"', + 'pytest-rerunfailures==12.0', + 'pytest-xdist==3.3.1', + 'parameterized==0.9.0', "sbvirtualdisplay==1.2.0", "behave==1.2.6", - 'soupsieve==2.3.2.post1;python_version<"3.7"', - 'soupsieve==2.4.1;python_version>="3.7"', + 'soupsieve==2.4.1', "beautifulsoup4==4.12.2", - 'pygments==2.14.0;python_version<"3.7"', - 'pygments==2.16.1;python_version>="3.7"', + 'pygments==2.16.1', 'pyreadline3==3.4.1;platform_system=="Windows"', "tabcompleter==1.2.1", "pdbp==1.4.6", - 'colorama==0.4.5;python_version<"3.7"', - 'colorama==0.4.6;python_version>="3.7"', - 'exceptiongroup==1.1.3;python_version>="3.7"', - 'future-breakpoint==2.0.0;python_version<"3.7"', + 'colorama==0.4.6', + 'exceptiongroup==1.1.3', 'importlib-metadata==4.2.0;python_version<"3.8"', - 'pyotp==2.7.0;python_version<"3.7"', - 'pyotp==2.9.0;python_version>="3.7"', - 'typing-extensions==4.1.1;python_version<"3.7"', - 'commonmark==0.9.1;python_version<"3.7"', # For old "rich" - 'markdown-it-py==3.0.0;python_version>="3.8"', # For new "rich" - 'mdurl==0.1.2;python_version>="3.7"', # For new "rich" - 'rich==12.6.0;python_version<"3.7"', - 'rich==13.5.2;python_version>="3.7"', + 'pyotp==2.9.0', + 'markdown-it-py==2.2.0;python_version<"3.8"', + 'markdown-it-py==3.0.0;python_version>="3.8"', + 'mdurl==0.1.2', + 'rich==13.5.2', ], extras_require={ # pip install -e .[allure] # Usage: pytest --alluredir=allure_results # Serve: allure serve allure_results "allure": [ - 'allure-pytest==2.9.45;python_version<"3.7"', - 'allure-pytest==2.13.2;python_version>="3.7"', - 'allure-python-commons==2.9.45;python_version<"3.7"', - 'allure-python-commons==2.13.2;python_version>="3.7"', - 'allure-behave==2.9.45;python_version<"3.7"', - 'allure-behave==2.13.2;python_version>="3.7"', + 'allure-pytest==2.13.2', + 'allure-python-commons==2.13.2', + 'allure-behave==2.13.2', ], # pip install -e .[coverage] # Usage: coverage run -m pytest; coverage html; coverage report "coverage": [ - 'coverage==6.2;python_version<"3.7"', - 'coverage==7.2.7;python_version>="3.7" and python_version<"3.8"', + 'coverage==7.2.7;python_version<"3.8"', 'coverage==7.3.0;python_version>="3.8"', - 'pytest-cov==4.0.0;python_version<"3.7"', - 'pytest-cov==4.1.0;python_version>="3.7"', + 'pytest-cov==4.1.0', ], # pip install -e .[flake8] # Usage: flake8 @@ -258,16 +222,13 @@ # (Not needed for debugging anymore. SeleniumBase now includes "pdbp".) "ipdb": [ "ipdb==0.13.13", - 'ipython==7.16.3;python_version<"3.7"', - 'ipython==7.34.0;python_version>="3.7"', + 'ipython==7.34.0', ], # pip install -e .[pdfminer] # (An optional library for parsing PDF files.) "pdfminer": [ - 'pdfminer.six==20211012;python_version<"3.7"', - 'pdfminer.six==20221105;python_version>="3.7"', - 'cryptography==36.0.2;python_version<"3.7"', - 'cryptography==39.0.2;python_version>="3.7" and python_version<"3.9"', # noqa: E501 + 'pdfminer.six==20221105', + 'cryptography==39.0.2;python_version<"3.9"', 'cryptography==41.0.3;python_version>="3.9"', "cffi==1.15.1", "pycparser==2.21", @@ -276,8 +237,7 @@ # pip install -e .[pillow] # (An optional library for image-processing.) "pillow": [ - 'Pillow==8.4.0;python_version<"3.7"', - 'Pillow==9.5.0;python_version>="3.7" and python_version<"3.8"', + 'Pillow==9.5.0;python_version<"3.8"', 'Pillow==10.0.0;python_version>="3.8"', ], # pip install -e .[psutil] @@ -286,15 +246,15 @@ ], # pip install -e .[selenium-wire] "selenium-wire": [ - 'selenium-wire==5.1.0;python_version>="3.7"', - 'Brotli==1.0.9;python_version>="3.7"', - 'blinker==1.6.2;python_version>="3.7"', - 'h2==4.1.0;python_version>="3.7"', - 'hpack==4.0.0;python_version>="3.7"', - 'hyperframe==6.0.1;python_version>="3.7"', - 'kaitaistruct==0.10;python_version>="3.7"', - 'pyasn1==0.5.0;python_version>="3.7"', - 'zstandard==0.21.0;python_version>="3.7"', + 'selenium-wire==5.1.0', + 'Brotli==1.0.9', + 'blinker==1.6.2', + 'h2==4.1.0', + 'hpack==4.0.0', + 'hyperframe==6.0.1', + 'kaitaistruct==0.10', + 'pyasn1==0.5.0', + 'zstandard==0.21.0', ], }, packages=[