From e5ce6fd8c14fdb07c4ea22478ffb95eb45d64ebc Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Sun, 24 Sep 2023 18:43:47 -0500 Subject: [PATCH] Look for Selenium Manager in path defined by Environment Variable (#12752) This allows people to build or download the binary as necessary and place it in any directory --- dotnet/src/webdriver/SeleniumManager.cs | 47 ++++++++++--------- .../selenium/manager/SeleniumManager.java | 42 +++++++++-------- .../common/seleniumManager.js | 2 +- .../webdriver/common/selenium_manager.py | 21 +++++---- .../webdriver/common/selenium_manager.rb | 47 ++++++++++--------- 5 files changed, 85 insertions(+), 74 deletions(-) diff --git a/dotnet/src/webdriver/SeleniumManager.cs b/dotnet/src/webdriver/SeleniumManager.cs index e051ef025ba5b..0828ffcf314ea 100644 --- a/dotnet/src/webdriver/SeleniumManager.cs +++ b/dotnet/src/webdriver/SeleniumManager.cs @@ -34,35 +34,36 @@ namespace OpenQA.Selenium /// public static class SeleniumManager { - private readonly static string binaryFullPath; + private static readonly string BinaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH"); static SeleniumManager() { - var currentDirectory = AppContext.BaseDirectory; - string binary; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (BinaryFullPath == null) { - binary = "selenium-manager/windows/selenium-manager.exe"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - binary = "selenium-manager/linux/selenium-manager"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - binary = "selenium-manager/macos/selenium-manager"; - } - else - { - throw new WebDriverException("Selenium Manager did not find supported operating system"); + var currentDirectory = AppContext.BaseDirectory; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager\\windows\\selenium-manager.exe"); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager\\linux\\selenium-manager"); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager\\macos\\selenium-manager"); + } + else + { + throw new PlatformNotSupportedException( + $"Selenium Manager doesn't support your runtime platform: {RuntimeInformation.OSDescription}"); + } } - binaryFullPath = Path.Combine(currentDirectory, binary); - - if (!File.Exists(binaryFullPath)) + if (!File.Exists(BinaryFullPath)) { - throw new WebDriverException($"Unable to locate or obtain Selenium Manager binary at {binaryFullPath}"); + throw new WebDriverException($"Unable to locate or obtain Selenium Manager binary at {BinaryFullPath}"); } } @@ -102,7 +103,7 @@ public static string DriverPath(DriverOptions options) } } - Dictionary output = RunCommand(binaryFullPath, argsBuilder.ToString()); + Dictionary output = RunCommand(BinaryFullPath, argsBuilder.ToString()); string browserPath = (string)output["browser_path"]; string driverPath = (string)output["driver_path"]; @@ -130,7 +131,7 @@ public static string DriverPath(DriverOptions options) private static Dictionary RunCommand(string fileName, string arguments) { Process process = new Process(); - process.StartInfo.FileName = binaryFullPath; + process.StartInfo.FileName = BinaryFullPath; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; diff --git a/java/src/org/openqa/selenium/manager/SeleniumManager.java b/java/src/org/openqa/selenium/manager/SeleniumManager.java index 563cfccd76764..2c1d788624554 100644 --- a/java/src/org/openqa/selenium/manager/SeleniumManager.java +++ b/java/src/org/openqa/selenium/manager/SeleniumManager.java @@ -25,6 +25,7 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; @@ -61,11 +62,11 @@ public class SeleniumManager { private static final Logger LOG = Logger.getLogger(SeleniumManager.class.getName()); private static final String SELENIUM_MANAGER = "selenium-manager"; - private static final String EXE = ".exe"; private static volatile SeleniumManager manager; - private Path binary; + private final String managerPath = System.getenv("SE_MANAGER_PATH"); + private Path binary = managerPath == null ? null : Paths.get(managerPath); /** Wrapper for the Selenium Manager binary. */ private SeleniumManager() { @@ -158,30 +159,31 @@ private static Result runCommand(Path binary, List arguments) { */ private synchronized Path getBinary() { if (binary == null) { - try { - Platform current = Platform.getCurrent(); - String folder = "linux"; - String extension = ""; - if (current.is(WINDOWS)) { - extension = EXE; - folder = "windows"; - } else if (current.is(MAC)) { - folder = "macos"; - } - String binaryPath = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension); - try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPath)) { - Path tmpPath = Files.createTempDirectory(SELENIUM_MANAGER + System.nanoTime()); + Platform current = Platform.getCurrent(); + String folder = "linux"; + String extension = ""; + if (current.is(WINDOWS)) { + extension = ".exe"; + folder = "windows"; + } else if (current.is(MAC)) { + folder = "macos"; + } + String binaryPath = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension); + try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPath)) { + Path tmpPath = Files.createTempDirectory(SELENIUM_MANAGER + System.nanoTime()); - deleteOnExit(tmpPath); + deleteOnExit(tmpPath); - binary = tmpPath.resolve(SELENIUM_MANAGER + extension); - Files.copy(inputStream, binary, REPLACE_EXISTING); - } - binary.toFile().setExecutable(true); + binary = tmpPath.resolve(SELENIUM_MANAGER + extension); + Files.copy(inputStream, binary, REPLACE_EXISTING); } catch (Exception e) { throw new WebDriverException("Unable to obtain Selenium Manager Binary", e); } + } else if (!Files.exists(binary)) { + throw new WebDriverException(String.format("Unable to obtain Selenium Manager Binary at: %s", binary)); } + binary.toFile().setExecutable(true); + LOG.fine(String.format("Selenium Manager binary found at: %s", binary)); return binary; diff --git a/javascript/node/selenium-webdriver/common/seleniumManager.js b/javascript/node/selenium-webdriver/common/seleniumManager.js index aaf9c1ef6ae03..1c063aa06bc39 100644 --- a/javascript/node/selenium-webdriver/common/seleniumManager.js +++ b/javascript/node/selenium-webdriver/common/seleniumManager.js @@ -46,7 +46,7 @@ function getBinary() { let seleniumManagerBasePath = path.join(__dirname, '..', '/bin') - const filePath = path.join(seleniumManagerBasePath, directory, file) + const filePath = process.env.SE_MANAGER_PATH || path.join(seleniumManagerBasePath, directory, file) if (!fs.existsSync(filePath)) { throw new Error(`Unable to obtain Selenium Manager at ${filePath}`) diff --git a/py/selenium/webdriver/common/selenium_manager.py b/py/selenium/webdriver/common/selenium_manager.py index ce6a07dcc2081..72d3e46cd61cf 100644 --- a/py/selenium/webdriver/common/selenium_manager.py +++ b/py/selenium/webdriver/common/selenium_manager.py @@ -40,19 +40,22 @@ def get_binary() -> Path: :Returns: The Selenium Manager executable location """ - platform = sys.platform - dirs = { - "darwin": "macos", - "win32": "windows", - "cygwin": "windows", - } + if os.getenv("SE_MANAGER_PATH"): + path = os.getenv("SE_MANAGER_PATH") + else: + platform = sys.platform - directory = dirs.get(platform) if dirs.get(platform) else platform + dirs = { + "darwin": "macos", + "win32": "windows", + "cygwin": "windows", + } - file = "selenium-manager.exe" if directory == "windows" else "selenium-manager" + directory = dirs.get(platform) if dirs.get(platform) else platform + file = "selenium-manager.exe" if directory == "windows" else "selenium-manager" - path = Path(__file__).parent.joinpath(directory, file) + path = Path(__file__).parent.joinpath(directory, file) if not path.is_file() and os.environ["CONDA_PREFIX"]: # conda has a separate package selenium-manager, installs in bin diff --git a/rb/lib/selenium/webdriver/common/selenium_manager.rb b/rb/lib/selenium/webdriver/common/selenium_manager.rb index d779d4b17d8ab..d8c300843cd44 100644 --- a/rb/lib/selenium/webdriver/common/selenium_manager.rb +++ b/rb/lib/selenium/webdriver/common/selenium_manager.rb @@ -75,31 +75,36 @@ def generate_command(binary, options) # @return [String] the path to the correct selenium manager def binary @binary ||= begin - path = File.expand_path(bin_path, __FILE__) - path << if Platform.windows? - '/windows/selenium-manager.exe' - elsif Platform.mac? - '/macos/selenium-manager' - elsif Platform.linux? - '/linux/selenium-manager' - end - location = File.expand_path(path, __FILE__) - - begin - Platform.assert_file(location) - Platform.assert_executable(location) - rescue TypeError - raise Error::WebDriverError, - "Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object" - rescue Error::WebDriverError => e - raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}" - end - - WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager) + location = ENV.fetch('SE_MANAGER_PATH', begin + directory = File.expand_path(bin_path, __FILE__) + if Platform.windows? + "#{directory}/windows/selenium-manager.exe" + elsif Platform.mac? + "#{directory}/macos/selenium-manager" + elsif Platform.linux? + "#{directory}/linux/selenium-manager" + end + end) + + validate_location(location) location end end + def validate_location(location) + begin + Platform.assert_file(location) + Platform.assert_executable(location) + rescue TypeError + raise Error::WebDriverError, + "Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object" + rescue Error::WebDriverError => e + raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}" + end + + WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager) + end + def run(*command) command += %w[--output json] command << '--debug' if WebDriver.logger.debug?