From 88e460866efebd4e84d180b35029dcc863267a2b Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 9 Jan 2025 20:45:08 +0700 Subject: [PATCH 1/8] [java] rawtypes javac warning fix for AbstractDriverOptions (#15048) rawtypes javac fixe for AbstractDriverOptions --- java/src/org/openqa/selenium/remote/AbstractDriverOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java b/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java index d94235ad88da6..60c97d9befdeb 100644 --- a/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java +++ b/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java @@ -40,7 +40,7 @@ import org.openqa.selenium.UnexpectedAlertBehaviour; import org.openqa.selenium.internal.Require; -public abstract class AbstractDriverOptions +public abstract class AbstractDriverOptions> extends MutableCapabilities { public DO setBrowserVersion(String browserVersion) { setCapability(BROWSER_VERSION, Require.nonNull("Browser version", browserVersion)); From 398a082bf68dff3c091c14f94f4d46930bc131fe Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Thu, 9 Jan 2025 14:44:42 +0100 Subject: [PATCH 2/8] [java] Test is now working in remote builds --- java/test/org/openqa/selenium/JavascriptEnabledDriverTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/java/test/org/openqa/selenium/JavascriptEnabledDriverTest.java b/java/test/org/openqa/selenium/JavascriptEnabledDriverTest.java index 16f732389a5c9..5c6d1b722da59 100644 --- a/java/test/org/openqa/selenium/JavascriptEnabledDriverTest.java +++ b/java/test/org/openqa/selenium/JavascriptEnabledDriverTest.java @@ -23,7 +23,6 @@ import static org.openqa.selenium.WaitingConditions.elementValueToEqual; import static org.openqa.selenium.WaitingConditions.windowToBeSwitchedToWithName; import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs; -import static org.openqa.selenium.testing.drivers.Browser.CHROME; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; import org.junit.jupiter.api.Test; @@ -31,7 +30,6 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.testing.JupiterTestBase; import org.openqa.selenium.testing.NoDriverAfterTest; -import org.openqa.selenium.testing.NotWorkingInRemoteBazelBuilds; import org.openqa.selenium.testing.NotYetImplemented; class JavascriptEnabledDriverTest extends JupiterTestBase { @@ -73,7 +71,6 @@ void testShouldWaitForLoadsToCompleteAfterJavascriptCausesANewPageToLoad() { } @Test - @NotWorkingInRemoteBazelBuilds(value = CHROME) void testShouldBeAbleToFindElementAfterJavascriptCausesANewPageToLoad() { driver.get(pages.formPage); From 85b816443b5cc05e5a7336c54161d16fc5f74d16 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Thu, 9 Jan 2025 11:32:39 -0500 Subject: [PATCH 3/8] [dotnet] Fix current version of `IgnoreTargetAttribute` in test suite (#15051) --- .../IgnoreTargetAttribute.cs | 83 ++++++++----------- 1 file changed, 34 insertions(+), 49 deletions(-) diff --git a/dotnet/test/common/CustomTestAttributes/IgnoreTargetAttribute.cs b/dotnet/test/common/CustomTestAttributes/IgnoreTargetAttribute.cs index a3b71df30d12d..152e71cc946bf 100644 --- a/dotnet/test/common/CustomTestAttributes/IgnoreTargetAttribute.cs +++ b/dotnet/test/common/CustomTestAttributes/IgnoreTargetAttribute.cs @@ -22,89 +22,74 @@ using NUnit.Framework.Internal; using OpenQA.Selenium.Environment; using System; -using System.Collections.Generic; +#nullable enable namespace OpenQA.Selenium { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] public class IgnoreTargetAttribute : NUnitAttribute, IApplyToTest { - private readonly String target; - private readonly string ignoreReason = string.Empty; - public IgnoreTargetAttribute(string target) { - this.target = target.ToLower(); + this.Value = target.ToLower(); } public IgnoreTargetAttribute(string target, string reason) : this(target) { - this.ignoreReason = reason; + this.Reason = reason; } - public string Value - { - get { return target; } - } + public string Value { get; } - public string Reason - { - get { return ignoreReason; } - } + public string Reason { get; } = string.Empty; public void ApplyToTest(Test test) { - if (test.RunState != RunState.NotRunnable) + if (test.RunState is RunState.NotRunnable) { - List ignoreAttributes = new List(); - if (test.IsSuite) - { - Attribute[] ignoreClassAttributes = - test.TypeInfo.GetCustomAttributes(true); - if (ignoreClassAttributes.Length > 0) - { - ignoreAttributes.AddRange(ignoreClassAttributes); - } - } - else + return; + } + IgnoreTargetAttribute[] ignoreAttributes; + if (test.IsSuite) + { + ignoreAttributes = test.TypeInfo!.GetCustomAttributes(true); + } + else + { + ignoreAttributes = test.Method!.GetCustomAttributes(true); + } + + foreach (IgnoreTargetAttribute platformToIgnoreAttr in ignoreAttributes) + { + if (IgnoreTestForPlatform(platformToIgnoreAttr.Value)) { - IgnoreTargetAttribute[] ignoreMethodAttributes = - test.Method.GetCustomAttributes(true); - if (ignoreMethodAttributes.Length > 0) + string ignoreReason = $"Ignoring target {EnvironmentManager.Instance.Browser}"; + if (!string.IsNullOrEmpty(platformToIgnoreAttr.Reason)) { - ignoreAttributes.AddRange(ignoreMethodAttributes); + ignoreReason = ignoreReason + ": " + platformToIgnoreAttr.Reason; } - } - foreach (Attribute attr in ignoreAttributes) - { - IgnoreTargetAttribute platformToIgnoreAttr = attr as IgnoreTargetAttribute; - if (platformToIgnoreAttr != null && IgnoreTestForPlatform(platformToIgnoreAttr.Value)) - { - string ignoreReason = - "Ignoring target " + EnvironmentManager.Instance.Browser.ToString() + "."; - if (!string.IsNullOrEmpty(platformToIgnoreAttr.Reason)) - { - ignoreReason = ignoreReason + " " + platformToIgnoreAttr.Reason; - } + test.RunState = RunState.Ignored; + test.Properties.Set(PropertyNames.SkipReason, ignoreReason); - test.RunState = RunState.Ignored; - test.Properties.Set(PropertyNames.SkipReason, platformToIgnoreAttr.Reason); - } } } } - private bool IgnoreTestForPlatform(string platformToIgnore) + private static bool IgnoreTestForPlatform(string platformToIgnore) { - return CurrentPlatform() != null && platformToIgnore.Equals(CurrentPlatform()); + return CurrentPlatform().Equals(platformToIgnore, StringComparison.OrdinalIgnoreCase); } - private string CurrentPlatform() + private static string CurrentPlatform() { - return "net6"; +#if NET8_0 + return "net8"; +#else +#error Update IgnoreTargetAttribute.CurrentPlatform to the current TFM +#endif } } } From 7d8068db1af1b92da54d20c65a7ab62f3e253a04 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Thu, 9 Jan 2025 19:37:15 +0300 Subject: [PATCH 4/8] [dotnet] Utilize dedicated WebDriver Spec endpoint to get named cookie (#14957) --- dotnet/src/webdriver/CookieJar.cs | 42 +++++-------- dotnet/src/webdriver/ICookieJar.cs | 2 +- dotnet/src/webdriver/NoSuchCookieException.cs | 63 +++++++++++++++++++ .../W3CWireProtocolCommandInfoRepository.cs | 2 +- dotnet/src/webdriver/WebDriver.cs | 3 + 5 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 dotnet/src/webdriver/NoSuchCookieException.cs diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index 8ae324fa6961f..0f2695b96a2de 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -36,27 +36,20 @@ public ReadOnlyCollection AllCookies { Response response = driver.InternalExecute(DriverCommand.GetAllCookies, new Dictionary()); - try + List toReturn = new List(); + if (response.Value is object?[] cookies) { - List toReturn = new List(); - if (response.Value is object?[] cookies) + foreach (object? rawCookie in cookies) { - foreach (object? rawCookie in cookies) + if (rawCookie != null) { - if (rawCookie != null) - { - Cookie newCookie = Cookie.FromDictionary((Dictionary)rawCookie); - toReturn.Add(newCookie); - } + Cookie newCookie = Cookie.FromDictionary((Dictionary)rawCookie); + toReturn.Add(newCookie); } } - - return new ReadOnlyCollection(toReturn); - } - catch (Exception e) - { - throw new WebDriverException("Unexpected problem getting cookies", e); } + + return new ReadOnlyCollection(toReturn); } } @@ -124,22 +117,21 @@ public void DeleteAllCookies() /// A Cookie from the name; or if not found. public Cookie? GetCookieNamed(string name) { - if (name is null) + if (string.IsNullOrWhiteSpace(name)) { - throw new ArgumentNullException(nameof(name)); + throw new ArgumentException("Cookie name cannot be empty", nameof(name)); } - - foreach (Cookie currentCookie in this.AllCookies) + try { - if (name.Equals(currentCookie.Name)) - { - return currentCookie; - } + var rawCookie = driver.InternalExecute(DriverCommand.GetCookie, new() { { "name", name } }).Value; + return Cookie.FromDictionary((Dictionary)rawCookie); + } + catch (NoSuchCookieException) + { + return null; } - - return null; } } } diff --git a/dotnet/src/webdriver/ICookieJar.cs b/dotnet/src/webdriver/ICookieJar.cs index 07594bf8f3173..f9eb69a4824bc 100644 --- a/dotnet/src/webdriver/ICookieJar.cs +++ b/dotnet/src/webdriver/ICookieJar.cs @@ -47,7 +47,7 @@ public interface ICookieJar /// The name of the cookie to retrieve. /// The containing the name. Returns /// if no cookie with the specified name is found. - /// If is . + /// If is or . Cookie? GetCookieNamed(string name); /// diff --git a/dotnet/src/webdriver/NoSuchCookieException.cs b/dotnet/src/webdriver/NoSuchCookieException.cs new file mode 100644 index 0000000000000..067a89eba6465 --- /dev/null +++ b/dotnet/src/webdriver/NoSuchCookieException.cs @@ -0,0 +1,63 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System; + +#nullable enable + +namespace OpenQA.Selenium +{ + /// + /// The exception that is thrown when a cookie is not found. + /// + [Serializable] + public class NoSuchCookieException : NotFoundException + { + /// + /// Initializes a new instance of the class. + /// + public NoSuchCookieException() + : base() + { + } + + /// + /// Initializes a new instance of the class with + /// a specified error message. + /// + /// The message that describes the error. + public NoSuchCookieException(string? message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class with + /// a specified error message and a reference to the inner exception that is the + /// cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, + /// or if no inner exception is specified. + public NoSuchCookieException(string? message, Exception? innerException) + : base(message, innerException) + { + } + } +} diff --git a/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs b/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs index d800da185613e..efac296c04c5e 100644 --- a/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs +++ b/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs @@ -104,7 +104,7 @@ protected override void InitializeCommandDictionary() this.TryAddCommand(DriverCommand.ExecuteScript, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/execute/sync")); this.TryAddCommand(DriverCommand.ExecuteAsyncScript, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/execute/async")); this.TryAddCommand(DriverCommand.GetAllCookies, new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/cookie")); - this.TryAddCommand(DriverCommand.GetCookie, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/cookie/{name}")); + this.TryAddCommand(DriverCommand.GetCookie, new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/cookie/{name}")); this.TryAddCommand(DriverCommand.AddCookie, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/cookie")); this.TryAddCommand(DriverCommand.DeleteCookie, new HttpCommandInfo(HttpCommandInfo.DeleteCommand, "/session/{sessionId}/cookie/{name}")); this.TryAddCommand(DriverCommand.DeleteAllCookies, new HttpCommandInfo(HttpCommandInfo.DeleteCommand, "/session/{sessionId}/cookie")); diff --git a/dotnet/src/webdriver/WebDriver.cs b/dotnet/src/webdriver/WebDriver.cs index 859858ba0ec53..974cbf608fcba 100644 --- a/dotnet/src/webdriver/WebDriver.cs +++ b/dotnet/src/webdriver/WebDriver.cs @@ -847,6 +847,9 @@ private static void UnpackAndThrowOnError(Response errorResponse, string command case WebDriverResult.UnsupportedOperation: throw new UnsupportedOperationException(errorMessage); + case WebDriverResult.NoSuchCookie: + throw new NoSuchCookieException(errorMessage); + default: throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "{0} ({1})", errorMessage, errorResponse.Status)); } From 8740f13ffffc3f018af0255ef7e8b53d11fcffbc Mon Sep 17 00:00:00 2001 From: Navin Chandra Date: Fri, 10 Jan 2025 14:34:51 +0530 Subject: [PATCH 5/8] [java]: allow setting custom timeout for DevTools (#14931) * allow setting custom timeout via overloaded constructor * Revert "allow setting custom timeout via overloaded constructor" This reverts commit 5dfc5f6f2128d0b7385d6a80706e4f4ce0639c4c. * increase timeout to 30s --- java/src/org/openqa/selenium/devtools/DevTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/org/openqa/selenium/devtools/DevTools.java b/java/src/org/openqa/selenium/devtools/DevTools.java index b83e68f0fd8f0..11a3207954225 100644 --- a/java/src/org/openqa/selenium/devtools/DevTools.java +++ b/java/src/org/openqa/selenium/devtools/DevTools.java @@ -42,7 +42,7 @@ public class DevTools implements Closeable { private static final Logger LOG = Logger.getLogger(DevTools.class.getName()); private final Domains protocol; - private final Duration timeout = Duration.ofSeconds(10); + private final Duration timeout = Duration.ofSeconds(30); private final Connection connection; private SessionID cdpSession = null; From c1bb977d1f1259be683e0c32892faede83b5cb07 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 10 Jan 2025 11:10:14 -0500 Subject: [PATCH 6/8] [dotnet] Tolerate invalid UTF-16 strings in DevTools JSON response (#14972) Co-authored-by: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> --- .../DevTools/Json/DevToolsJsonOptions.cs | 35 +++++++++++ .../DevTools/Json/StringConverter.cs | 61 +++++++++++++++++++ dotnet/src/webdriver/cdp/README.md | 4 +- .../src/generator/Templates/domain.hbs | 2 +- 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs create mode 100644 dotnet/src/webdriver/DevTools/Json/StringConverter.cs diff --git a/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs b/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs new file mode 100644 index 0000000000000..4b624a9f6b43e --- /dev/null +++ b/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs @@ -0,0 +1,35 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System.Text.Json; + +#nullable enable + +namespace OpenQA.Selenium.DevTools.Json; + +internal static class DevToolsJsonOptions +{ + public static JsonSerializerOptions Default { get; } = new JsonSerializerOptions() + { + Converters = + { + new StringConverter(), + } + }; +} diff --git a/dotnet/src/webdriver/DevTools/Json/StringConverter.cs b/dotnet/src/webdriver/DevTools/Json/StringConverter.cs new file mode 100644 index 0000000000000..0ba9a9627fc7f --- /dev/null +++ b/dotnet/src/webdriver/DevTools/Json/StringConverter.cs @@ -0,0 +1,61 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +#nullable enable + +namespace OpenQA.Selenium.DevTools.Json; + +internal sealed class StringConverter : JsonConverter +{ + public override bool HandleNull => true; + + public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + try + { + return reader.GetString(); + } + catch (InvalidOperationException) + { + // Fallback to read the value as bytes instead of string. + // System.Text.Json library throws exception when CDP remote end sends non-encoded string as binary data. + // Using JavaScriptEncoder.UnsafeRelaxedJsonEscaping doesn't help because the string actually is byte[]. + // https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-Request - here "postData" property + // is a string, which we cannot deserialize properly. This property is marked as deprecated, and new "postDataEntries" + // is suggested for using, where most likely it is base64 encoded. + + var bytes = reader.ValueSpan; + var sb = new StringBuilder(bytes.Length); + foreach (byte b in bytes) + { + sb.Append(Convert.ToChar(b)); + } + + return sb.ToString(); + } + } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => + writer.WriteStringValue(value); +} diff --git a/dotnet/src/webdriver/cdp/README.md b/dotnet/src/webdriver/cdp/README.md index f78d0b3d04ba4..20c23edd23a22 100644 --- a/dotnet/src/webdriver/cdp/README.md +++ b/dotnet/src/webdriver/cdp/README.md @@ -17,7 +17,7 @@ add an entry for version `` to the `SupportedDevToolsVersions` dictionary ini 6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd), add the following block (substituting the proper value for ``): -``` +```bash if not exist "%1..\..\..\bazel-bin\dotnet\src\webdriver\cdp\v\DevToolsSessionDomains.cs" ( echo Generating CDP code for version pushd "%1..\..\.." @@ -29,7 +29,7 @@ if not exist "%1..\..\..\bazel-bin\dotnet\src\webdriver\cdp\v\DevToolsSessio 7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh), add the following block (substituting the proper value for ``): -``` +```bash if [[ ! -f "$1../../../bazel-bin/dotnet/src/webdriver/cdp/v/DevToolsSessionDomains.cs" ]] then echo "Generating CDP code for version " diff --git a/third_party/dotnet/devtools/src/generator/Templates/domain.hbs b/third_party/dotnet/devtools/src/generator/Templates/domain.hbs index 1fc6271239b39..8dc01ba4fb8ea 100644 --- a/third_party/dotnet/devtools/src/generator/Templates/domain.hbs +++ b/third_party/dotnet/devtools/src/generator/Templates/domain.hbs @@ -61,7 +61,7 @@ namespace {{rootNamespace}}.{{domain.Name}} if (m_eventMap.ContainsKey(e.EventName)) { var eventData = m_eventMap[e.EventName]; - var eventArgs = e.EventData.Deserialize(eventData.EventArgsType); + var eventArgs = e.EventData.Deserialize(eventData.EventArgsType, global::OpenQA.Selenium.DevTools.Json.DevToolsJsonOptions.Default); eventData.EventInvoker(eventArgs); } } From d457c4e2178fd67a75fc376661377dbc0e8e4995 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:11:15 +0300 Subject: [PATCH 7/8] [dotnet] Fix logging issue when log context level conflicts with logger already captured level (#15057) --- .../webdriver/Internal/Logging/LogContext.cs | 33 ++++++++++++++----- .../test/common/Internal/Logging/LogTest.cs | 24 ++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/dotnet/src/webdriver/Internal/Logging/LogContext.cs b/dotnet/src/webdriver/Internal/Logging/LogContext.cs index bb4d9feede2c5..081ebbd4c5ab4 100644 --- a/dotnet/src/webdriver/Internal/Logging/LogContext.cs +++ b/dotnet/src/webdriver/Internal/Logging/LogContext.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; #nullable enable @@ -30,7 +31,7 @@ namespace OpenQA.Selenium.Internal.Logging /// Represents a logging context that provides methods for creating sub-contexts, retrieving loggers, emitting log messages, and configuring minimum log levels. /// /// - internal class LogContext : ILogContext + internal sealed class LogContext : ILogContext { private ConcurrentDictionary? _loggers; @@ -46,7 +47,7 @@ public LogContext(LogEventLevel level, ILogContext? parentLogContext, Concurrent _parentLogContext = parentLogContext; - _loggers = loggers; + _loggers = CloneLoggers(loggers, level); if (handlers is not null) { @@ -65,12 +66,7 @@ public ILogContext CreateContext() public ILogContext CreateContext(LogEventLevel minimumLevel) { - ConcurrentDictionary? loggers = null; - - if (_loggers != null) - { - loggers = new ConcurrentDictionary(_loggers.Select(l => new KeyValuePair(l.Key, new Logger(l.Value.Issuer, minimumLevel)))); - } + ConcurrentDictionary? loggers = CloneLoggers(_loggers, minimumLevel); var context = new LogContext(minimumLevel, this, loggers, Handlers); @@ -98,7 +94,7 @@ public ILogger GetLogger(Type type) public bool IsEnabled(ILogger logger, LogEventLevel level) { - return Handlers != null && level >= _level && level >= logger.Level; + return Handlers != null && level >= _level && (_loggers?.TryGetValue(logger.Issuer, out var loggerEntry) != true || level >= loggerEntry?.Level); } public void EmitMessage(ILogger logger, LogEventLevel level, string message) @@ -155,5 +151,24 @@ public void Dispose() Log.CurrentContext = _parentLogContext; } + + [return: NotNullIfNotNull(nameof(loggers))] + private static ConcurrentDictionary? CloneLoggers(ConcurrentDictionary? loggers, LogEventLevel minimumLevel) + { + if (loggers is null) + { + return null; + } + + var cloned = new Dictionary(loggers.Count); + + foreach (KeyValuePair logger in loggers) + { + var clonedLogger = new Logger(logger.Value.Issuer, minimumLevel); + cloned.Add(logger.Key, clonedLogger); + } + + return new ConcurrentDictionary(cloned); + } } } diff --git a/dotnet/test/common/Internal/Logging/LogTest.cs b/dotnet/test/common/Internal/Logging/LogTest.cs index d872f665c094a..a7d67684c2609 100644 --- a/dotnet/test/common/Internal/Logging/LogTest.cs +++ b/dotnet/test/common/Internal/Logging/LogTest.cs @@ -28,13 +28,27 @@ public class LogTest private TestLogHandler testLogHandler; private ILogger logger; + private void ResetGlobalLog() + { + Log.SetLevel(LogEventLevel.Info); + Log.Handlers.Clear().Handlers.Add(new ConsoleLogHandler()); + } + [SetUp] public void SetUp() { + ResetGlobalLog(); + testLogHandler = new TestLogHandler(); logger = Log.GetLogger(); } + [TearDown] + public void TearDown() + { + ResetGlobalLog(); + } + [Test] public void LoggerShouldEmitEvent() { @@ -160,6 +174,16 @@ public void ContextShouldChangeLevel() Assert.That(logger.Level, Is.EqualTo(LogEventLevel.Warn)); } + [Test] + public void ContextShouldEmitMessages() + { + using var context = Log.CreateContext(LogEventLevel.Trace).Handlers.Add(testLogHandler); + + logger.Trace("test message"); + + Assert.That(testLogHandler.Events.Count, Is.EqualTo(1)); + } + [Test] public void ShouldCreateContextWithCustomHandler() { From 4aee006fb3f6b437c4cd190d8aff107597fbbf8e Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 10 Jan 2025 14:00:04 -0500 Subject: [PATCH 8/8] [dotnet] Apply formatting on internal CDP generator (#15049) --- ...odeGenerationDefinitionTemplateSettings.cs | 40 +++--------- .../CodeGen/CodeGenerationSettings.cs | 50 +++------------ .../CodeGen/CodeGenerationTemplateSettings.cs | 12 +--- .../generator/CodeGen/CodeGeneratorBase.cs | 15 +---- .../generator/CodeGen/CodeGeneratorContext.cs | 12 +--- .../src/generator/CodeGen/CommandGenerator.cs | 4 +- .../src/generator/CodeGen/CommandInfo.cs | 21 ++----- .../src/generator/CodeGen/DomainGenerator.cs | 4 +- .../src/generator/CodeGen/EventGenerator.cs | 4 +- .../src/generator/CodeGen/EventInfo.cs | 14 +---- .../CodeGen/IServiceProviderExtensions.cs | 2 + .../generator/CodeGen/ProtocolGenerator.cs | 22 ++++--- .../src/generator/CodeGen/TemplatesManager.cs | 17 +++-- .../src/generator/CodeGen/TypeGenerator.cs | 10 ++- .../src/generator/CodeGen/TypeInfo.cs | 32 ++-------- .../devtools/src/generator/CodeGen/Utility.cs | 19 ++++-- .../Converters/BooleanJsonConverter.cs | 5 +- .../dotnet/devtools/src/generator/Program.cs | 2 +- .../ProtocolDefinition/CommandDefinition.cs | 26 ++------ .../ProtocolDefinition/DomainDefinition.cs | 32 ++-------- .../ProtocolDefinition/EventDefinition.cs | 8 +-- .../ProtocolDefinition/ProtocolDefinition.cs | 18 +----- .../ProtocolDefinitionItem.cs | 26 ++------ .../ProtocolVersionDefinition.cs | 44 ++++--------- .../ProtocolDefinition/TypeDefinition.cs | 62 +++++-------------- .../generator/ProtocolDefinition/Version.cs | 16 ++--- 26 files changed, 155 insertions(+), 362 deletions(-) diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationDefinitionTemplateSettings.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationDefinitionTemplateSettings.cs index 150554d8c0d3f..c1758190172f8 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationDefinitionTemplateSettings.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationDefinitionTemplateSettings.cs @@ -16,7 +16,8 @@ public CodeGenerationDefinitionTemplateSettings() OutputPath = "{{domainName}}\\{{className}}Adapter.cs", }; - CommandTemplate = new CodeGenerationTemplateSettings { + CommandTemplate = new CodeGenerationTemplateSettings + { TemplatePath = "command.hbs", OutputPath = "{{domainName}}\\{{className}}Command.cs", }; @@ -47,46 +48,21 @@ public CodeGenerationDefinitionTemplateSettings() } [JsonProperty("domainTemplate")] - public CodeGenerationTemplateSettings DomainTemplate - { - get; - set; - } + public CodeGenerationTemplateSettings DomainTemplate { get; set; } [JsonProperty("commandTemplate")] - public CodeGenerationTemplateSettings CommandTemplate - { - get; - set; - } + public CodeGenerationTemplateSettings CommandTemplate { get; set; } [JsonProperty("eventTemplate")] - public CodeGenerationTemplateSettings EventTemplate - { - get; - set; - } + public CodeGenerationTemplateSettings EventTemplate { get; set; } [JsonProperty("typeObjectTemplate")] - public CodeGenerationTemplateSettings TypeObjectTemplate - { - get; - set; - } + public CodeGenerationTemplateSettings TypeObjectTemplate { get; set; } [JsonProperty("typeHashTemplate")] - public CodeGenerationTemplateSettings TypeHashTemplate - { - get; - set; - } + public CodeGenerationTemplateSettings TypeHashTemplate { get; set; } [JsonProperty("typeEnumTemplate")] - public CodeGenerationTemplateSettings TypeEnumTemplate - { - get; - set; - } - + public CodeGenerationTemplateSettings TypeEnumTemplate { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationSettings.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationSettings.cs index c8ccff1655312..ebbf2c753107d 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationSettings.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationSettings.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.CodeGen +namespace OpenQA.Selenium.DevToolsGenerator.CodeGen { using Newtonsoft.Json; using System.Collections.Generic; @@ -27,74 +27,42 @@ public CodeGenerationSettings() /// Collection of templates that will be parsed and output in the target folder. /// [JsonProperty("include")] - public ICollection Include - { - get; - set; - } + public ICollection Include { get; set; } /// /// Indicates whether or not domains marked as depreciated will be generated. (Default: true) /// [JsonProperty("includeDeprecatedDomains")] - public bool IncludeDeprecatedDomains - { - get; - set; - } + public bool IncludeDeprecatedDomains { get; set; } /// /// Indicates whether or not domains marked as depreciated will be generated. (Default: true) /// [JsonProperty("includeExperimentalDomains")] - public bool IncludeExperimentalDomains - { - get; - set; - } + public bool IncludeExperimentalDomains { get; set; } /// /// Gets or sets the root namespace of generated classes. /// [JsonProperty("rootNamespace")] - public string RootNamespace - { - get; - set; - } + public string RootNamespace { get; set; } /// /// Gets the version number of the runtime. /// [JsonProperty("runtimeVersion")] - public string RuntimeVersion - { - get; - set; - } + public string RuntimeVersion { get; set; } [JsonProperty("definitionTemplates")] - public CodeGenerationDefinitionTemplateSettings DefinitionTemplates - { - get; - set; - } + public CodeGenerationDefinitionTemplateSettings DefinitionTemplates { get; set; } [JsonProperty("templatesPath")] - public string TemplatesPath - { - get; - set; - } + public string TemplatesPath { get; set; } /// /// The using statements that will be included on each generated file. /// [JsonProperty("usingStatements")] - public ICollection UsingStatements - { - get; - set; - } + public ICollection UsingStatements { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationTemplateSettings.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationTemplateSettings.cs index 2c020351d2dd0..4f2dbe266a585 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationTemplateSettings.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationTemplateSettings.cs @@ -8,17 +8,9 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen public class CodeGenerationTemplateSettings { [JsonProperty("templatePath")] - public string TemplatePath - { - get; - set; - } + public string TemplatePath { get; set; } [JsonProperty("outputPath")] - public string OutputPath - { - get; - set; - } + public string OutputPath { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorBase.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorBase.cs index c69d3020b0ac0..aaf2344d7f5ce 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorBase.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorBase.cs @@ -19,26 +19,17 @@ public abstract class CodeGeneratorBase : ICodeGenerator /// /// Gets the service provider associated with the generator. /// - public IServiceProvider ServiceProvider - { - get { return m_serviceProvider; } - } + public IServiceProvider ServiceProvider => m_serviceProvider; /// /// Gets the code generation settings associated with the generator. /// - public CodeGenerationSettings Settings - { - get { return m_settings.Value; } - } + public CodeGenerationSettings Settings => m_settings.Value; /// /// Gets a template manager associated with the generator. /// - public TemplatesManager TemplatesManager - { - get { return m_templatesManager.Value; } - } + public TemplatesManager TemplatesManager => m_templatesManager.Value; protected CodeGeneratorBase(IServiceProvider serviceProvider) { diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorContext.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorContext.cs index 7a7d713d4de08..6970ee7ad4f7c 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorContext.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CodeGeneratorContext.cs @@ -8,16 +8,8 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen /// public sealed class CodeGeneratorContext { - public DomainDefinition Domain - { - get; - set; - } + public DomainDefinition Domain { get; set; } - public Dictionary KnownTypes - { - get; - set; - } + public Dictionary KnownTypes { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CommandGenerator.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CommandGenerator.cs index 8e7334d5e091f..4874a604d2989 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CommandGenerator.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CommandGenerator.cs @@ -19,8 +19,10 @@ public override IDictionary GenerateCode(CommandDefinition comma { var result = new Dictionary(StringComparer.OrdinalIgnoreCase); - if (String.IsNullOrWhiteSpace(Settings.DefinitionTemplates.CommandTemplate.TemplatePath)) + if (string.IsNullOrWhiteSpace(Settings.DefinitionTemplates.CommandTemplate.TemplatePath)) + { return result; + } var commandGenerator = TemplatesManager.GetGeneratorForTemplate(Settings.DefinitionTemplates.CommandTemplate); diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/CommandInfo.cs b/third_party/dotnet/devtools/src/generator/CodeGen/CommandInfo.cs index aaaaa90d30f7b..f70dfd4601861 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/CommandInfo.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/CommandInfo.cs @@ -1,25 +1,14 @@ -namespace OpenQA.Selenium.DevToolsGenerator.CodeGen +namespace OpenQA.Selenium.DevToolsGenerator.CodeGen { /// /// Represents information about a Chrome Debugger Protocol command. /// public sealed class CommandInfo { - public string CommandName - { - get; - set; - } + public string CommandName { get; set; } - public string FullTypeName - { - get; - set; - } - public string FullResponseTypeName - { - get; - set; - } + public string FullTypeName { get; set; } + + public string FullResponseTypeName { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/DomainGenerator.cs b/third_party/dotnet/devtools/src/generator/CodeGen/DomainGenerator.cs index 5d22752532ece..3bb3761aec311 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/DomainGenerator.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/DomainGenerator.cs @@ -45,8 +45,10 @@ public override IDictionary GenerateCode(DomainDefinition domain .ForEach(x => result.Add(x.Key, x.Value)); } - if (String.IsNullOrWhiteSpace(Settings.DefinitionTemplates.DomainTemplate.TemplatePath)) + if (string.IsNullOrWhiteSpace(Settings.DefinitionTemplates.DomainTemplate.TemplatePath)) + { return result; + } var domainGenerator = TemplatesManager.GetGeneratorForTemplate(Settings.DefinitionTemplates.DomainTemplate); diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/EventGenerator.cs b/third_party/dotnet/devtools/src/generator/CodeGen/EventGenerator.cs index 3958ccf135d43..00cefd809cd32 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/EventGenerator.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/EventGenerator.cs @@ -19,8 +19,10 @@ public override IDictionary GenerateCode(EventDefinition eventDe { var result = new Dictionary(StringComparer.OrdinalIgnoreCase); - if (String.IsNullOrWhiteSpace(Settings.DefinitionTemplates.EventTemplate.TemplatePath)) + if (string.IsNullOrWhiteSpace(Settings.DefinitionTemplates.EventTemplate.TemplatePath)) + { return result; + } var eventGenerator = TemplatesManager.GetGeneratorForTemplate(Settings.DefinitionTemplates.EventTemplate); diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/EventInfo.cs b/third_party/dotnet/devtools/src/generator/CodeGen/EventInfo.cs index bdd95381d69dd..0e78b688ac880 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/EventInfo.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/EventInfo.cs @@ -1,20 +1,12 @@ -namespace OpenQA.Selenium.DevToolsGenerator.CodeGen +namespace OpenQA.Selenium.DevToolsGenerator.CodeGen { /// /// Represents information about a Chrome Debugger Protocol event. /// public sealed class EventInfo { - public string EventName - { - get; - set; - } + public string EventName { get; set; } - public string FullTypeName - { - get; - set; - } + public string FullTypeName { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/IServiceProviderExtensions.cs b/third_party/dotnet/devtools/src/generator/CodeGen/IServiceProviderExtensions.cs index 37d824be071bb..1fca894afb84b 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/IServiceProviderExtensions.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/IServiceProviderExtensions.cs @@ -19,7 +19,9 @@ public static class IServiceProviderExtensions public static IServiceCollection AddCodeGenerationServices(this IServiceCollection serviceCollection, CodeGenerationSettings settings) { if (settings == null) + { throw new ArgumentNullException(nameof(settings)); + } return serviceCollection .AddSingleton(settings) diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/ProtocolGenerator.cs b/third_party/dotnet/devtools/src/generator/CodeGen/ProtocolGenerator.cs index c58abbd468b55..676c6937578bc 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/ProtocolGenerator.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/ProtocolGenerator.cs @@ -20,7 +20,7 @@ public ProtocolGenerator(IServiceProvider serviceProvider) public override IDictionary GenerateCode(ProtocolDefinition protocolDefinition, CodeGeneratorContext context) { - if (String.IsNullOrWhiteSpace(Settings.TemplatesPath)) + if (string.IsNullOrWhiteSpace(Settings.TemplatesPath)) { Settings.TemplatesPath = Path.GetDirectoryName(Settings.TemplatesPath); } @@ -55,9 +55,9 @@ public override IDictionary GenerateCode(ProtocolDefinition prot //Get eventinfos as an array ICollection events = new List(); - foreach(var domain in domains) + foreach (var domain in domains) { - foreach(var @event in domain.Events) + foreach (var @event in domain.Events) { events.Add(new EventInfo { @@ -71,7 +71,8 @@ public override IDictionary GenerateCode(ProtocolDefinition prot var types = GetTypesInDomain(domains); //Create an object that contains information that include templates can use. - var includeData = new { + var includeData = new + { chromeVersion = protocolDefinition.BrowserVersion, runtimeVersion = Settings.RuntimeVersion, rootNamespace = Settings.RootNamespace, @@ -140,22 +141,27 @@ private Dictionary GetTypesInDomain(ICollection 0) + if (type.Enum != null && type.Enum.Count > 0) + { typeInfo = new TypeInfo { ByRef = true, IsPrimitive = false, TypeName = type.Id.Dehumanize(), }; + } else + { typeInfo = new TypeInfo { IsPrimitive = true, TypeName = "string" }; + } + break; case "array": - if ((type.Items == null || String.IsNullOrWhiteSpace(type.Items.Type)) && + if ((type.Items == null || string.IsNullOrWhiteSpace(type.Items.Type)) && type.Items.TypeReference != "StringIndex" && type.Items.TypeReference != "FilterEntry") { throw new NotImplementedException("Did not expect a top-level domain array type to specify a TypeReference"); @@ -171,8 +177,10 @@ private Dictionary GetTypesInDomain(ICollection /// Gets the code generation settings associated with the protocol generator /// - public CodeGenerationSettings Settings - { - get { return m_settings; } - } + public CodeGenerationSettings Settings => m_settings; public TemplatesManager(CodeGenerationSettings settings) { @@ -39,14 +36,20 @@ public Func GetGeneratorForTemplate(CodeGenerationTemplateSettin { var templatePath = templateSettings.TemplatePath; if (m_templateGenerators.ContainsKey(templatePath)) + { return m_templateGenerators[templatePath]; + } var targetTemplate = templatePath; if (!Path.IsPathRooted(targetTemplate)) + { targetTemplate = Path.Combine(Settings.TemplatesPath, targetTemplate); + } if (!File.Exists(targetTemplate)) + { throw new FileNotFoundException($"Unable to locate a template at {targetTemplate} - please ensure that a template file exists at this location."); + } var templateContents = File.ReadAllText(targetTemplate); @@ -81,7 +84,7 @@ public Func GetGeneratorForTemplate(CodeGenerationTemplateSettin var str = arguments[0] == null ? "" : arguments[0].ToString(); - if (String.IsNullOrWhiteSpace(str)) + if (string.IsNullOrWhiteSpace(str)) { switch (context) { @@ -100,7 +103,7 @@ public Func GetGeneratorForTemplate(CodeGenerationTemplateSettin { int.TryParse(frontPaddingObj.ToString(), out frontPadding); } - + str = Utility.ReplaceLineEndings(str, Environment.NewLine + new StringBuilder(4 * frontPadding).Insert(0, " ", frontPadding) + "/// "); writer.WriteSafeString(str); @@ -121,7 +124,9 @@ public Func GetGeneratorForTemplate(CodeGenerationTemplateSettin var codeGenContext = arguments[0] as CodeGeneratorContext; if (codeGenContext == null) + { throw new InvalidOperationException("Expected context argument to be non-null."); + } var mappedType = Utility.GetTypeMappingForType(typeDefinition, codeGenContext.Domain, codeGenContext.KnownTypes); writer.WriteSafeString(mappedType); diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/TypeGenerator.cs b/third_party/dotnet/devtools/src/generator/CodeGen/TypeGenerator.cs index d57a4ec7b925a..9ff9a467ffaa1 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/TypeGenerator.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/TypeGenerator.cs @@ -20,14 +20,20 @@ public override IDictionary GenerateCode(TypeDefinition typeDefi var result = new Dictionary(StringComparer.OrdinalIgnoreCase); if (context.KnownTypes == null) + { throw new InvalidOperationException("Expected knowntypes to be specified in context"); + } if (context.Domain == null) + { throw new InvalidOperationException("Expected domain to be specified in context"); + } var typeInfo = context.KnownTypes[$"{context.Domain.Name}.{typeDefinition.Id}"]; if (typeInfo.IsPrimitive) + { return result; + } //Base the code generation template on the specified type definition type. CodeGenerationTemplateSettings templateSettings; @@ -50,8 +56,10 @@ public override IDictionary GenerateCode(TypeDefinition typeDefi templateSettings = Settings.DefinitionTemplates.TypeHashTemplate; } - if (String.IsNullOrWhiteSpace(templateSettings.TemplatePath)) + if (string.IsNullOrWhiteSpace(templateSettings.TemplatePath)) + { return result; + } var typeGenerator = TemplatesManager.GetGeneratorForTemplate(templateSettings); diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/TypeInfo.cs b/third_party/dotnet/devtools/src/generator/CodeGen/TypeInfo.cs index 9407d6e607ef6..5b87e94c369bc 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/TypeInfo.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/TypeInfo.cs @@ -1,38 +1,18 @@ -namespace OpenQA.Selenium.DevToolsGenerator.CodeGen +namespace OpenQA.Selenium.DevToolsGenerator.CodeGen { /// /// Represents information about a Chrome Debugger Protocol type. /// public sealed class TypeInfo { - public bool ByRef - { - get; - set; - } + public bool ByRef { get; set; } - public string Namespace - { - get; - set; - } + public string Namespace { get; set; } - public bool IsPrimitive - { - get; - set; - } + public bool IsPrimitive { get; set; } - public string TypeName - { - get; - set; - } + public string TypeName { get; set; } - public string SourcePath - { - get; - set; - } + public string SourcePath { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/CodeGen/Utility.cs b/third_party/dotnet/devtools/src/generator/CodeGen/Utility.cs index 52eade64d5519..cb62f699409cb 100644 --- a/third_party/dotnet/devtools/src/generator/CodeGen/Utility.cs +++ b/third_party/dotnet/devtools/src/generator/CodeGen/Utility.cs @@ -42,8 +42,10 @@ public static string GetTypeMappingForType(TypeDefinition typeDefinition, Domain { var type = typeDefinition.Type; - if (String.IsNullOrWhiteSpace(type)) + if (string.IsNullOrWhiteSpace(type)) + { type = typeDefinition.TypeReference; + } string mappedType = null; if (type.Contains(".") && knownTypes.ContainsKey(type)) @@ -54,16 +56,22 @@ public static string GetTypeMappingForType(TypeDefinition typeDefinition, Domain var primitiveType = typeInfo.TypeName; if (typeDefinition.Optional && typeInfo.ByRef) + { primitiveType += "?"; + } if (isArray) + { primitiveType += "[]"; + } return primitiveType; } mappedType = $"{typeInfo.Namespace}.{typeInfo.TypeName}"; if (typeDefinition.Optional && typeInfo.ByRef) + { mappedType += "?"; + } } if (mappedType == null) @@ -76,7 +84,9 @@ public static string GetTypeMappingForType(TypeDefinition typeDefinition, Domain mappedType = typeInfo.TypeName; if (typeInfo.ByRef && typeDefinition.Optional) + { mappedType += "?"; + } } } @@ -113,20 +123,21 @@ public static string GetTypeMappingForType(TypeDefinition typeDefinition, Domain } if (isArray) + { mappedType += "[]"; + } return mappedType; } public static string ReplaceLineEndings(string value, string replacement = null) { - if (String.IsNullOrEmpty(value)) + if (string.IsNullOrEmpty(value)) { return value; } - if (replacement == null) - replacement = string.Empty; + replacement ??= string.Empty; return Regex.Replace(value, @"\r\n?|\n|\u2028|\u2029", replacement, RegexOptions.Compiled); } diff --git a/third_party/dotnet/devtools/src/generator/Converters/BooleanJsonConverter.cs b/third_party/dotnet/devtools/src/generator/Converters/BooleanJsonConverter.cs index 424438eecdcc8..99c2d4292a7fb 100644 --- a/third_party/dotnet/devtools/src/generator/Converters/BooleanJsonConverter.cs +++ b/third_party/dotnet/devtools/src/generator/Converters/BooleanJsonConverter.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.Converters +namespace OpenQA.Selenium.DevToolsGenerator.Converters { using Newtonsoft.Json; using System; @@ -54,7 +54,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist /// /// Specifies that this converter will not participate in writing results. /// - public override bool CanWrite { get { return false; } } + public override bool CanWrite => false; /// /// Writes the JSON representation of the object. @@ -62,6 +62,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist /// The to write to.The value.The calling serializer. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { + throw new NotSupportedException(); } } } diff --git a/third_party/dotnet/devtools/src/generator/Program.cs b/third_party/dotnet/devtools/src/generator/Program.cs index 20ddf910bc7f2..a2aded339afb1 100644 --- a/third_party/dotnet/devtools/src/generator/Program.cs +++ b/third_party/dotnet/devtools/src/generator/Program.cs @@ -88,7 +88,7 @@ static int Main(string[] args) { var targetFileHash = sha1.ComputeHash(File.ReadAllBytes(targetFilePath)); var codeFileHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(codeFile.Value)); - if (String.Compare(Convert.ToBase64String(targetFileHash), Convert.ToBase64String(codeFileHash)) != 0) + if (string.Compare(Convert.ToBase64String(targetFileHash), Convert.ToBase64String(codeFileHash)) != 0) { File.WriteAllText(targetFilePath, codeFile.Value); } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/CommandDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/CommandDefinition.cs index 4198d006976e7..9d7dec364c5ad 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/CommandDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/CommandDefinition.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition +namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition { using Newtonsoft.Json; using System.Collections.Generic; @@ -15,32 +15,16 @@ public CommandDefinition() } [JsonProperty(PropertyName = "handlers")] - public ICollection Handlers - { - get; - set; - } + public ICollection Handlers { get; set; } [JsonProperty(PropertyName = "parameters")] - public ICollection Parameters - { - get; - set; - } + public ICollection Parameters { get; set; } [JsonProperty(PropertyName = "returns")] - public ICollection Returns - { - get; - set; - } + public ICollection Returns { get; set; } [JsonProperty(PropertyName = "redirect")] - public string Redirect - { - get; - set; - } + public string Redirect { get; set; } [JsonIgnore] public bool NoParameters => Parameters == null || Parameters.Count == 0; diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/DomainDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/DomainDefinition.cs index d4cd5b7eefb81..7c461f3277676 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/DomainDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/DomainDefinition.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition +namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition { using Newtonsoft.Json; using System.Collections.Generic; @@ -16,38 +16,18 @@ public DomainDefinition() } [JsonProperty(PropertyName = "domain")] - public override string Name - { - get; - set; - } + public override string Name { get; set; } [JsonProperty(PropertyName = "types")] - public ICollection Types - { - get; - set; - } + public ICollection Types { get; set; } [JsonProperty(PropertyName = "commands")] - public ICollection Commands - { - get; - set; - } + public ICollection Commands { get; set; } [JsonProperty(PropertyName = "events")] - public ICollection Events - { - get; - set; - } + public ICollection Events { get; set; } [JsonProperty(PropertyName = "dependencies")] - public ICollection Dependencies - { - get; - set; - } + public ICollection Dependencies { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/EventDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/EventDefinition.cs index 161b356dd7908..ba0d19a661b34 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/EventDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/EventDefinition.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition +namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition { using Newtonsoft.Json; using System.Collections.Generic; @@ -12,10 +12,6 @@ public EventDefinition() } [JsonProperty(PropertyName = "parameters")] - public ICollection Parameters - { - get; - set; - } + public ICollection Parameters { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinition.cs index c00520f7d8878..487b18e45ae27 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinition.cs @@ -12,24 +12,12 @@ public ProtocolDefinition() } [JsonProperty(PropertyName = "browserVersion", Required = Required.Always)] - public ProtocolVersionDefinition BrowserVersion - { - get; - set; - } + public ProtocolVersionDefinition BrowserVersion { get; set; } [JsonProperty(PropertyName = "version", Required = Required.Always)] - public Version Version - { - get; - set; - } + public Version Version { get; set; } [JsonProperty(PropertyName = "domains", Required = Required.Always)] - public ICollection Domains - { - get; - set; - } + public ICollection Domains { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinitionItem.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinitionItem.cs index cd415d9b225a5..75bdf196f993f 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinitionItem.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolDefinitionItem.cs @@ -7,32 +7,20 @@ public abstract class ProtocolDefinitionItem : IDefinition { [JsonProperty(PropertyName = "deprecated")] - public bool Deprecated - { - get; - set; - } + public bool Deprecated { get; set; } public string Description { - get => InitialDescription != null ? InitialDescription.Replace("<", "<").Replace(">", ">") : null; + get => InitialDescription?.Replace("<", "<").Replace(">", ">"); set => InitialDescription = value; } [JsonProperty(PropertyName = "experimental")] [JsonConverter(typeof(BooleanJsonConverter))] - public bool Experimental - { - get; - set; - } + public bool Experimental { get; set; } [JsonProperty(PropertyName = "name")] - public virtual string Name - { - get; - set; - } + public virtual string Name { get; set; } public override string ToString() { @@ -40,10 +28,6 @@ public override string ToString() } [JsonProperty(PropertyName = "description")] - protected string InitialDescription - { - get; - set; - } + protected string InitialDescription { get; set; } } } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolVersionDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolVersionDefinition.cs index 2e3e706ca3284..172f9bd5f47c7 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolVersionDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/ProtocolVersionDefinition.cs @@ -12,44 +12,22 @@ namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition public class ProtocolVersionDefinition { [JsonProperty(PropertyName = "Browser")] - public string Browser - { - get; - set; - } + public string Browser { get; set; } [JsonIgnore] - public string BrowserVersion - { - get { return Regex.Match(Browser, ".*/(.*)").Groups[1].Value; } - } + public string BrowserVersion => Regex.Match(Browser, ".*/(.*)").Groups[1].Value; [JsonIgnore] - public string BrowserMajorVersion - { - get { return Regex.Match(Browser, ".*/(\\d+)\\..*").Groups[1].Value; } - } + public string BrowserMajorVersion => Regex.Match(Browser, ".*/(\\d+)\\..*").Groups[1].Value; [JsonProperty(PropertyName = "Protocol-Version")] - public string ProtocolVersion - { - get; - set; - } + public string ProtocolVersion { get; set; } [JsonProperty(PropertyName = "User-Agent")] - public string UserAgent - { - get; - set; - } + public string UserAgent { get; set; } [JsonProperty(PropertyName = "V8-Version")] - public string V8Version - { - get; - set; - } + public string V8Version { get; set; } [JsonIgnore] public string V8VersionNumber @@ -60,18 +38,16 @@ public string V8VersionNumber var v8VersionRegex = new Regex(@"^(\d+)\.(\d+)\.(\d+)(\.\d+.*)?"); var v8VersionMatch = v8VersionRegex.Match(V8Version); if (v8VersionMatch.Success == false || v8VersionMatch.Groups.Count < 4) + { throw new InvalidOperationException($"Unable to determine v8 version number from v8 version string ({V8Version})"); + } return $"{v8VersionMatch.Groups[1].Value}.{v8VersionMatch.Groups[2].Value}.{v8VersionMatch.Groups[3].Value}"; } } [JsonProperty(PropertyName = "WebKit-Version")] - public string WebKitVersion - { - get; - set; - } + public string WebKitVersion { get; set; } [JsonIgnore] public string WebKitVersionHash @@ -82,7 +58,9 @@ public string WebKitVersionHash var webkitVersionRegex = new Regex(@"\s\(@(\b[0-9a-f]{5,40}\b)"); var webkitVersionMatch = webkitVersionRegex.Match(WebKitVersion); if (webkitVersionMatch.Success == false || webkitVersionMatch.Groups.Count != 2) + { throw new InvalidOperationException($"Unable to determine webkit version hash from webkit version string ({WebKitVersion})"); + } return webkitVersionMatch.Groups[1].Value; } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/TypeDefinition.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/TypeDefinition.cs index 5bb39aded4496..0c1948b0c356c 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/TypeDefinition.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/TypeDefinition.cs @@ -15,76 +15,44 @@ public TypeDefinition() } [JsonProperty(PropertyName = "id")] - public string Id - { - get; - set; - } + public string Id { get; set; } [JsonProperty(PropertyName = "type")] - public string Type - { - get; - set; - } + public string Type { get; set; } [JsonProperty(PropertyName = "enum")] - public ICollection Enum - { - get; - set; - } + public ICollection Enum { get; set; } [JsonProperty(PropertyName = "properties")] - public ICollection Properties - { - get; - set; - } + public ICollection Properties { get; set; } [JsonProperty(PropertyName = "items")] - public TypeDefinition Items - { - get; - set; - } + public TypeDefinition Items { get; set; } [JsonProperty(PropertyName = "minItems")] - public int MinItems - { - get; - set; - } + public int MinItems { get; set; } [JsonProperty(PropertyName = "maxItems")] - public int MaxItems - { - get; - set; - } + public int MaxItems { get; set; } [JsonProperty(PropertyName = "$ref")] - public string TypeReference - { - get; - set; - } + public string TypeReference { get; set; } [JsonProperty(PropertyName = "optional")] [JsonConverter(typeof(BooleanJsonConverter))] - public bool Optional - { - get; - set; - } + public bool Optional { get; set; } public override string ToString() { - if (!String.IsNullOrWhiteSpace(Id)) + if (!string.IsNullOrWhiteSpace(Id)) + { return Id; + } - if (!String.IsNullOrWhiteSpace(Name)) + if (!string.IsNullOrWhiteSpace(Name)) + { return Name; + } return $"Ref: {TypeReference}"; } diff --git a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/Version.cs b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/Version.cs index 82f92dc636426..efbde86ee9ee2 100644 --- a/third_party/dotnet/devtools/src/generator/ProtocolDefinition/Version.cs +++ b/third_party/dotnet/devtools/src/generator/ProtocolDefinition/Version.cs @@ -1,4 +1,4 @@ -namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition +namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition { using Newtonsoft.Json; using System; @@ -9,23 +9,17 @@ public sealed class Version : IComparable { [JsonProperty(PropertyName = "major")] - public string Major - { - get; - set; - } + public string Major { get; set; } [JsonProperty(PropertyName = "minor")] - public string Minor - { - get; - set; - } + public string Minor { get; set; } public int CompareTo(Version other) { if (other == null) + { return -1; + } return ToString().CompareTo(other.ToString()); }