Skip to content

Commit

Permalink
[dotnet] Lazy-load Selenium manager binary location (#14639)
Browse files Browse the repository at this point in the history
* [dotnet] Lazy-load Selenium manager binary location

* PR suggestions

* Enable NRT for `SeleniumManager`

* fix last hypothetical null reference exception in selenium manager

* Do not use nullable json properties

* fix ResultResponse deserizalization

* Fix ResultResponse again

* Make ResultResponse properties required

---------

Co-authored-by: Nikolay Borisenko <[email protected]>
  • Loading branch information
RenderMichael and nvborisenko authored Oct 24, 2024
1 parent a149d9e commit c3e3bc8
Showing 1 changed file with 26 additions and 33 deletions.
59 changes: 26 additions & 33 deletions dotnet/src/webdriver/SeleniumManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using static OpenQA.Selenium.SeleniumManagerResponse;

#nullable enable

namespace OpenQA.Selenium
{
Expand All @@ -36,27 +39,25 @@ public static class SeleniumManager
{
private static readonly ILogger _logger = Log.GetLogger(typeof(SeleniumManager));

private static readonly string BinaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH");

private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNameCaseInsensitive = true, TypeInfoResolver = SeleniumManagerSerializerContext.Default };

static SeleniumManager()
private static readonly Lazy<string> _lazyBinaryFullPath = new(() =>
{

if (BinaryFullPath == null)
string? binaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH");
if (binaryFullPath == null)
{
var currentDirectory = AppContext.BaseDirectory;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "windows", "selenium-manager.exe");
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");
binaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "linux", "selenium-manager");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "macos", "selenium-manager");
binaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "macos", "selenium-manager");
}
else
{
Expand All @@ -65,11 +66,13 @@ static SeleniumManager()
}
}

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}");
}
}

return binaryFullPath;
});

/// <summary>
/// Determines the location of the browser and driver binaries.
Expand All @@ -88,7 +91,7 @@ public static Dictionary<string, string> BinaryPaths(string arguments)
argsBuilder.Append(" --debug");
}

var smCommandResult = RunCommand(BinaryFullPath, argsBuilder.ToString());
var smCommandResult = RunCommand(_lazyBinaryFullPath.Value, argsBuilder.ToString());
Dictionary<string, string> binaryPaths = new()
{
{ "browser_path", smCommandResult.BrowserPath },
Expand All @@ -112,10 +115,10 @@ public static Dictionary<string, string> BinaryPaths(string arguments)
/// <returns>
/// the standard output of the execution.
/// </returns>
private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName, string arguments)
private static ResultResponse RunCommand(string fileName, string arguments)
{
Process process = new Process();
process.StartInfo.FileName = BinaryFullPath;
process.StartInfo.FileName = _lazyBinaryFullPath.Value;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
Expand Down Expand Up @@ -183,7 +186,7 @@ private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName

try
{
jsonResponse = JsonSerializer.Deserialize<SeleniumManagerResponse>(output, _serializerOptions);
jsonResponse = JsonSerializer.Deserialize<SeleniumManagerResponse>(output, _serializerOptions)!;
}
catch (Exception ex)
{
Expand Down Expand Up @@ -222,32 +225,22 @@ private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName
}
}

internal class SeleniumManagerResponse
internal record SeleniumManagerResponse(IReadOnlyList<LogEntryResponse> Logs, ResultResponse Result)
{
public IReadOnlyList<LogEntryResponse> Logs { get; set; }

public ResultResponse Result { get; set; }
public record LogEntryResponse(string Level, string Message);

public class LogEntryResponse
{
public string Level { get; set; }

public string Message { get; set; }
}

public class ResultResponse
public record ResultResponse
{
[JsonPropertyName("driver_path")]
public string DriverPath { get; set; }
[JsonRequired]
public string DriverPath { get; init; } = null!;

[JsonPropertyName("browser_path")]
public string BrowserPath { get; set; }
[JsonRequired]
public string BrowserPath { get; init; } = null!;
}
}

[JsonSerializable(typeof(SeleniumManagerResponse))]
internal partial class SeleniumManagerSerializerContext : JsonSerializerContext
{

}
internal partial class SeleniumManagerSerializerContext : JsonSerializerContext;
}

0 comments on commit c3e3bc8

Please sign in to comment.