From 86943a3e83a4e209b7c0806bdab5963227f5b7ba Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 6 Dec 2025 22:40:46 -0500 Subject: [PATCH 1/5] [dotnet] Add C# 14 extension to polyfill `ArgumentNullException.ThrowIfNull` --- .../Permissions/PermissionsBiDiExtensions.cs | 5 +-- .../webdriver/BiDi/WebDriver.Extensions.cs | 2 +- .../src/webdriver/Chromium/ChromiumDriver.cs | 10 +---- dotnet/src/webdriver/Cookie.cs | 5 +-- dotnet/src/webdriver/CookieJar.cs | 10 +---- .../DevTools/CommandResponseTypeMap.cs | 10 +---- .../webdriver/DevTools/WebSocketConnection.cs | 10 +---- .../webdriver/DevTools/v141/V141Network.cs | 35 ++++------------- .../webdriver/DevTools/v142/V142Network.cs | 35 ++++------------- .../webdriver/DevTools/v143/V143Network.cs | 35 ++++------------- dotnet/src/webdriver/DriverOptions.cs | 5 +-- .../DriverProcessStartedEventArgs.cs | 5 +-- dotnet/src/webdriver/Firefox/FirefoxDriver.cs | 10 +---- .../src/webdriver/Firefox/FirefoxProfile.cs | 5 +-- dotnet/src/webdriver/Firefox/Preferences.cs | 20 ++-------- .../webdriver/IE/InternetExplorerDriver.cs | 10 +---- dotnet/src/webdriver/Interactions/Actions.cs | 5 +-- .../Interactions/WheelInputDevice.cs | 5 +-- .../webdriver/Internal/Logging/LogContext.cs | 5 +-- .../ArgumentNullExceptionExtensions.cs | 38 +++++++++++++++++++ .../CallerArgumentExpressionAttribute.cs | 29 ++++++++++++++ dotnet/src/webdriver/JavaScriptEngine.cs | 35 ++++------------- dotnet/src/webdriver/Logs.cs | 5 +-- .../webdriver/Remote/HttpCommandExecutor.cs | 10 +---- .../src/webdriver/Remote/RemoteWebDriver.cs | 5 +-- dotnet/src/webdriver/Safari/SafariDriver.cs | 10 +---- dotnet/src/webdriver/TargetLocator.cs | 5 +-- dotnet/src/webdriver/WebDriver.cs | 35 ++++------------- 28 files changed, 134 insertions(+), 265 deletions(-) create mode 100644 dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs create mode 100644 dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs index 792d10162936c..4668735c4add7 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs @@ -26,10 +26,7 @@ public static class PermissionsBiDiExtensions { public static PermissionsModule AsPermissions(this BiDi bidi) { - if (bidi is null) - { - throw new ArgumentNullException(nameof(bidi)); - } + ArgumentNullException.ThrowIfNull(bidi); return bidi.AsModule(); } diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 2aedc80a2c092..3a53b2cfc5690 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -26,7 +26,7 @@ public static class WebDriverExtensions { public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOptions? options = null) { - if (webDriver is null) throw new ArgumentNullException(nameof(webDriver)); + ArgumentNullException.ThrowIfNull(webDriver); string? webSocketUrl = null; diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs index ac9b73c04d899..32531af0a6f2c 100644 --- a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs +++ b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs @@ -150,15 +150,9 @@ protected ChromiumDriver(ChromiumDriverService service, ChromiumOptions options, /// private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { - if (service is null) - { - throw new ArgumentNullException(nameof(service)); - } + ArgumentNullException.ThrowIfNull(service); - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); if (service.DriverServicePath == null) { diff --git a/dotnet/src/webdriver/Cookie.cs b/dotnet/src/webdriver/Cookie.cs index 292757bf7652f..8ee0f581820b1 100644 --- a/dotnet/src/webdriver/Cookie.cs +++ b/dotnet/src/webdriver/Cookie.cs @@ -255,10 +255,7 @@ internal long? ExpirySeconds /// A object with the proper parameters set. public static Cookie FromDictionary(Dictionary rawCookie) { - if (rawCookie == null) - { - throw new ArgumentNullException(nameof(rawCookie)); - } + ArgumentNullException.ThrowIfNull(rawCookie); string name = rawCookie["name"]!.ToString()!; string value = string.Empty; diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index 39e405559964e..2c666b3dface0 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -58,10 +58,7 @@ public ReadOnlyCollection AllCookies /// If is . public void AddCookie(Cookie cookie) { - if (cookie is null) - { - throw new ArgumentNullException(nameof(cookie)); - } + ArgumentNullException.ThrowIfNull(cookie); Dictionary parameters = new Dictionary(); parameters.Add("cookie", cookie); @@ -92,10 +89,7 @@ public void DeleteCookieNamed(string name) /// If is . public void DeleteCookie(Cookie cookie) { - if (cookie is null) - { - throw new ArgumentNullException(nameof(cookie)); - } + ArgumentNullException.ThrowIfNull(cookie); this.DeleteCookieNamed(cookie.Name); } diff --git a/dotnet/src/webdriver/DevTools/CommandResponseTypeMap.cs b/dotnet/src/webdriver/DevTools/CommandResponseTypeMap.cs index bd8f56a11cdcc..79c190dc058cd 100644 --- a/dotnet/src/webdriver/DevTools/CommandResponseTypeMap.cs +++ b/dotnet/src/webdriver/DevTools/CommandResponseTypeMap.cs @@ -38,15 +38,9 @@ public class CommandResponseTypeMap /// If or are . public void AddCommandResponseType(Type commandSettingsType, Type commandResponseType) { - if (commandSettingsType is null) - { - throw new ArgumentNullException(nameof(commandSettingsType)); - } + ArgumentNullException.ThrowIfNull(commandSettingsType); - if (commandResponseType is null) - { - throw new ArgumentNullException(nameof(commandResponseType)); - } + ArgumentNullException.ThrowIfNull(commandResponseType); if (!commandResponseTypeDictionary.ContainsKey(commandSettingsType)) { diff --git a/dotnet/src/webdriver/DevTools/WebSocketConnection.cs b/dotnet/src/webdriver/DevTools/WebSocketConnection.cs index 811312fd5f346..549fb14093883 100644 --- a/dotnet/src/webdriver/DevTools/WebSocketConnection.cs +++ b/dotnet/src/webdriver/DevTools/WebSocketConnection.cs @@ -94,10 +94,7 @@ public WebSocketConnection(TimeSpan startupTimeout, TimeSpan shutdownTimeout) /// Thrown when the connection is not established within the startup timeout. public virtual async Task Start(string url) { - if (url is null) - { - throw new ArgumentNullException(nameof(url)); - } + ArgumentNullException.ThrowIfNull(url); this.Log($"Opening connection to URL {url}", DevToolsSessionLogLevel.Trace); bool connected = false; @@ -162,10 +159,7 @@ public virtual async Task Stop() /// The task object representing the asynchronous operation. public virtual async Task SendData(string data) { - if (data is null) - { - throw new ArgumentNullException(nameof(data)); - } + ArgumentNullException.ThrowIfNull(data); ArraySegment messageBuffer = new ArraySegment(Encoding.UTF8.GetBytes(data)); this.Log($"SEND >>> {data}"); diff --git a/dotnet/src/webdriver/DevTools/v141/V141Network.cs b/dotnet/src/webdriver/DevTools/v141/V141Network.cs index e1bf79812f7c4..3c7925bf0a51b 100644 --- a/dotnet/src/webdriver/DevTools/v141/V141Network.cs +++ b/dotnet/src/webdriver/DevTools/v141/V141Network.cs @@ -118,10 +118,7 @@ public override async Task DisableFetch() /// If is null. public override async Task SetUserAgentOverride(UserAgent userAgent) { - if (userAgent is null) - { - throw new ArgumentNullException(nameof(userAgent)); - } + ArgumentNullException.ThrowIfNull(userAgent); await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() { @@ -139,10 +136,7 @@ await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() /// If is . public override async Task ContinueRequest(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); var commandSettings = new ContinueRequestCommandSettings() { @@ -179,15 +173,9 @@ public override async Task ContinueRequest(HttpRequestData requestData) /// If or are . public override async Task ContinueRequestWithResponse(HttpRequestData requestData, HttpResponseData responseData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); var commandSettings = new FulfillRequestCommandSettings() { @@ -227,10 +215,7 @@ public override async Task ContinueRequestWithResponse(HttpRequestData requestDa /// If is . public override async Task ContinueRequestWithoutModification(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); await fetch.ContinueRequest(new ContinueRequestCommandSettings() { RequestId = requestData.RequestId }).ConfigureAwait(false); } @@ -281,10 +266,7 @@ await fetch.ContinueWithAuth(new ContinueWithAuthCommandSettings() /// If is . public override async Task AddResponseBody(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); // If the response is a redirect, retrieving the body will throw an error in CDP. if (responseData.StatusCode < 300 || responseData.StatusCode > 399) @@ -312,10 +294,7 @@ public override async Task AddResponseBody(HttpResponseData responseData) /// If is . public override async Task ContinueResponseWithoutModification(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); await fetch.ContinueResponse(new ContinueResponseCommandSettings() { RequestId = responseData.RequestId }).ConfigureAwait(false); } diff --git a/dotnet/src/webdriver/DevTools/v142/V142Network.cs b/dotnet/src/webdriver/DevTools/v142/V142Network.cs index 0ce59dcda7c5b..45d1bcf66a361 100644 --- a/dotnet/src/webdriver/DevTools/v142/V142Network.cs +++ b/dotnet/src/webdriver/DevTools/v142/V142Network.cs @@ -118,10 +118,7 @@ public override async Task DisableFetch() /// If is null. public override async Task SetUserAgentOverride(UserAgent userAgent) { - if (userAgent is null) - { - throw new ArgumentNullException(nameof(userAgent)); - } + ArgumentNullException.ThrowIfNull(userAgent); await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() { @@ -139,10 +136,7 @@ await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() /// If is . public override async Task ContinueRequest(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); var commandSettings = new ContinueRequestCommandSettings() { @@ -179,15 +173,9 @@ public override async Task ContinueRequest(HttpRequestData requestData) /// If or are . public override async Task ContinueRequestWithResponse(HttpRequestData requestData, HttpResponseData responseData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); var commandSettings = new FulfillRequestCommandSettings() { @@ -227,10 +215,7 @@ public override async Task ContinueRequestWithResponse(HttpRequestData requestDa /// If is . public override async Task ContinueRequestWithoutModification(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); await fetch.ContinueRequest(new ContinueRequestCommandSettings() { RequestId = requestData.RequestId }).ConfigureAwait(false); } @@ -281,10 +266,7 @@ await fetch.ContinueWithAuth(new ContinueWithAuthCommandSettings() /// If is . public override async Task AddResponseBody(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); // If the response is a redirect, retrieving the body will throw an error in CDP. if (responseData.StatusCode < 300 || responseData.StatusCode > 399) @@ -312,10 +294,7 @@ public override async Task AddResponseBody(HttpResponseData responseData) /// If is . public override async Task ContinueResponseWithoutModification(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); await fetch.ContinueResponse(new ContinueResponseCommandSettings() { RequestId = responseData.RequestId }).ConfigureAwait(false); } diff --git a/dotnet/src/webdriver/DevTools/v143/V143Network.cs b/dotnet/src/webdriver/DevTools/v143/V143Network.cs index c2074770af733..832ede3f463fc 100644 --- a/dotnet/src/webdriver/DevTools/v143/V143Network.cs +++ b/dotnet/src/webdriver/DevTools/v143/V143Network.cs @@ -118,10 +118,7 @@ public override async Task DisableFetch() /// If is null. public override async Task SetUserAgentOverride(UserAgent userAgent) { - if (userAgent is null) - { - throw new ArgumentNullException(nameof(userAgent)); - } + ArgumentNullException.ThrowIfNull(userAgent); await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() { @@ -139,10 +136,7 @@ await network.SetUserAgentOverride(new SetUserAgentOverrideCommandSettings() /// If is . public override async Task ContinueRequest(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); var commandSettings = new ContinueRequestCommandSettings() { @@ -179,15 +173,9 @@ public override async Task ContinueRequest(HttpRequestData requestData) /// If or are . public override async Task ContinueRequestWithResponse(HttpRequestData requestData, HttpResponseData responseData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); var commandSettings = new FulfillRequestCommandSettings() { @@ -227,10 +215,7 @@ public override async Task ContinueRequestWithResponse(HttpRequestData requestDa /// If is . public override async Task ContinueRequestWithoutModification(HttpRequestData requestData) { - if (requestData is null) - { - throw new ArgumentNullException(nameof(requestData)); - } + ArgumentNullException.ThrowIfNull(requestData); await fetch.ContinueRequest(new ContinueRequestCommandSettings() { RequestId = requestData.RequestId }).ConfigureAwait(false); } @@ -281,10 +266,7 @@ await fetch.ContinueWithAuth(new ContinueWithAuthCommandSettings() /// If is . public override async Task AddResponseBody(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); // If the response is a redirect, retrieving the body will throw an error in CDP. if (responseData.StatusCode < 300 || responseData.StatusCode > 399) @@ -312,10 +294,7 @@ public override async Task AddResponseBody(HttpResponseData responseData) /// If is . public override async Task ContinueResponseWithoutModification(HttpResponseData responseData) { - if (responseData is null) - { - throw new ArgumentNullException(nameof(responseData)); - } + ArgumentNullException.ThrowIfNull(responseData); await fetch.ContinueResponse(new ContinueResponseCommandSettings() { RequestId = responseData.RequestId }).ConfigureAwait(false); } diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs index 483ceb03130a4..9fa185cc5946e 100644 --- a/dotnet/src/webdriver/DriverOptions.cs +++ b/dotnet/src/webdriver/DriverOptions.cs @@ -269,10 +269,7 @@ public virtual void AddAdditionalOption(string optionName, object optionValue) /// If is . public virtual DriverOptionsMergeResult GetMergeResult(DriverOptions other) { - if (other is null) - { - throw new ArgumentNullException(nameof(other)); - } + ArgumentNullException.ThrowIfNull(other); DriverOptionsMergeResult result = new DriverOptionsMergeResult(); if (this.BrowserName != null && other.BrowserName != null) diff --git a/dotnet/src/webdriver/DriverProcessStartedEventArgs.cs b/dotnet/src/webdriver/DriverProcessStartedEventArgs.cs index 0f48e2704302e..829dad27b8a43 100644 --- a/dotnet/src/webdriver/DriverProcessStartedEventArgs.cs +++ b/dotnet/src/webdriver/DriverProcessStartedEventArgs.cs @@ -34,10 +34,7 @@ public class DriverProcessStartedEventArgs : EventArgs /// If is . public DriverProcessStartedEventArgs(Process driverProcess) { - if (driverProcess is null) - { - throw new ArgumentNullException(nameof(driverProcess)); - } + ArgumentNullException.ThrowIfNull(driverProcess); this.ProcessId = driverProcess.Id; } diff --git a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs index 7bef00b3f3a53..f4fef3525f4bf 100644 --- a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs +++ b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs @@ -203,15 +203,9 @@ public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options, TimeS /// If is . private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); - if (service is null) - { - throw new ArgumentNullException(nameof(service)); - } + ArgumentNullException.ThrowIfNull(service); if (service.DriverServicePath == null) { diff --git a/dotnet/src/webdriver/Firefox/FirefoxProfile.cs b/dotnet/src/webdriver/Firefox/FirefoxProfile.cs index 7284973d066d2..588fa654bb898 100644 --- a/dotnet/src/webdriver/Firefox/FirefoxProfile.cs +++ b/dotnet/src/webdriver/Firefox/FirefoxProfile.cs @@ -108,10 +108,7 @@ public static FirefoxProfile FromBase64String(string base64) /// If is . public void AddExtension(string extensionToInstall) { - if (extensionToInstall is null) - { - throw new ArgumentNullException(nameof(extensionToInstall)); - } + ArgumentNullException.ThrowIfNull(extensionToInstall); this.extensions.Add(Path.GetFileNameWithoutExtension(extensionToInstall), new FirefoxExtension(extensionToInstall)); } diff --git a/dotnet/src/webdriver/Firefox/Preferences.cs b/dotnet/src/webdriver/Firefox/Preferences.cs index f02f61f9134f2..db734ff68ff3a 100644 --- a/dotnet/src/webdriver/Firefox/Preferences.cs +++ b/dotnet/src/webdriver/Firefox/Preferences.cs @@ -69,15 +69,9 @@ public Preferences(JsonElement defaultImmutablePreferences, JsonElement defaultP /// internal void SetPreference(string key, string value) { - if (key is null) - { - throw new ArgumentNullException(nameof(key)); - } + ArgumentNullException.ThrowIfNull(key); - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } + ArgumentNullException.ThrowIfNull(value); if (IsWrappedAsString(value)) { @@ -99,10 +93,7 @@ internal void SetPreference(string key, string value) /// If the specified preference is immutable. internal void SetPreference(string key, int value) { - if (key is null) - { - throw new ArgumentNullException(nameof(key)); - } + ArgumentNullException.ThrowIfNull(key); this.ThrowIfPreferenceIsImmutable(key, value); this.preferences[key] = value.ToString(CultureInfo.InvariantCulture); @@ -119,10 +110,7 @@ internal void SetPreference(string key, int value) /// If the specified preference is immutable. internal void SetPreference(string key, bool value) { - if (key is null) - { - throw new ArgumentNullException(nameof(key)); - } + ArgumentNullException.ThrowIfNull(key); this.ThrowIfPreferenceIsImmutable(key, value); this.preferences[key] = value ? "true" : "false"; diff --git a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs index 8ead0709b7db9..88ce8b29312bc 100644 --- a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs +++ b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs @@ -161,15 +161,9 @@ public InternetExplorerDriver(InternetExplorerDriverService service, InternetExp /// private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { - if (service is null) - { - throw new ArgumentNullException(nameof(service)); - } + ArgumentNullException.ThrowIfNull(service); - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); if (service.DriverServicePath == null) { diff --git a/dotnet/src/webdriver/Interactions/Actions.cs b/dotnet/src/webdriver/Interactions/Actions.cs index 1018a8be10c73..7b0856d970684 100644 --- a/dotnet/src/webdriver/Interactions/Actions.cs +++ b/dotnet/src/webdriver/Interactions/Actions.cs @@ -555,10 +555,7 @@ public Actions ScrollByAmount(int deltaX, int deltaY) /// If both or either of Viewport and Element are set. public Actions ScrollFromOrigin(WheelInputDevice.ScrollOrigin scrollOrigin, int deltaX, int deltaY) { - if (scrollOrigin is null) - { - throw new ArgumentNullException(nameof(scrollOrigin)); - } + ArgumentNullException.ThrowIfNull(scrollOrigin); if (scrollOrigin.Viewport && scrollOrigin.Element != null) { diff --git a/dotnet/src/webdriver/Interactions/WheelInputDevice.cs b/dotnet/src/webdriver/Interactions/WheelInputDevice.cs index daa7ea285ee2a..6ff0d3a5694e2 100644 --- a/dotnet/src/webdriver/Interactions/WheelInputDevice.cs +++ b/dotnet/src/webdriver/Interactions/WheelInputDevice.cs @@ -90,10 +90,7 @@ public Interaction CreateWheelScroll(int deltaX, int deltaY, TimeSpan duration) /// If is . public Interaction CreateWheelScroll(IWebElement target, int xOffset, int yOffset, int deltaX, int deltaY, TimeSpan duration) { - if (target is null) - { - throw new ArgumentNullException(nameof(target)); - } + ArgumentNullException.ThrowIfNull(target); return new WheelScrollInteraction(this, target, CoordinateOrigin.Element, xOffset, yOffset, deltaX, deltaY, duration); } diff --git a/dotnet/src/webdriver/Internal/Logging/LogContext.cs b/dotnet/src/webdriver/Internal/Logging/LogContext.cs index 5bb8ed5359e98..01ec992f8a907 100644 --- a/dotnet/src/webdriver/Internal/Logging/LogContext.cs +++ b/dotnet/src/webdriver/Internal/Logging/LogContext.cs @@ -80,10 +80,7 @@ public ILogger GetLogger() public ILogger GetLogger(Type type) { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } + ArgumentNullException.ThrowIfNull(type); _loggers ??= new ConcurrentDictionary(); diff --git a/dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs b/dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs new file mode 100644 index 0000000000000..830458e1c726e --- /dev/null +++ b/dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs @@ -0,0 +1,38 @@ +// +// 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.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System; + +internal static class ArgumentNullExceptionExtensions +{ + extension(ArgumentNullException) + { + public static void ThrowIfNull([NotNull] object? arg, [CallerArgumentExpression(nameof(arg))] string paramName = "") + { + if (arg is null) + { + throw new ArgumentNullException(paramName); + } + } + } +} + diff --git a/dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs b/dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs new file mode 100644 index 0000000000000..0fda050aa38a5 --- /dev/null +++ b/dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs @@ -0,0 +1,29 @@ +// +// 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. +// + +namespace System.Runtime.CompilerServices; + +#if !NET8_0_OR_GREATER + +internal class CallerArgumentExpressionAttribute(string paramName) : Attribute +{ + public string ParamName = paramName; +} + +#endif diff --git a/dotnet/src/webdriver/JavaScriptEngine.cs b/dotnet/src/webdriver/JavaScriptEngine.cs index 86f20c64c6f2c..06929d42a3766 100644 --- a/dotnet/src/webdriver/JavaScriptEngine.cs +++ b/dotnet/src/webdriver/JavaScriptEngine.cs @@ -166,15 +166,9 @@ public async Task DisableDomMutationMonitoring() /// If or are . public async Task AddInitializationScript(string scriptName, [StringSyntax(StringSyntaxConstants.JavaScript)] string script) { - if (scriptName is null) - { - throw new ArgumentNullException(nameof(scriptName)); - } + ArgumentNullException.ThrowIfNull(scriptName); - if (script is null) - { - throw new ArgumentNullException(nameof(script)); - } + ArgumentNullException.ThrowIfNull(script); if (this.initializationScripts.TryGetValue(scriptName, out InitializationScript? existingScript)) { @@ -198,10 +192,7 @@ public async Task AddInitializationScript(string scriptNam /// If is . public async Task RemoveInitializationScript(string scriptName) { - if (scriptName is null) - { - throw new ArgumentNullException(nameof(scriptName)); - } + ArgumentNullException.ThrowIfNull(scriptName); if (this.initializationScripts.TryGetValue(scriptName, out InitializationScript? script)) { @@ -235,10 +226,7 @@ public async Task ClearInitializationScripts() /// If is . public async Task PinScript([StringSyntax(StringSyntaxConstants.JavaScript)] string script) { - if (script == null) - { - throw new ArgumentNullException(nameof(script)); - } + ArgumentNullException.ThrowIfNull(script); string newScriptHandle = Guid.NewGuid().ToString("N"); @@ -263,10 +251,7 @@ public async Task PinScript([StringSyntax(StringSyntaxConstants.Ja /// If is . public async Task UnpinScript(PinnedScript script) { - if (script == null) - { - throw new ArgumentNullException(nameof(script)); - } + ArgumentNullException.ThrowIfNull(script); if (this.pinnedScripts.ContainsKey(script.Handle)) { @@ -286,10 +271,7 @@ public async Task UnpinScript(PinnedScript script) /// If A binding with the specified name already exists. public async Task AddScriptCallbackBinding(string bindingName) { - if (bindingName is null) - { - throw new ArgumentNullException(nameof(bindingName)); - } + ArgumentNullException.ThrowIfNull(bindingName); if (!this.bindings.Add(bindingName)) { @@ -308,10 +290,7 @@ public async Task AddScriptCallbackBinding(string bindingName) /// If is . public async Task RemoveScriptCallbackBinding(string bindingName) { - if (bindingName is null) - { - throw new ArgumentNullException(nameof(bindingName)); - } + ArgumentNullException.ThrowIfNull(bindingName); await this.session.Value.Domains.JavaScript.RemoveBinding(bindingName).ConfigureAwait(false); _ = this.bindings.Remove(bindingName); diff --git a/dotnet/src/webdriver/Logs.cs b/dotnet/src/webdriver/Logs.cs index f72f194ad5d9d..90f9800370cc4 100644 --- a/dotnet/src/webdriver/Logs.cs +++ b/dotnet/src/webdriver/Logs.cs @@ -77,10 +77,7 @@ public ReadOnlyCollection AvailableLogTypes /// If is . public ReadOnlyCollection GetLog(string logKind) { - if (logKind is null) - { - throw new ArgumentNullException(nameof(logKind)); - } + ArgumentNullException.ThrowIfNull(logKind); List entries = new List(); diff --git a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs index 13b50064436eb..c0c8fe58e928e 100644 --- a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs +++ b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs @@ -385,10 +385,7 @@ private class HttpRequestInfo { public HttpRequestInfo(Uri serverUri, Command commandToExecute, HttpCommandInfo commandInfo) { - if (commandInfo is null) - { - throw new ArgumentNullException(nameof(commandInfo)); - } + ArgumentNullException.ThrowIfNull(commandInfo); this.FullUri = commandInfo.CreateCommandUri(serverUri, commandToExecute); this.HttpMethod = commandInfo.Method; @@ -424,10 +421,7 @@ private class DiagnosticsHttpHandler : DelegatingHandler public DiagnosticsHttpHandler(HttpMessageHandler messageHandler, ILogger logger) : base(messageHandler) { - if (messageHandler is null) - { - throw new ArgumentNullException(nameof(messageHandler)); - } + ArgumentNullException.ThrowIfNull(messageHandler); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } diff --git a/dotnet/src/webdriver/Remote/RemoteWebDriver.cs b/dotnet/src/webdriver/Remote/RemoteWebDriver.cs index a71f985af1aa7..b478c02be4b4a 100644 --- a/dotnet/src/webdriver/Remote/RemoteWebDriver.cs +++ b/dotnet/src/webdriver/Remote/RemoteWebDriver.cs @@ -448,10 +448,7 @@ public DevToolsSession GetDevToolsSession() [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)] public DevToolsSession GetDevToolsSession(DevToolsOptions options) { - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); if (this.devToolsSession == null) { diff --git a/dotnet/src/webdriver/Safari/SafariDriver.cs b/dotnet/src/webdriver/Safari/SafariDriver.cs index 8b84b657072f9..930acb51c06df 100644 --- a/dotnet/src/webdriver/Safari/SafariDriver.cs +++ b/dotnet/src/webdriver/Safari/SafariDriver.cs @@ -167,15 +167,9 @@ public SafariDriver(SafariDriverService service, SafariOptions options, TimeSpan /// private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { - if (service is null) - { - throw new ArgumentNullException(nameof(service)); - } + ArgumentNullException.ThrowIfNull(service); - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); if (service.DriverServicePath == null) { diff --git a/dotnet/src/webdriver/TargetLocator.cs b/dotnet/src/webdriver/TargetLocator.cs index 263dca0fe19a7..3d92e674815e9 100644 --- a/dotnet/src/webdriver/TargetLocator.cs +++ b/dotnet/src/webdriver/TargetLocator.cs @@ -137,10 +137,7 @@ public IWebDriver ParentFrame() /// If is . public IWebDriver Window(string windowHandleOrName) { - if (windowHandleOrName is null) - { - throw new ArgumentNullException(nameof(windowHandleOrName)); - } + ArgumentNullException.ThrowIfNull(windowHandleOrName); Dictionary parameters = new Dictionary(); parameters.Add("handle", windowHandleOrName); diff --git a/dotnet/src/webdriver/WebDriver.cs b/dotnet/src/webdriver/WebDriver.cs index 45181ed88a2c0..446afd75b52b1 100644 --- a/dotnet/src/webdriver/WebDriver.cs +++ b/dotnet/src/webdriver/WebDriver.cs @@ -259,10 +259,7 @@ public void Dispose() /// If is . public object? ExecuteScript(PinnedScript script, params object?[]? args) { - if (script == null) - { - throw new ArgumentNullException(nameof(script)); - } + ArgumentNullException.ThrowIfNull(script); return this.ExecuteScript(script.MakeExecutionScript(), args); } @@ -365,10 +362,7 @@ public Screenshot GetScreenshot() /// If is . public PrintDocument Print(PrintOptions printOptions) { - if (printOptions is null) - { - throw new ArgumentNullException(nameof(printOptions)); - } + ArgumentNullException.ThrowIfNull(printOptions); Response commandResponse = this.Execute(DriverCommand.Print, printOptions.ToDictionary()); @@ -649,10 +643,7 @@ protected void StartSession(ICapabilities capabilities) /// If is . protected virtual Dictionary GetCapabilitiesDictionary(ICapabilities capabilitiesToConvert) { - if (capabilitiesToConvert is null) - { - throw new ArgumentNullException(nameof(capabilitiesToConvert)); - } + ArgumentNullException.ThrowIfNull(capabilitiesToConvert); Dictionary capabilitiesDictionary = new Dictionary(); @@ -999,10 +990,7 @@ private static void UnpackAndThrowOnError(Response errorResponse, string command /// If is . public string AddVirtualAuthenticator(VirtualAuthenticatorOptions options) { - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); Response commandResponse = this.Execute(DriverCommand.AddVirtualAuthenticator, options.ToDictionary()); @@ -1019,10 +1007,7 @@ public string AddVirtualAuthenticator(VirtualAuthenticatorOptions options) /// If is . public void RemoveVirtualAuthenticator(string authenticatorId) { - if (authenticatorId is null) - { - throw new ArgumentNullException(nameof(authenticatorId)); - } + ArgumentNullException.ThrowIfNull(authenticatorId); Dictionary parameters = new Dictionary(); parameters.Add("authenticatorId", authenticatorId); @@ -1044,10 +1029,7 @@ public void RemoveVirtualAuthenticator(string authenticatorId) /// If a Virtual Authenticator has not been added yet. public void AddCredential(Credential credential) { - if (credential is null) - { - throw new ArgumentNullException(nameof(credential)); - } + ArgumentNullException.ThrowIfNull(credential); string authenticatorId = this.AuthenticatorId ?? throw new InvalidOperationException("Virtual Authenticator needs to be added before it can perform operations"); @@ -1106,10 +1088,7 @@ public void RemoveCredential(byte[] credentialId) /// If a Virtual Authenticator has not been added yet. public void RemoveCredential(string credentialId) { - if (credentialId is null) - { - throw new ArgumentNullException(nameof(credentialId)); - } + ArgumentNullException.ThrowIfNull(credentialId); string authenticatorId = this.AuthenticatorId ?? throw new InvalidOperationException("Virtual Authenticator needs to be added before it can perform operations"); From 202dc9eff476dd1487a8ce8073d44121d4b25416 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Tue, 9 Dec 2025 00:38:26 -0500 Subject: [PATCH 2/5] [dotnet] Update lang version to 14 --- dotnet/src/support/BUILD.bazel | 4 ++-- dotnet/src/support/Selenium.WebDriver.Support.csproj | 2 +- dotnet/src/webdriver/BUILD.bazel | 12 ++++++------ dotnet/src/webdriver/Selenium.WebDriver.csproj | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dotnet/src/support/BUILD.bazel b/dotnet/src/support/BUILD.bazel index 9cc66665c7618..f7fd31317265c 100644 --- a/dotnet/src/support/BUILD.bazel +++ b/dotnet/src/support/BUILD.bazel @@ -37,7 +37,7 @@ csharp_library( "//dotnet:source_files_support_needs_from_core", ], out = "WebDriver.Support", - langversion = "12.0", + langversion = "14.0", nullable = "enable", target_frameworks = [ "netstandard2.0", @@ -80,7 +80,7 @@ csharp_library( ], out = "WebDriver.Support.StrongNamed", keyfile = "//dotnet:Selenium.snk", - langversion = "12.0", + langversion = "14.0", nullable = "enable", target_frameworks = [ "netstandard2.0", diff --git a/dotnet/src/support/Selenium.WebDriver.Support.csproj b/dotnet/src/support/Selenium.WebDriver.Support.csproj index 1b2d7313a771e..9c5716d26749c 100644 --- a/dotnet/src/support/Selenium.WebDriver.Support.csproj +++ b/dotnet/src/support/Selenium.WebDriver.Support.csproj @@ -5,7 +5,7 @@ WebDriver.Support OpenQA.Selenium.Support visual-studio - 12.0 + 14.0 enable diff --git a/dotnet/src/webdriver/BUILD.bazel b/dotnet/src/webdriver/BUILD.bazel index 09c585520ff95..c0abfcdcd1b2d 100644 --- a/dotnet/src/webdriver/BUILD.bazel +++ b/dotnet/src/webdriver/BUILD.bazel @@ -51,7 +51,7 @@ csharp_library( internals_visible_to = [ "WebDriver.Common.Tests", ], - langversion = "12.0", + langversion = "14.0", nullable = "enable", target_frameworks = [ "net462", @@ -83,7 +83,7 @@ csharp_library( internals_visible_to = [ "WebDriver.Common.Tests", ], - langversion = "12.0", + langversion = "14.0", nullable = "enable", resources = [], target_frameworks = [ @@ -119,7 +119,7 @@ csharp_library( internals_visible_to = [ "WebDriver.Common.Tests", ], - langversion = "12.0", + langversion = "14.0", nullable = "enable", resources = [], target_frameworks = [ @@ -142,7 +142,7 @@ csharp_library( ]) + devtools_version_targets(), out = "WebDriver.StrongNamed", keyfile = "//dotnet:Selenium.snk", - langversion = "12.0", + langversion = "14.0", nullable = "enable", target_frameworks = [ "net462", @@ -172,7 +172,7 @@ csharp_library( ]) + devtools_version_targets(), out = "WebDriver.StrongNamed", keyfile = "//dotnet:Selenium.snk", - langversion = "12.0", + langversion = "14.0", nullable = "enable", resources = [], target_frameworks = [ @@ -206,7 +206,7 @@ csharp_library( "NET8_0_OR_GREATER", ], keyfile = "//dotnet:Selenium.snk", - langversion = "12.0", + langversion = "14.0", nullable = "enable", resources = [], target_frameworks = [ diff --git a/dotnet/src/webdriver/Selenium.WebDriver.csproj b/dotnet/src/webdriver/Selenium.WebDriver.csproj index e68638772ef22..ad09dfe5dc63a 100644 --- a/dotnet/src/webdriver/Selenium.WebDriver.csproj +++ b/dotnet/src/webdriver/Selenium.WebDriver.csproj @@ -4,7 +4,7 @@ net462;netstandard2.0;net8.0; WebDriver OpenQA.Selenium - 12.0 + 14.0 enable From 122096ce05a64d6e89113efdf69ca9901562e56f Mon Sep 17 00:00:00 2001 From: Michael Render Date: Tue, 9 Dec 2025 00:43:08 -0500 Subject: [PATCH 3/5] Move polyfills to `Properties` folder --- .../Polyfills => Properties}/ArgumentNullExceptionExtensions.cs | 0 .../Polyfills => Properties}/CallerArgumentExpressionAttribute.cs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename dotnet/src/webdriver/{Internal/Polyfills => Properties}/ArgumentNullExceptionExtensions.cs (100%) rename dotnet/src/webdriver/{Internal/Polyfills => Properties}/CallerArgumentExpressionAttribute.cs (100%) diff --git a/dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs b/dotnet/src/webdriver/Properties/ArgumentNullExceptionExtensions.cs similarity index 100% rename from dotnet/src/webdriver/Internal/Polyfills/ArgumentNullExceptionExtensions.cs rename to dotnet/src/webdriver/Properties/ArgumentNullExceptionExtensions.cs diff --git a/dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs b/dotnet/src/webdriver/Properties/CallerArgumentExpressionAttribute.cs similarity index 100% rename from dotnet/src/webdriver/Internal/Polyfills/CallerArgumentExpressionAttribute.cs rename to dotnet/src/webdriver/Properties/CallerArgumentExpressionAttribute.cs From 2d95d783cb733cc421e24daf6bdb169813fa6247 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Tue, 9 Dec 2025 00:56:40 -0500 Subject: [PATCH 4/5] Account for new exception in alert test --- dotnet/test/common/AlertsTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/common/AlertsTest.cs b/dotnet/test/common/AlertsTest.cs index 7bf5985d01a37..f2255c1964a66 100644 --- a/dotnet/test/common/AlertsTest.cs +++ b/dotnet/test/common/AlertsTest.cs @@ -420,7 +420,7 @@ public void ShouldNotHandleAlertInAnotherWindow() IWebElement el = driver.FindElement(By.Id("open-new-window")); WaitFor(AlertToBePresent, TimeSpan.FromSeconds(5), "No alert found"); }, - Throws.TypeOf()); + Throws.InstanceOf()); } finally From d327ab4ce283e3bde899f9e6861df17496182a88 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Tue, 9 Dec 2025 00:57:53 -0500 Subject: [PATCH 5/5] Revert push to wrong branch --- dotnet/test/common/AlertsTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/common/AlertsTest.cs b/dotnet/test/common/AlertsTest.cs index f2255c1964a66..7bf5985d01a37 100644 --- a/dotnet/test/common/AlertsTest.cs +++ b/dotnet/test/common/AlertsTest.cs @@ -420,7 +420,7 @@ public void ShouldNotHandleAlertInAnotherWindow() IWebElement el = driver.FindElement(By.Id("open-new-window")); WaitFor(AlertToBePresent, TimeSpan.FromSeconds(5), "No alert found"); }, - Throws.InstanceOf()); + Throws.TypeOf()); } finally