diff --git a/MODULE.bazel b/MODULE.bazel index 348c66a2bf10d..1eded29c3d1a2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -17,7 +17,7 @@ bazel_dep(name = "protobuf", version = "21.7", dev_dependency = True, repo_name # Required for rules_rust to import the crates properly bazel_dep(name = "rules_cc", version = "0.0.9", dev_dependency = True) -bazel_dep(name = "rules_dotnet", version = "0.15.1") +bazel_dep(name = "rules_dotnet", version = "0.16.0") bazel_dep(name = "rules_java", version = "7.11.1") bazel_dep(name = "rules_jvm_external", version = "6.3") bazel_dep(name = "rules_nodejs", version = "6.2.0") diff --git a/dotnet/src/webdriver/BUILD.bazel b/dotnet/src/webdriver/BUILD.bazel index 1f23755fa1025..afcdd0785bae4 100644 --- a/dotnet/src/webdriver/BUILD.bazel +++ b/dotnet/src/webdriver/BUILD.bazel @@ -55,6 +55,7 @@ csharp_library( framework("nuget", "Microsoft.Bcl.AsyncInterfaces"), framework("nuget", "System.Threading.Tasks.Extensions"), framework("nuget", "System.Memory"), + framework("nuget", "System.Text.Encodings.Web"), framework("nuget", "System.Text.Json"), ], ) @@ -119,6 +120,7 @@ csharp_library( framework("nuget", "Microsoft.Bcl.AsyncInterfaces"), framework("nuget", "System.Threading.Tasks.Extensions"), framework("nuget", "System.Memory"), + framework("nuget", "System.Text.Encodings.Web"), framework("nuget", "System.Text.Json"), ], ) diff --git a/dotnet/src/webdriver/SeleniumManager.cs b/dotnet/src/webdriver/SeleniumManager.cs index 5e365ede075b6..d57b13f278180 100644 --- a/dotnet/src/webdriver/SeleniumManager.cs +++ b/dotnet/src/webdriver/SeleniumManager.cs @@ -24,7 +24,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.Json; -using System.Text.Json.Nodes; +using System.Text.Json.Serialization; namespace OpenQA.Selenium { @@ -38,6 +38,8 @@ public static class SeleniumManager private static readonly string BinaryFullPath = Environment.GetEnvironmentVariable("SE_MANAGER_PATH"); + private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNameCaseInsensitive = true, TypeInfoResolver = SeleniumManagerSerializerContext.Default }; + static SeleniumManager() { @@ -86,10 +88,12 @@ public static Dictionary BinaryPaths(string arguments) argsBuilder.Append(" --debug"); } - var output = RunCommand(BinaryFullPath, argsBuilder.ToString()); - Dictionary binaryPaths = new Dictionary(); - binaryPaths.Add("browser_path", (string)output["browser_path"]); - binaryPaths.Add("driver_path", (string)output["driver_path"]); + var smCommandResult = RunCommand(BinaryFullPath, argsBuilder.ToString()); + Dictionary binaryPaths = new() + { + { "browser_path", smCommandResult.BrowserPath }, + { "driver_path", smCommandResult.DriverPath } + }; if (_logger.IsEnabled(LogEventLevel.Trace)) { @@ -108,7 +112,7 @@ public static Dictionary BinaryPaths(string arguments) /// /// the standard output of the execution. /// - private static JsonNode RunCommand(string fileName, string arguments) + private static SeleniumManagerResponse.ResultResponse RunCommand(string fileName, string arguments) { Process process = new Process(); process.StartInfo.FileName = BinaryFullPath; @@ -174,47 +178,76 @@ private static JsonNode RunCommand(string fileName, string arguments) } string output = outputBuilder.ToString().Trim(); - JsonNode resultJsonNode; + + SeleniumManagerResponse jsonResponse; + try { - var deserializedOutput = JsonSerializer.Deserialize>(output); - resultJsonNode = deserializedOutput["result"]; + jsonResponse = JsonSerializer.Deserialize(output, _serializerOptions); } catch (Exception ex) { throw new WebDriverException($"Error deserializing Selenium Manager's response: {output}", ex); } - if (resultJsonNode["logs"] is not null) + if (jsonResponse.Logs is not null) { - var logs = resultJsonNode["logs"]; - foreach (var entry in logs.AsArray()) + foreach (var entry in jsonResponse.Logs) { - switch (entry.GetPropertyName()) + switch (entry.Level) { case "WARN": if (_logger.IsEnabled(LogEventLevel.Warn)) { - _logger.Warn(entry.GetValue()); + _logger.Warn(entry.Message); } break; case "DEBUG": if (_logger.IsEnabled(LogEventLevel.Debug)) { - _logger.Debug(entry.GetValue()); + _logger.Debug(entry.Message); } break; case "INFO": if (_logger.IsEnabled(LogEventLevel.Info)) { - _logger.Info(entry.GetValue()); + _logger.Info(entry.Message); } break; } } } - return resultJsonNode; + return jsonResponse.Result; + } + } + + internal class SeleniumManagerResponse + { + public IReadOnlyList Logs { get; set; } + + public ResultResponse Result { get; set; } + + public class LogEntryResponse + { + public string Level { get; set; } + + public string Message { get; set; } + } + + public class ResultResponse + { + [JsonPropertyName("driver_path")] + public string DriverPath { get; set; } + + [JsonPropertyName("browser_path")] + public string BrowserPath { get; set; } } } + + [JsonSerializable(typeof(SeleniumManagerResponse))] + internal partial class SeleniumManagerSerializerContext : JsonSerializerContext + { + + } }