diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
index 489109d34f2d4..8fe31ce9249af 100644
--- a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
+++ b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
@@ -128,7 +128,7 @@ public class ChromiumDriver : WebDriver, ISupportsLogs, IDevTools
/// The to be used with the ChromiumDriver.
/// The maximum amount of time to wait for each command.
protected ChromiumDriver(ChromiumDriverService service, ChromiumOptions options, TimeSpan commandTimeout)
- : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options))
+ : base(service.CreateCommandExecutor(options, commandTimeout, searchForBrowserPath: true), ConvertOptionsToCapabilities(options))
{
this.optionsCapabilityName = options.CapabilityName;
}
@@ -141,30 +141,6 @@ protected static IReadOnlyDictionary ChromiumCustomCommands
get { return new ReadOnlyDictionary(chromiumCustomCommands); }
}
- ///
- /// Uses DriverFinder to set Service attributes if necessary when creating the command executor
- ///
- ///
- ///
- ///
- ///
- private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout)
- {
- if (service.DriverServicePath == null)
- {
- DriverFinder finder = new DriverFinder(options);
- string fullServicePath = finder.GetDriverPath();
- service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
- service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
- if (finder.HasBrowserPath())
- {
- options.BinaryLocation = finder.GetBrowserPath();
- options.BrowserVersion = null;
- }
- }
- return new DriverServiceCommandExecutor(service, commandTimeout);
- }
-
///
/// Gets or sets the responsible for detecting
/// sequences of keystrokes representing file paths and names.
diff --git a/dotnet/src/webdriver/DriverFinder.cs b/dotnet/src/webdriver/DriverFinder.cs
index 2f768af71414f..0b957779d2378 100644
--- a/dotnet/src/webdriver/DriverFinder.cs
+++ b/dotnet/src/webdriver/DriverFinder.cs
@@ -19,10 +19,13 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;
+#nullable enable
+
namespace OpenQA.Selenium
{
///
@@ -31,17 +34,18 @@ namespace OpenQA.Selenium
///
public class DriverFinder
{
- private DriverOptions options;
- private Dictionary paths = new Dictionary();
+ private readonly DriverOptions options;
+ private readonly Dictionary paths = new Dictionary();
private const string BrowserPathKey = "browser_path";
private const string DriverPathKey = "driver_path";
///
/// Initializes a new instance of the class.
///
+ /// If is .
public DriverFinder(DriverOptions options)
{
- this.options = options;
+ this.options = options ?? throw new ArgumentNullException(nameof(options));
}
///
@@ -66,11 +70,33 @@ public string GetDriverPath()
return BinaryPaths()[DriverPathKey];
}
+ ///
+ /// Gets a value indicating whether a browser path exists, as retrieved by the Selenium Manager.
+ ///
+ /// if a browser path exists; otherwise, .
public bool HasBrowserPath()
{
return !string.IsNullOrWhiteSpace(GetBrowserPath());
}
+ ///
+ /// Tries to get the browser path, as retrieved by Selenium Manager.
+ ///
+ /// If the method returns , the full browser path.
+ /// if a browser path exists; otherwise, .
+ public bool TryGetBrowserPath([NotNullWhen(true)] out string? browserPath)
+ {
+ string? path = GetBrowserPath();
+ if (!string.IsNullOrWhiteSpace(path))
+ {
+ browserPath = path;
+ return true;
+ }
+
+ browserPath = null;
+ return false;
+ }
+
///
/// Invokes Selenium Manager to get the binaries paths and validates if they exist.
///
@@ -80,29 +106,27 @@ public bool HasBrowserPath()
/// If one of the paths does not exist.
private Dictionary BinaryPaths()
{
- if (paths.ContainsKey(DriverPathKey) && !string.IsNullOrWhiteSpace(paths[DriverPathKey]))
+ if (paths.TryGetValue(DriverPathKey, out string? cachedDriverPath)
+ && !string.IsNullOrWhiteSpace(cachedDriverPath))
{
return paths;
}
+
Dictionary binaryPaths = SeleniumManager.BinaryPaths(CreateArguments());
string driverPath = binaryPaths[DriverPathKey];
string browserPath = binaryPaths[BrowserPathKey];
- if (File.Exists(driverPath))
- {
- paths.Add(DriverPathKey, driverPath);
- }
- else
+ if (!File.Exists(driverPath))
{
throw new NoSuchDriverException($"The driver path is not a valid file: {driverPath}");
}
- if (File.Exists(browserPath))
- {
- paths.Add(BrowserPathKey, browserPath);
- }
- else
+
+ if (!File.Exists(browserPath))
{
throw new NoSuchDriverException($"The browser path is not a valid file: {browserPath}");
}
+
+ paths.Add(DriverPathKey, driverPath);
+ paths.Add(BrowserPathKey, browserPath);
return paths;
}
diff --git a/dotnet/src/webdriver/DriverService.cs b/dotnet/src/webdriver/DriverService.cs
index 80f2218ba57cc..982381558ba5b 100644
--- a/dotnet/src/webdriver/DriverService.cs
+++ b/dotnet/src/webdriver/DriverService.cs
@@ -428,5 +428,29 @@ private bool WaitForServiceInitialization()
return isInitialized;
}
+
+ ///
+ /// Uses DriverFinder to set Service attributes if necessary when creating the command executor
+ ///
+ /// The to be used with the driver.
+ /// The maximum amount of time to wait for each command.
+ /// Whether to search for browser binaries.
+ /// A command executor.
+ internal DriverServiceCommandExecutor CreateCommandExecutor(DriverOptions options, TimeSpan commandTimeout, bool searchForBrowserPath)
+ {
+ if (DriverServicePath == null)
+ {
+ DriverFinder finder = new DriverFinder(options);
+ string fullServicePath = finder.GetDriverPath();
+ DriverServicePath = Path.GetDirectoryName(fullServicePath);
+ DriverServiceExecutableName = Path.GetFileName(fullServicePath);
+ if (searchForBrowserPath && finder.TryGetBrowserPath(out string browserPath))
+ {
+ options.BinaryLocation = browserPath;
+ options.BrowserVersion = null;
+ }
+ }
+ return new DriverServiceCommandExecutor(this, commandTimeout);
+ }
}
}
diff --git a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
index 123f0eb6dc545..05155891fe36c 100644
--- a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
+++ b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
@@ -188,36 +188,12 @@ public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options)
/// The to be used with the Firefox driver.
/// The maximum amount of time to wait for each command.
public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options, TimeSpan commandTimeout)
- : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options))
+ : base(service.CreateCommandExecutor(options, commandTimeout, searchForBrowserPath: true), ConvertOptionsToCapabilities(options))
{
// Add the custom commands unique to Firefox
this.AddCustomFirefoxCommands();
}
- ///
- /// Uses DriverFinder to set Service attributes if necessary when creating the command executor
- ///
- ///
- ///
- ///
- ///
- private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout)
- {
- if (service.DriverServicePath == null)
- {
- DriverFinder finder = new DriverFinder(options);
- string fullServicePath = finder.GetDriverPath();
- service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
- service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
- if (finder.HasBrowserPath())
- {
- options.BinaryLocation = finder.GetBrowserPath();
- options.BrowserVersion = null;
- }
- }
- return new DriverServiceCommandExecutor(service, commandTimeout);
- }
-
///
/// Gets a read-only dictionary of the custom WebDriver commands defined for FirefoxDriver.
/// The keys of the dictionary are the names assigned to the command; the values are the
diff --git a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs
index f129ef28e2769..94a2c281f7ce8 100644
--- a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs
+++ b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs
@@ -142,29 +142,10 @@ public InternetExplorerDriver(InternetExplorerDriverService service, InternetExp
/// The used to initialize the driver.
/// The maximum amount of time to wait for each command.
public InternetExplorerDriver(InternetExplorerDriverService service, InternetExplorerOptions options, TimeSpan commandTimeout)
- : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options))
+ : base(service.CreateCommandExecutor(options, commandTimeout, searchForBrowserPath: false), ConvertOptionsToCapabilities(options))
{
}
- ///
- /// Uses DriverFinder to set Service attributes if necessary when creating the command executor
- ///
- ///
- ///
- ///
- ///
- private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout)
- {
- if (service.DriverServicePath == null)
- {
- DriverFinder finder = new DriverFinder(options);
- string fullServicePath = finder.GetDriverPath();
- service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
- service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
- }
- return new DriverServiceCommandExecutor(service, commandTimeout);
- }
-
///
/// Gets or sets the responsible for detecting
/// sequences of keystrokes representing file paths and names.
diff --git a/dotnet/src/webdriver/Safari/SafariDriver.cs b/dotnet/src/webdriver/Safari/SafariDriver.cs
index b8d81c22ed56d..d14386068dbb9 100644
--- a/dotnet/src/webdriver/Safari/SafariDriver.cs
+++ b/dotnet/src/webdriver/Safari/SafariDriver.cs
@@ -145,32 +145,13 @@ public SafariDriver(SafariDriverService service, SafariOptions options)
/// The to be used with the Safari driver.
/// The maximum amount of time to wait for each command.
public SafariDriver(SafariDriverService service, SafariOptions options, TimeSpan commandTimeout)
- : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options))
+ : base(service.CreateCommandExecutor(options, commandTimeout, searchForBrowserPath: false), ConvertOptionsToCapabilities(options))
{
this.AddCustomSafariCommand(AttachDebuggerCommand, HttpCommandInfo.PostCommand, "/session/{sessionId}/apple/attach_debugger");
this.AddCustomSafariCommand(GetPermissionsCommand, HttpCommandInfo.GetCommand, "/session/{sessionId}/apple/permissions");
this.AddCustomSafariCommand(SetPermissionsCommand, HttpCommandInfo.PostCommand, "/session/{sessionId}/apple/permissions");
}
- ///
- /// Uses DriverFinder to set Service attributes if necessary when creating the command executor
- ///
- ///
- ///
- ///
- ///
- private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout)
- {
- if (service.DriverServicePath == null)
- {
- DriverFinder finder = new DriverFinder(options);
- string fullServicePath = finder.GetDriverPath();
- service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
- service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
- }
- return new DriverServiceCommandExecutor(service, commandTimeout);
- }
-
///
/// This opens Safari's Web Inspector.
/// If driver subsequently executes script of "debugger;"