You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The SFC licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Tuple
|
|
|
|
from selenium.common.exceptions import SeleniumManagerException
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SeleniumManager:
|
|
"""
|
|
Wrapper for getting information from the Selenium Manager binaries.
|
|
This implementation is still in beta, and may change.
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
pass
|
|
|
|
@staticmethod
|
|
def get_binary() -> Path:
|
|
"""
|
|
Determines the path of the correct Selenium Manager binary.
|
|
:Returns: The Selenium Manager executable location
|
|
"""
|
|
directory = sys.platform
|
|
if directory == "darwin":
|
|
directory = "macos"
|
|
elif directory in ("win32", "cygwin"):
|
|
directory = "windows"
|
|
|
|
file = "selenium-manager.exe" if directory == "windows" else "selenium-manager"
|
|
|
|
path = Path(__file__).parent.joinpath(directory, file)
|
|
|
|
if not path.is_file():
|
|
tracker = "https://github.com/SeleniumHQ/selenium/issues"
|
|
raise SeleniumManagerException(f"{path} is missing. Please open an issue on {tracker}")
|
|
|
|
return path
|
|
|
|
def driver_location(self, browser: str) -> str:
|
|
"""
|
|
Determines the path of the correct driver.
|
|
:Args:
|
|
- browser: which browser to get the driver path for.
|
|
:Returns: The driver path to use
|
|
"""
|
|
allowed = ("chrome", "firefox", "edge", "ie")
|
|
if browser not in allowed:
|
|
raise SeleniumManagerException(f"{browser} is not a valid browser. Choose one of: {allowed}")
|
|
|
|
if browser == 'ie':
|
|
browser = 'iexplorer'
|
|
|
|
binary, flag, browser = str(self.get_binary()), "--browser", browser
|
|
result = self.run((binary, flag, browser))
|
|
executable = result.split("\t")[-1].strip()
|
|
logger.debug(f"Using driver at: {executable}")
|
|
return executable
|
|
|
|
@staticmethod
|
|
def run(args: Tuple[str, str, str]) -> str:
|
|
"""
|
|
Executes the Selenium Manager Binary.
|
|
:Args:
|
|
- args: the components of the command being executed.
|
|
:Returns: The log string containing the driver location.
|
|
"""
|
|
command = " ".join(args)
|
|
logger.debug(f"Executing: {command}")
|
|
completed_proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
|
|
stderr = completed_proc.stderr.decode("utf-8").rstrip("\n")
|
|
if completed_proc.returncode:
|
|
raise SeleniumManagerException(f"Selenium manager failed for: {command}. {stderr}")
|
|
else:
|
|
# selenium manager exited 0 successfully, parse the executable path from stdout.
|
|
return stdout.split("\t")[-1].strip()
|