From f693fd13ccc816bea7f83097de936f9bd768db38 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 1 Sep 2023 18:36:15 -0400 Subject: [PATCH] Drop support for Python 3.6 and Opera --- seleniumbase/console_scripts/ReadMe.md | 2 +- seleniumbase/console_scripts/run.py | 2 +- seleniumbase/console_scripts/sb_install.py | 129 +-- seleniumbase/core/browser_launcher.py | 1169 +++++++------------- seleniumbase/core/log_helper.py | 3 - seleniumbase/fixtures/base_case.py | 70 +- seleniumbase/fixtures/constants.py | 4 - seleniumbase/fixtures/page_utils.py | 1 - seleniumbase/plugins/driver_manager.py | 8 - seleniumbase/plugins/pytest_plugin.py | 18 - seleniumbase/plugins/sb_manager.py | 9 - seleniumbase/plugins/selenium_plugin.py | 16 - setup.py | 3 +- 13 files changed, 392 insertions(+), 1042 deletions(-) diff --git a/seleniumbase/console_scripts/ReadMe.md b/seleniumbase/console_scripts/ReadMe.md index 5b8d1f8f..8e4fccb9 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 2a22c666..373a43bc 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 339556b0..7f1e45e6 100644 --- a/seleniumbase/console_scripts/sb_install.py +++ b/seleniumbase/console_scripts/sb_install.py @@ -3,7 +3,7 @@ Downloads the specified webdriver to "seleniumbase/drivers/" 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 @@ Examples: 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 @@ LOCAL_PATH = "/usr/local/bin/" # On Mac and Linux systems 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 c8c84b99..132abeea 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -10,6 +10,7 @@ import urllib3 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 constants 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_GECKODRIVER = None 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 @@ if IS_MAC or IS_LINUX: 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 @@ elif IS_WINDOWS: 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: + 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, ) - 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: - return webdriver.Firefox( - executable_path=LOCAL_GECKODRIVER, - service_log_path=os.devnull, - options=firefox_options, - ) + else: + raise # Not an obvious fix. else: - if selenium4_or_newer: - service = FirefoxService(log_output=os.devnull) - try: + service = FirefoxService(log_output=os.devnull) + 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 + ) + ): + 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, ) - 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: - return webdriver.Firefox( - service_log_path=os.devnull, - 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: + 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: try: if not _was_driver_repaired(): _repair_edgedriver(edge_version) - _mark_driver_repaired() + _mark_driver_repaired() 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 - else: - capabilities = edge_options.to_capabilities() - capabilities["platform"] = "" - try: - driver = Edge( - executable_path=LOCAL_EDGEDRIVER, - service_log_path=os.devnull, - capabilities=capabilities, - ) - 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: - if not _was_driver_repaired(): - _repair_edgedriver(edge_version) - _mark_driver_repaired() - else: + 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 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 + if IS_LINUX: + if "--headless" in ( + chrome_options.arguments ): - 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 + chrome_options.arguments.remove( + "--headless" ) - 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 - ): - chrome_options.add_experimental_option( - "w3c", True - ) - 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 96a84bb6..854e14ba 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 2c18c8c0..1e3e13fc 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -95,9 +95,6 @@ python3_11_or_newer = False 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): "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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 @@ class BaseCase(unittest.TestCase): 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 ec990975..11220422 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 03a1e46f..29ca5254 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 48987a3a..3c27b2db 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 efb8c8fa..86f5e663 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 391a4682..d60527a7 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 bd8f252b..0b03faf8 100644 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -128,13 +128,6 @@ class SeleniumBrowser(Plugin): 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 @@ class SeleniumBrowser(Plugin): 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 @@ class SeleniumBrowser(Plugin): 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 d5165f8b..f54292f6 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 @@ setup( "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",