Path: blob/trunk/py/selenium/webdriver/common/selenium_manager.py
1864 views
# Licensed to the Software Freedom Conservancy (SFC) under one1# or more contributor license agreements. See the NOTICE file2# distributed with this work for additional information3# regarding copyright ownership. The SFC licenses this file4# to you under the Apache License, Version 2.0 (the5# "License"); you may not use this file except in compliance6# with the License. You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing,11# software distributed under the License is distributed on an12# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13# KIND, either express or implied. See the License for the14# specific language governing permissions and limitations15# under the License.16import json17import logging18import os19import platform20import subprocess21import sys22import sysconfig23from pathlib import Path24from typing import Optional2526from selenium.common import WebDriverException2728logger = logging.getLogger(__name__)293031class SeleniumManager:32"""Wrapper for getting information from the Selenium Manager binaries.3334This implementation is still in beta, and may change.35"""3637def binary_paths(self, args: list) -> dict:38"""Determines the locations of the requested assets.3940:Args:41- args: the commands to send to the selenium manager binary.42:Returns: dictionary of assets and their path43"""4445args = [str(self._get_binary())] + args46if logger.getEffectiveLevel() == logging.DEBUG:47args.append("--debug")48args.append("--language-binding")49args.append("python")50args.append("--output")51args.append("json")5253return self._run(args)5455@staticmethod56def _get_binary() -> Path:57"""Determines the path of the correct Selenium Manager binary.5859:Returns: The Selenium Manager executable location6061:Raises: WebDriverException if the platform is unsupported62"""6364compiled_path = Path(__file__).parent.joinpath("selenium-manager")65exe = sysconfig.get_config_var("EXE")66if exe is not None:67compiled_path = compiled_path.with_suffix(exe)6869path: Optional[Path] = None7071if (env_path := os.getenv("SE_MANAGER_PATH")) is not None:72logger.debug("Selenium Manager set by env SE_MANAGER_PATH to: %s", env_path)73path = Path(env_path)74elif compiled_path.exists():75path = compiled_path76else:77allowed = {78("darwin", "any"): "macos/selenium-manager",79("win32", "any"): "windows/selenium-manager.exe",80("cygwin", "any"): "windows/selenium-manager.exe",81("linux", "x86_64"): "linux/selenium-manager",82("freebsd", "x86_64"): "linux/selenium-manager",83("openbsd", "x86_64"): "linux/selenium-manager",84}8586arch = platform.machine() if sys.platform in ("linux", "freebsd", "openbsd") else "any"87if sys.platform in ["freebsd", "openbsd"]:88logger.warning("Selenium Manager binary may not be compatible with %s; verify settings", sys.platform)8990location = allowed.get((sys.platform, arch))91if location is None:92raise WebDriverException(f"Unsupported platform/architecture combination: {sys.platform}/{arch}")9394path = Path(__file__).parent.joinpath(location)9596if path is None or not path.is_file():97raise WebDriverException(f"Unable to obtain working Selenium Manager binary; {path}")9899logger.debug("Selenium Manager binary found at: %s", path)100101return path102103@staticmethod104def _run(args: list[str]) -> dict:105"""Executes the Selenium Manager Binary.106107:Args:108- args: the components of the command being executed.109:Returns: The log string containing the driver location.110"""111command = " ".join(args)112logger.debug("Executing process: %s", command)113try:114if sys.platform == "win32":115completed_proc = subprocess.run(args, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)116else:117completed_proc = subprocess.run(args, capture_output=True)118stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")119stderr = completed_proc.stderr.decode("utf-8").rstrip("\n")120output = json.loads(stdout) if stdout != "" else {"logs": [], "result": {}}121except Exception as err:122raise WebDriverException(f"Unsuccessful command executed: {command}") from err123124SeleniumManager._process_logs(output["logs"])125result = output["result"]126if completed_proc.returncode:127raise WebDriverException(128f"Unsuccessful command executed: {command}; code: {completed_proc.returncode}\n{result}\n{stderr}"129)130return result131132@staticmethod133def _process_logs(log_items: list[dict]):134for item in log_items:135if item["level"] == "WARN":136logger.warning(item["message"])137elif item["level"] in ["DEBUG", "INFO"]:138logger.debug(item["message"])139140141