diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 2c34844ffcbd1..93150dd91013f 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -21,8 +21,11 @@
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+#nullable enable
+
namespace OpenQA.Selenium
{
///
@@ -112,22 +115,9 @@ public Dictionary ToCapabilities()
///
public abstract class DriverOptions
{
- private string browserName;
- private string browserVersion;
- private string platformName;
- private Proxy proxy;
- private bool? acceptInsecureCertificates;
- private bool? useWebSocketUrl;
- private bool useStrictFileInteractability;
- private bool? enableDownloads;
- private TimeSpan? scriptTimeout;
- private TimeSpan? pageLoadTimeout;
- private TimeSpan? implicitWaitTimeout;
- private UnhandledPromptBehavior unhandledPromptBehavior = UnhandledPromptBehavior.Default;
- private PageLoadStrategy pageLoadStrategy = PageLoadStrategy.Default;
- private Dictionary additionalCapabilities = new Dictionary();
- private Dictionary loggingPreferences = new Dictionary();
- private Dictionary knownCapabilityNames = new Dictionary();
+ private readonly Dictionary additionalCapabilities = new Dictionary();
+ private readonly Dictionary loggingPreferences = new Dictionary();
+ private readonly Dictionary knownCapabilityNames = new Dictionary();
///
/// Initializes a new instance of the class.
@@ -148,97 +138,57 @@ protected DriverOptions()
///
/// Gets or sets the name of the browser.
///
- public string BrowserName
- {
- get { return this.browserName; }
- protected set { this.browserName = value; }
- }
+ public string? BrowserName { get; protected set; }
///
/// Gets or sets the version of the browser.
///
- public string BrowserVersion
- {
- get { return this.browserVersion; }
- set { this.browserVersion = value; }
- }
+ public string? BrowserVersion { get; set; }
///
/// Gets or sets the name of the platform on which the browser is running.
///
- public string PlatformName
- {
- get { return this.platformName; }
- set { this.platformName = value; }
- }
+ public string? PlatformName { get; set; }
///
/// Gets or sets a value indicating whether the browser should accept self-signed
/// SSL certificates.
///
- public bool? AcceptInsecureCertificates
- {
- get { return this.acceptInsecureCertificates; }
- set { this.acceptInsecureCertificates = value; }
- }
+ public bool? AcceptInsecureCertificates { get; set; }
///
/// Gets or sets a value indicating whether the driver should request a URL to
/// a WebSocket to be used for bidirectional communication.
///
- public bool? UseWebSocketUrl
- {
- get { return this.useWebSocketUrl; }
- set { this.useWebSocketUrl = value; }
- }
+ public bool? UseWebSocketUrl { get; set; }
///
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
/// Defaults to .
///
- public UnhandledPromptBehavior UnhandledPromptBehavior
- {
- get { return this.unhandledPromptBehavior; }
- set { this.unhandledPromptBehavior = value; }
- }
+ public UnhandledPromptBehavior UnhandledPromptBehavior { get; set; } = UnhandledPromptBehavior.Default;
///
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
/// Defaults to .
///
- public PageLoadStrategy PageLoadStrategy
- {
- get { return this.pageLoadStrategy; }
- set { this.pageLoadStrategy = value; }
- }
+ public PageLoadStrategy PageLoadStrategy { get; set; } = PageLoadStrategy.Default;
///
/// Gets or sets the to be used with this browser.
///
- public Proxy Proxy
- {
- get { return this.proxy; }
- set { this.proxy = value; }
- }
+ public Proxy? Proxy { get; set; }
///
/// Gets or sets a value indicating whether <input type='file'/> elements
/// must be visible to allow uploading of files.
///
- public bool UseStrictFileInteractability
- {
- get { return this.useStrictFileInteractability; }
- set { this.useStrictFileInteractability = value; }
- }
+ public bool UseStrictFileInteractability { get; set; }
///
/// Gets or sets a value indicating whether files may be downloaded from remote node.
///
- public bool? EnableDownloads
- {
- get { return this.enableDownloads; }
- set { this.enableDownloads = value; }
- }
+ public bool? EnableDownloads { get; set; }
///
/// Gets or sets the asynchronous script timeout, which is the amount
@@ -246,22 +196,14 @@ public bool? EnableDownloads
/// This timeout only affects the
/// method.
///
- public TimeSpan? ScriptTimeout
- {
- get { return this.scriptTimeout; }
- set { this.scriptTimeout = value; }
- }
+ public TimeSpan? ScriptTimeout { get; set; }
///
/// Gets or sets the page load timeout, which is the amount of time the driver
/// should wait for a page to load when setting the
/// property.
///
- public TimeSpan? PageLoadTimeout
- {
- get { return this.pageLoadTimeout; }
- set { this.pageLoadTimeout = value; }
- }
+ public TimeSpan? PageLoadTimeout { get; set; }
///
/// Gets or sets the implicit wait timeout, which is the amount of time the
@@ -280,20 +222,16 @@ public TimeSpan? PageLoadTimeout
/// slower location strategies like XPath.
///
///
- public TimeSpan? ImplicitWaitTimeout
- {
- get { return this.implicitWaitTimeout; }
- set { this.implicitWaitTimeout = value; }
- }
+ public TimeSpan? ImplicitWaitTimeout { get; set; }
///
/// Set or Get the location of the browser
/// Override in subclass
///
- public virtual string BinaryLocation
+ public virtual string? BinaryLocation
{
- get { return null; }
- set { throw new NotImplementedException(); }
+ get => null;
+ set => throw new NotImplementedException();
}
///
@@ -330,45 +268,51 @@ public virtual void AddAdditionalOption(string optionName, object optionValue)
///
/// The object to compare with.
/// A object containing the status of the attempted merge.
+ /// If is .
public virtual DriverOptionsMergeResult GetMergeResult(DriverOptions other)
{
+ if (other is null)
+ {
+ throw new ArgumentNullException(nameof(other));
+ }
+
DriverOptionsMergeResult result = new DriverOptionsMergeResult();
- if (this.browserName != null && other.BrowserName != null)
+ if (this.BrowserName != null && other.BrowserName != null)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "BrowserName";
return result;
}
- if (this.browserVersion != null && other.BrowserVersion != null)
+ if (this.BrowserVersion != null && other.BrowserVersion != null)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "BrowserVersion";
return result;
}
- if (this.platformName != null && other.PlatformName != null)
+ if (this.PlatformName != null && other.PlatformName != null)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "PlatformName";
return result;
}
- if (this.proxy != null && other.Proxy != null)
+ if (this.Proxy != null && other.Proxy != null)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "Proxy";
return result;
}
- if (this.unhandledPromptBehavior != UnhandledPromptBehavior.Default && other.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
+ if (this.UnhandledPromptBehavior != UnhandledPromptBehavior.Default && other.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "UnhandledPromptBehavior";
return result;
}
- if (this.pageLoadStrategy != PageLoadStrategy.Default && other.PageLoadStrategy != PageLoadStrategy.Default)
+ if (this.PageLoadStrategy != PageLoadStrategy.Default && other.PageLoadStrategy != PageLoadStrategy.Default)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "PageLoadStrategy";
@@ -393,10 +337,10 @@ public void SetLoggingPreference(string logType, LogLevel logLevel)
/// Returns the current options as a .
///
/// The current options as a .
- internal IDictionary ToDictionary()
+ internal IDictionary? ToDictionary()
{
- IHasCapabilitiesDictionary desired = this.ToCapabilities() as IHasCapabilitiesDictionary;
- if (desired == null)
+ ICapabilities? capabilities = this.ToCapabilities();
+ if (capabilities is not IHasCapabilitiesDictionary desired)
{
return null;
}
@@ -413,16 +357,15 @@ internal IDictionary ToDictionary()
/// thrown when attempting to add a capability for which there is already a type safe option, or
/// when is or the empty string.
///
- protected void ValidateCapabilityName(string capabilityName)
+ protected void ValidateCapabilityName([NotNull] string? capabilityName)
{
- if (string.IsNullOrEmpty(capabilityName))
+ if (capabilityName is null || string.IsNullOrEmpty(capabilityName))
{
throw new ArgumentException("Capability name may not be null an empty string.", nameof(capabilityName));
}
- if (this.IsKnownCapabilityName(capabilityName))
+ if (this.TryGetKnownCapability(capabilityName!, out string? typeSafeOptionName))
{
- string typeSafeOptionName = this.GetTypeSafeOptionName(capabilityName);
string message = string.Format(CultureInfo.InvariantCulture, "There is already an option for the {0} capability. Please use the {1} instead.", capabilityName, typeSafeOptionName);
throw new ArgumentException(message, nameof(capabilityName));
}
@@ -443,9 +386,9 @@ protected void AddKnownCapabilityName(string capabilityName, string typeSafeOpti
/// Remove a capability from the list of known capabilities
///
/// The name of the capability to be removed.
- protected void RemoveKnownCapabilityName(string capabilityName)
+ protected void RemoveKnownCapabilityName(string? capabilityName)
{
- if (!string.IsNullOrEmpty(capabilityName) && this.knownCapabilityNames.ContainsKey(capabilityName))
+ if (capabilityName is not null)
{
this.knownCapabilityNames.Remove(capabilityName);
}
@@ -461,6 +404,17 @@ protected bool IsKnownCapabilityName(string capabilityName)
return this.knownCapabilityNames.ContainsKey(capabilityName);
}
+ ///
+ /// Gets a value indicating whether the specified capability name is a known capability name which has a type-safe option.
+ ///
+ /// The name of the capability to check.
+ /// The name of the type-safe option for the given capability name, or if not found.
+ /// if the capability name is known; otherwise .
+ protected bool TryGetKnownCapability(string capabilityName, [NotNullWhen(true)] out string? typeSafeOptionName)
+ {
+ return this.knownCapabilityNames.TryGetValue(capabilityName, out typeSafeOptionName);
+ }
+
///
/// Gets the name of the type-safe option for a given capability name.
///
@@ -480,7 +434,7 @@ protected string GetTypeSafeOptionName(string capabilityName)
/// Generates the logging preferences dictionary for transmission as a desired capability.
///
/// The dictionary containing the logging preferences.
- protected Dictionary GenerateLoggingPreferencesDictionary()
+ protected Dictionary? GenerateLoggingPreferencesDictionary()
{
if (this.loggingPreferences.Count == 0)
{
@@ -504,45 +458,45 @@ protected Dictionary GenerateLoggingPreferencesDictionary()
protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecificationCompliant)
{
DesiredCapabilities capabilities = new DesiredCapabilities();
- if (!string.IsNullOrEmpty(this.browserName))
+ if (!string.IsNullOrEmpty(this.BrowserName))
{
- capabilities.SetCapability(CapabilityType.BrowserName, this.browserName);
+ capabilities.SetCapability(CapabilityType.BrowserName, this.BrowserName!);
}
- if (!string.IsNullOrEmpty(this.browserVersion))
+ if (!string.IsNullOrEmpty(this.BrowserVersion))
{
- capabilities.SetCapability(CapabilityType.BrowserVersion, this.browserVersion);
+ capabilities.SetCapability(CapabilityType.BrowserVersion, this.BrowserVersion!);
}
- if (!string.IsNullOrEmpty(this.platformName))
+ if (!string.IsNullOrEmpty(this.PlatformName))
{
- capabilities.SetCapability(CapabilityType.PlatformName, this.platformName);
+ capabilities.SetCapability(CapabilityType.PlatformName, this.PlatformName!);
}
- if (this.acceptInsecureCertificates.HasValue)
+ if (this.AcceptInsecureCertificates.HasValue)
{
- capabilities.SetCapability(CapabilityType.AcceptInsecureCertificates, this.acceptInsecureCertificates);
+ capabilities.SetCapability(CapabilityType.AcceptInsecureCertificates, this.AcceptInsecureCertificates);
}
- if (this.useWebSocketUrl.HasValue)
+ if (this.UseWebSocketUrl.HasValue)
{
- capabilities.SetCapability(CapabilityType.WebSocketUrl, this.useWebSocketUrl);
+ capabilities.SetCapability(CapabilityType.WebSocketUrl, this.UseWebSocketUrl);
}
- if (this.enableDownloads.HasValue)
+ if (this.EnableDownloads.HasValue)
{
- capabilities.SetCapability(CapabilityType.EnableDownloads, this.enableDownloads);
+ capabilities.SetCapability(CapabilityType.EnableDownloads, this.EnableDownloads);
}
- if (this.useStrictFileInteractability)
+ if (this.UseStrictFileInteractability)
{
capabilities.SetCapability(CapabilityType.UseStrictFileInteractability, true);
}
- if (this.pageLoadStrategy != PageLoadStrategy.Default)
+ if (this.PageLoadStrategy != PageLoadStrategy.Default)
{
string pageLoadStrategySetting = "normal";
- switch (this.pageLoadStrategy)
+ switch (this.PageLoadStrategy)
{
case PageLoadStrategy.Eager:
pageLoadStrategySetting = "eager";
@@ -583,7 +537,7 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
if (this.Proxy != null)
{
- Dictionary proxyCapability = this.Proxy.ToCapability();
+ Dictionary? proxyCapability = this.Proxy.ToCapability();
if (!isSpecificationCompliant)
{
proxyCapability = this.Proxy.ToLegacyCapability();
@@ -595,13 +549,13 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
}
}
- if (this.scriptTimeout.HasValue || this.pageLoadTimeout.HasValue || this.implicitWaitTimeout.HasValue)
+ if (this.ScriptTimeout.HasValue || this.PageLoadTimeout.HasValue || this.ImplicitWaitTimeout.HasValue)
{
var timeouts = new Timeout
{
- Script = this.scriptTimeout,
- PageLoad = this.pageLoadTimeout,
- ImplicitWait = this.implicitWaitTimeout
+ Script = this.ScriptTimeout,
+ PageLoad = this.PageLoadTimeout,
+ ImplicitWait = this.ImplicitWaitTimeout
};
capabilities.SetCapability(CapabilityType.Timeouts, timeouts.ToCapabilities());