Skip to content

Commit c3e3bc8

Browse files
[dotnet] Lazy-load Selenium manager binary location (#14639)
* [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]>
1 parent a149d9e commit c3e3bc8

File tree

1 file changed

+26
-33
lines changed

1 file changed

+26
-33
lines changed

dotnet/src/webdriver/SeleniumManager.cs

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
using System.Text;
2626
using System.Text.Json;
2727
using System.Text.Json.Serialization;
28+
using static OpenQA.Selenium.SeleniumManagerResponse;
29+
30+
#nullable enable
2831

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

39-
private static readonly string BinaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH");
40-
4142
private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNameCaseInsensitive = true, TypeInfoResolver = SeleniumManagerSerializerContext.Default };
4243

43-
static SeleniumManager()
44+
private static readonly Lazy<string> _lazyBinaryFullPath = new(() =>
4445
{
45-
46-
if (BinaryFullPath == null)
46+
string? binaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH");
47+
if (binaryFullPath == null)
4748
{
4849
var currentDirectory = AppContext.BaseDirectory;
4950
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
5051
{
51-
BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "windows", "selenium-manager.exe");
52+
binaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "windows", "selenium-manager.exe");
5253
}
5354
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
5455
{
55-
BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "linux", "selenium-manager");
56+
binaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "linux", "selenium-manager");
5657
}
5758
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
5859
{
59-
BinaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "macos", "selenium-manager");
60+
binaryFullPath = Path.Combine(currentDirectory, "selenium-manager", "macos", "selenium-manager");
6061
}
6162
else
6263
{
@@ -65,11 +66,13 @@ static SeleniumManager()
6566
}
6667
}
6768

68-
if (!File.Exists(BinaryFullPath))
69+
if (!File.Exists(binaryFullPath))
6970
{
70-
throw new WebDriverException($"Unable to locate or obtain Selenium Manager binary at {BinaryFullPath}");
71+
throw new WebDriverException($"Unable to locate or obtain Selenium Manager binary at {binaryFullPath}");
7172
}
72-
}
73+
74+
return binaryFullPath;
75+
});
7376

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

91-
var smCommandResult = RunCommand(BinaryFullPath, argsBuilder.ToString());
94+
var smCommandResult = RunCommand(_lazyBinaryFullPath.Value, argsBuilder.ToString());
9295
Dictionary<string, string> binaryPaths = new()
9396
{
9497
{ "browser_path", smCommandResult.BrowserPath },
@@ -112,10 +115,10 @@ public static Dictionary<string, string> BinaryPaths(string arguments)
112115
/// <returns>
113116
/// the standard output of the execution.
114117
/// </returns>
115-
private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName, string arguments)
118+
private static ResultResponse RunCommand(string fileName, string arguments)
116119
{
117120
Process process = new Process();
118-
process.StartInfo.FileName = BinaryFullPath;
121+
process.StartInfo.FileName = _lazyBinaryFullPath.Value;
119122
process.StartInfo.Arguments = arguments;
120123
process.StartInfo.UseShellExecute = false;
121124
process.StartInfo.CreateNoWindow = true;
@@ -183,7 +186,7 @@ private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName
183186

184187
try
185188
{
186-
jsonResponse = JsonSerializer.Deserialize<SeleniumManagerResponse>(output, _serializerOptions);
189+
jsonResponse = JsonSerializer.Deserialize<SeleniumManagerResponse>(output, _serializerOptions)!;
187190
}
188191
catch (Exception ex)
189192
{
@@ -222,32 +225,22 @@ private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName
222225
}
223226
}
224227

225-
internal class SeleniumManagerResponse
228+
internal record SeleniumManagerResponse(IReadOnlyList<LogEntryResponse> Logs, ResultResponse Result)
226229
{
227-
public IReadOnlyList<LogEntryResponse> Logs { get; set; }
228-
229-
public ResultResponse Result { get; set; }
230+
public record LogEntryResponse(string Level, string Message);
230231

231-
public class LogEntryResponse
232-
{
233-
public string Level { get; set; }
234-
235-
public string Message { get; set; }
236-
}
237-
238-
public class ResultResponse
232+
public record ResultResponse
239233
{
240234
[JsonPropertyName("driver_path")]
241-
public string DriverPath { get; set; }
235+
[JsonRequired]
236+
public string DriverPath { get; init; } = null!;
242237

243238
[JsonPropertyName("browser_path")]
244-
public string BrowserPath { get; set; }
239+
[JsonRequired]
240+
public string BrowserPath { get; init; } = null!;
245241
}
246242
}
247243

248244
[JsonSerializable(typeof(SeleniumManagerResponse))]
249-
internal partial class SeleniumManagerSerializerContext : JsonSerializerContext
250-
{
251-
252-
}
245+
internal partial class SeleniumManagerSerializerContext : JsonSerializerContext;
253246
}

0 commit comments

Comments
 (0)