Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dotnet] Simplify and nullable annotate DriverFinder #15232

Merged
merged 14 commits into from
Feb 28, 2025
4 changes: 2 additions & 2 deletions dotnet/src/webdriver/Chromium/ChromiumDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
string fullServicePath = finder.GetDriverPath();
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
if (finder.HasBrowserPath())
if (finder.TryGetBrowserPath(out string browserPath))
{
options.BinaryLocation = finder.GetBrowserPath();
options.BinaryLocation = browserPath;
options.BrowserVersion = null;
}
}
Expand Down
52 changes: 40 additions & 12 deletions dotnet/src/webdriver/DriverFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
/// <summary>
Expand All @@ -31,17 +34,16 @@ namespace OpenQA.Selenium
/// </summary>
public class DriverFinder
{
private DriverOptions options;
private readonly DriverOptions options;
private Dictionary<string, string> paths = new Dictionary<string, string>();
private const string BrowserPathKey = "browser_path";
private const string DriverPathKey = "driver_path";

/// <summary>
/// Initializes a new instance of the <see cref="DriverFinder"/> class.
/// </summary>
/// <exception cref="ArgumentNullException">If <paramref name="options"/> is <see langword="null"/>.</exception>
public DriverFinder(DriverOptions options)
{
this.options = options;
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

/// <summary>
Expand All @@ -52,7 +54,7 @@ public DriverFinder(DriverOptions options)
/// </returns>
public string GetBrowserPath()
{
return BinaryPaths()[BrowserPathKey];
return BinaryPaths()[SeleniumManager.BrowserPathKey];
}

/// <summary>
Expand All @@ -63,14 +65,36 @@ public string GetBrowserPath()
/// </returns>
public string GetDriverPath()
{
return BinaryPaths()[DriverPathKey];
return BinaryPaths()[SeleniumManager.DriverPathKey];
}

/// <summary>
/// Gets whether there is a browser path for the given browser on this platform.
/// </summary>
/// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
public bool HasBrowserPath()
{
return !string.IsNullOrWhiteSpace(GetBrowserPath());
}

/// <summary>
/// Tries to get the browser path, as retrieved by Selenium Manager.
/// </summary>
/// <param name="browserPath">If the method returns <see langword="true"/>, the full browser path.</param>
/// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
public bool TryGetBrowserPath([NotNullWhen(true)] out string? browserPath)
{
string? path = GetBrowserPath();
if (!string.IsNullOrWhiteSpace(path))
{
browserPath = path;
return true;
}

browserPath = null;
return false;
}

/// <summary>
/// Invokes Selenium Manager to get the binaries paths and validates if they exist.
/// </summary>
Expand All @@ -80,29 +104,33 @@ public bool HasBrowserPath()
/// <exception cref="NoSuchDriverException">If one of the paths does not exist.</exception>
private Dictionary<string, string> BinaryPaths()
{
if (paths.ContainsKey(DriverPathKey) && !string.IsNullOrWhiteSpace(paths[DriverPathKey]))
if (paths.ContainsKey(SeleniumManager.DriverPathKey) && !string.IsNullOrWhiteSpace(paths[SeleniumManager.DriverPathKey]))
{
return paths;
}

Dictionary<string, string> binaryPaths = SeleniumManager.BinaryPaths(CreateArguments());
string driverPath = binaryPaths[DriverPathKey];
string browserPath = binaryPaths[BrowserPathKey];
string driverPath = binaryPaths[SeleniumManager.DriverPathKey];
string browserPath = binaryPaths[SeleniumManager.BrowserPathKey];

if (File.Exists(driverPath))
{
paths.Add(DriverPathKey, driverPath);
paths.Add(SeleniumManager.DriverPathKey, driverPath);
}
else
{
throw new NoSuchDriverException($"The driver path is not a valid file: {driverPath}");
}

if (File.Exists(browserPath))
{
paths.Add(BrowserPathKey, browserPath);
paths.Add(SeleniumManager.BrowserPathKey, browserPath);
}
else
{
throw new NoSuchDriverException($"The browser path is not a valid file: {browserPath}");
}

return paths;
}

Expand All @@ -123,7 +151,7 @@ private string CreateArguments()
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-version {0}", options.BrowserVersion);
}

string browserBinary = options.BinaryLocation;
string? browserBinary = options.BinaryLocation;
if (!string.IsNullOrEmpty(browserBinary))
{
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-path \"{0}\"", browserBinary);
Expand Down
4 changes: 2 additions & 2 deletions dotnet/src/webdriver/Firefox/FirefoxDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,9 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
string fullServicePath = finder.GetDriverPath();
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
if (finder.HasBrowserPath())
if (finder.TryGetBrowserPath(out string browserPath))
{
options.BinaryLocation = finder.GetBrowserPath();
options.BinaryLocation = browserPath;
options.BrowserVersion = null;
}
}
Expand Down
15 changes: 9 additions & 6 deletions dotnet/src/webdriver/SeleniumManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ namespace OpenQA.Selenium
/// </summary>
public static class SeleniumManager
{
internal const string DriverPathKey = "driver_path";
internal const string BrowserPathKey = "browser_path";

private static readonly ILogger _logger = Log.GetLogger(typeof(SeleniumManager));

private static readonly Lazy<string> _lazyBinaryFullPath = new(() =>
Expand Down Expand Up @@ -93,14 +96,14 @@ public static Dictionary<string, string> BinaryPaths(string arguments)
var smCommandResult = RunCommand(_lazyBinaryFullPath.Value, argsBuilder.ToString());
Dictionary<string, string> binaryPaths = new()
{
{ "browser_path", smCommandResult.BrowserPath },
{ "driver_path", smCommandResult.DriverPath }
{ BrowserPathKey, smCommandResult.BrowserPath },
{ DriverPathKey, smCommandResult.DriverPath }
};

if (_logger.IsEnabled(LogEventLevel.Trace))
{
_logger.Trace($"Driver path: {binaryPaths["driver_path"]}");
_logger.Trace($"Browser path: {binaryPaths["browser_path"]}");
_logger.Trace($"Driver path: {binaryPaths[DriverPathKey]}");
_logger.Trace($"Browser path: {binaryPaths[BrowserPathKey]}");
}

return binaryPaths;
Expand Down Expand Up @@ -214,9 +217,9 @@ public sealed record LogEntryResponse(string Level, string Message);

public sealed record ResultResponse
(
[property: JsonPropertyName("driver_path")]
[property: JsonPropertyName(SeleniumManager.DriverPathKey)]
string DriverPath,
[property: JsonPropertyName("browser_path")]
[property: JsonPropertyName(SeleniumManager.BrowserPathKey)]
string BrowserPath
);
}
Expand Down
Loading