Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b120bea

Browse files
RenderMichaelsandeepsuryaprasad
authored andcommittedMar 23, 2025
[dotnet] Annotate nullability on elements and WebDriver (SeleniumHQ#15352)
* [dotnet] Annotate nullability on elements and `WebDriver` * Fix null warnings
1 parent fbc87f5 commit b120bea

16 files changed

+85
-97
lines changed
 

‎dotnet/src/support/Events/EventFiringWebDriver.cs

+14-26
Original file line numberDiff line numberDiff line change
@@ -442,14 +442,14 @@ public void Dispose()
442442
/// variable, as if the function were called via "Function.apply"
443443
/// </para>
444444
/// </remarks>
445-
public object ExecuteScript(string script, params object?[] args)
445+
public object? ExecuteScript(string script, params object?[] args)
446446
{
447447
if (this.WrappedDriver is not IJavaScriptExecutor javascriptDriver)
448448
{
449449
throw new NotSupportedException("Underlying driver instance does not support executing JavaScript");
450450
}
451451

452-
object scriptResult;
452+
object? scriptResult;
453453
try
454454
{
455455
object?[] unwrappedArgs = UnwrapElementArguments(args);
@@ -505,7 +505,7 @@ public object ExecuteScript(string script, params object?[] args)
505505
/// variable, as if the function were called via "Function.apply"
506506
/// </para>
507507
/// </remarks>
508-
public object ExecuteScript(PinnedScript script, params object?[] args)
508+
public object? ExecuteScript(PinnedScript script, params object?[] args)
509509
{
510510
if (script == null)
511511
{
@@ -517,7 +517,7 @@ public object ExecuteScript(PinnedScript script, params object?[] args)
517517
throw new NotSupportedException("Underlying driver instance does not support executing JavaScript");
518518
}
519519

520-
object scriptResult;
520+
object? scriptResult;
521521
try
522522
{
523523
object?[] unwrappedArgs = UnwrapElementArguments(args);
@@ -542,14 +542,14 @@ public object ExecuteScript(PinnedScript script, params object?[] args)
542542
/// <param name="script">The JavaScript code to execute.</param>
543543
/// <param name="args">The arguments to the script.</param>
544544
/// <returns>The value returned by the script.</returns>
545-
public object ExecuteAsyncScript(string script, params object?[] args)
545+
public object? ExecuteAsyncScript(string script, params object?[] args)
546546
{
547547
if (this.WrappedDriver is not IJavaScriptExecutor javascriptDriver)
548548
{
549549
throw new NotSupportedException("Underlying driver instance does not support executing JavaScript");
550550
}
551551

552-
object scriptResult;
552+
object? scriptResult;
553553
try
554554
{
555555
object?[] unwrappedArgs = UnwrapElementArguments(args);
@@ -1589,20 +1589,17 @@ public void Click()
15891589
/// </summary>
15901590
/// <param name="attributeName">Attribute you wish to get details of</param>
15911591
/// <returns>The attribute's current value or null if the value is not set.</returns>
1592-
public string GetAttribute(string attributeName)
1592+
public string? GetAttribute(string attributeName)
15931593
{
1594-
string attribute;
15951594
try
15961595
{
1597-
attribute = this.WrappedElement.GetAttribute(attributeName);
1596+
return this.WrappedElement.GetAttribute(attributeName);
15981597
}
15991598
catch (Exception ex)
16001599
{
16011600
this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex));
16021601
throw;
16031602
}
1604-
1605-
return attribute;
16061603
}
16071604

16081605
/// <summary>
@@ -1617,20 +1614,17 @@ public string GetAttribute(string attributeName)
16171614
/// of an IDL property of the element, either use the <see cref="GetAttribute(string)"/>
16181615
/// method or the <see cref="GetDomProperty(string)"/> method.
16191616
/// </remarks>
1620-
public string GetDomAttribute(string attributeName)
1617+
public string? GetDomAttribute(string attributeName)
16211618
{
1622-
string attribute;
16231619
try
16241620
{
1625-
attribute = this.WrappedElement.GetDomAttribute(attributeName);
1621+
return this.WrappedElement.GetDomAttribute(attributeName);
16261622
}
16271623
catch (Exception ex)
16281624
{
16291625
this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex));
16301626
throw;
16311627
}
1632-
1633-
return attribute;
16341628
}
16351629

16361630
/// <summary>
@@ -1639,20 +1633,17 @@ public string GetDomAttribute(string attributeName)
16391633
/// <param name="propertyName">The name of the JavaScript property to get the value of.</param>
16401634
/// <returns>The JavaScript property's current value. Returns a <see langword="null"/> if the
16411635
/// value is not set or the property does not exist.</returns>
1642-
public string GetDomProperty(string propertyName)
1636+
public string? GetDomProperty(string propertyName)
16431637
{
1644-
string elementProperty;
16451638
try
16461639
{
1647-
elementProperty = this.WrappedElement.GetDomProperty(propertyName);
1640+
return this.WrappedElement.GetDomProperty(propertyName);
16481641
}
16491642
catch (Exception ex)
16501643
{
16511644
this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex));
16521645
throw;
16531646
}
1654-
1655-
return elementProperty;
16561647
}
16571648

16581649
/// <summary>
@@ -1683,22 +1674,19 @@ public string GetCssValue(string propertyName)
16831674
/// <returns>A shadow root representation.</returns>
16841675
public ISearchContext GetShadowRoot()
16851676
{
1686-
ISearchContext shadowRoot;
16871677
try
16881678
{
16891679
GetShadowRootEventArgs e = new GetShadowRootEventArgs(this.parentDriver.WrappedDriver, this.WrappedElement);
16901680
this.parentDriver.OnGettingShadowRoot(e);
1691-
shadowRoot = this.WrappedElement.GetShadowRoot();
1681+
ISearchContext shadowRoot = this.WrappedElement.GetShadowRoot();
16921682
this.parentDriver.OnGetShadowRootCompleted(e);
1693-
shadowRoot = new EventFiringShadowRoot(this.parentDriver, shadowRoot);
1683+
return new EventFiringShadowRoot(this.parentDriver, shadowRoot);
16941684
}
16951685
catch (Exception ex)
16961686
{
16971687
this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex));
16981688
throw;
16991689
}
1700-
1701-
return shadowRoot;
17021690
}
17031691

17041692
/// <summary>

‎dotnet/src/webdriver/By.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ protected By(Func<ISearchContext, IWebElement> findElementMethod, Func<ISearchCo
9999
protected string Description { get; set; } = "OpenQA.Selenium.By";
100100

101101
/// <summary>
102-
/// Gets or sets the method used to find a single element matching specified criteria.
102+
/// Gets or sets the method used to find a single element matching specified criteria, or throws <see cref="NoSuchElementException"/> if no element is found.
103103
/// </summary>
104104
protected Func<ISearchContext, IWebElement>? FindElementMethod { get; set; }
105105

@@ -324,6 +324,7 @@ public static By CssSelector(string cssSelectorToFind)
324324
/// </summary>
325325
/// <param name="context">An <see cref="ISearchContext"/> object to use to search for the elements.</param>
326326
/// <returns>The first matching <see cref="IWebElement"/> on the current context.</returns>
327+
/// <exception cref="NoSuchElementException">If no element matches the criteria.</exception>
327328
public virtual IWebElement FindElement(ISearchContext context)
328329
{
329330
if (this.FindElementMethod is not { } findElementMethod)

‎dotnet/src/webdriver/Chromium/ChromiumDriver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
168168
string fullServicePath = finder.GetDriverPath();
169169
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
170170
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
171-
if (finder.TryGetBrowserPath(out string browserPath))
171+
if (finder.TryGetBrowserPath(out string? browserPath))
172172
{
173173
options.BinaryLocation = browserPath;
174174
options.BrowserVersion = null;

‎dotnet/src/webdriver/Command.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ public Command(string name, string jsonParameters)
5656
/// <param name="name">Name of the command</param>
5757
/// <param name="parameters">Parameters for that command</param>
5858
/// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langword="null"/>.</exception>
59-
public Command(SessionId? sessionId, string name, Dictionary<string, object>? parameters)
59+
public Command(SessionId? sessionId, string name, Dictionary<string, object?>? parameters)
6060
{
6161
this.SessionId = sessionId;
62-
this.Parameters = parameters ?? new Dictionary<string, object>();
62+
this.Parameters = parameters ?? new Dictionary<string, object?>();
6363
this.Name = name ?? throw new ArgumentNullException(nameof(name));
6464
}
6565

@@ -79,7 +79,7 @@ public Command(SessionId? sessionId, string name, Dictionary<string, object>? pa
7979
/// Gets the parameters of the command
8080
/// </summary>
8181
[JsonPropertyName("parameters")]
82-
public Dictionary<string, object> Parameters { get; }
82+
public Dictionary<string, object?> Parameters { get; }
8383

8484
/// <summary>
8585
/// Gets the parameters of the command as a JSON-encoded string.
@@ -118,9 +118,9 @@ public override string ToString()
118118
/// <returns>A <see cref="Dictionary{K, V}"/> with a string keys, and an object value. </returns>
119119
/// <exception cref="JsonException">If <paramref name="value"/> is not a JSON object.</exception>
120120
/// <exception cref="ArgumentNullException">If <paramref name="value"/> is <see langword="null"/>.</exception>
121-
private static Dictionary<string, object>? ConvertParametersFromJson(string value)
121+
private static Dictionary<string, object?>? ConvertParametersFromJson(string value)
122122
{
123-
Dictionary<string, object>? parameters = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions);
123+
Dictionary<string, object?>? parameters = JsonSerializer.Deserialize<Dictionary<string, object?>>(value, s_jsonSerializerOptions);
124124
return parameters;
125125
}
126126
}

‎dotnet/src/webdriver/CookieJar.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public void DeleteAllCookies()
127127
{
128128
var rawCookie = driver.InternalExecute(DriverCommand.GetCookie, new() { { "name", name } }).Value;
129129

130-
return Cookie.FromDictionary((Dictionary<string, object>)rawCookie!);
130+
return Cookie.FromDictionary((Dictionary<string, object?>)rawCookie!);
131131
}
132132
catch (NoSuchCookieException)
133133
{

‎dotnet/src/webdriver/Firefox/FirefoxDriver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
221221
string fullServicePath = finder.GetDriverPath();
222222
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
223223
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
224-
if (finder.TryGetBrowserPath(out string browserPath))
224+
if (finder.TryGetBrowserPath(out string? browserPath))
225225
{
226226
options.BinaryLocation = browserPath;
227227
options.BrowserVersion = null;

‎dotnet/src/webdriver/Firefox/FirefoxProfile.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public void WriteToDisk()
160160
this.ProfileDirectory = GenerateProfileDirectoryName();
161161
if (!string.IsNullOrEmpty(this.sourceProfileDir))
162162
{
163-
FileUtilities.CopyDirectory(this.sourceProfileDir, this.ProfileDirectory);
163+
FileUtilities.CopyDirectory(this.sourceProfileDir!, this.ProfileDirectory);
164164
}
165165
else
166166
{

‎dotnet/src/webdriver/IJavascriptExecutor.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using System;
2121
using System.Collections.Generic;
2222

23+
#nullable enable
24+
2325
namespace OpenQA.Selenium
2426
{
2527
/// <summary>
@@ -62,7 +64,7 @@ public interface IJavaScriptExecutor
6264
/// variable, as if the function were called via "Function.apply"
6365
/// </para>
6466
/// </remarks>
65-
object ExecuteScript(string script, params object[] args);
67+
object? ExecuteScript(string script, params object?[] args);
6668

6769
/// <summary>
6870
/// Executes JavaScript in the context of the currently selected frame or window.
@@ -100,14 +102,14 @@ public interface IJavaScriptExecutor
100102
/// </para>
101103
/// </remarks>
102104
/// <exception cref="ArgumentNullException">If <paramref name="script" /> is <see langword="null"/>.</exception>
103-
object ExecuteScript(PinnedScript script, params object[] args);
105+
object? ExecuteScript(PinnedScript script, params object?[] args);
104106

105107
/// <summary>
106108
/// Executes JavaScript asynchronously in the context of the currently selected frame or window.
107109
/// </summary>
108110
/// <param name="script">The JavaScript code to execute.</param>
109111
/// <param name="args">The arguments to the script.</param>
110112
/// <returns>The value returned by the script.</returns>
111-
object ExecuteAsyncScript(string script, params object[] args);
113+
object? ExecuteAsyncScript(string script, params object?[] args);
112114
}
113115
}

‎dotnet/src/webdriver/IWebDriver.cs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using System;
2121
using System.Collections.ObjectModel;
2222

23+
#nullable enable
24+
2325
namespace OpenQA.Selenium
2426
{
2527
/// <summary>

‎dotnet/src/webdriver/IWebElement.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using System;
2121
using System.Drawing;
2222

23+
#nullable enable
24+
2325
namespace OpenQA.Selenium
2426
{
2527
/// <summary>
@@ -170,7 +172,7 @@ public interface IWebElement : ISearchContext
170172
/// </list>
171173
/// </remarks>
172174
/// <exception cref="StaleElementReferenceException">Thrown when the target element is no longer valid in the document DOM.</exception>
173-
string GetAttribute(string attributeName);
175+
string? GetAttribute(string attributeName);
174176

175177
/// <summary>
176178
/// Gets the value of a declared HTML attribute of this element.
@@ -185,7 +187,7 @@ public interface IWebElement : ISearchContext
185187
/// of an IDL property of the element, either use the <see cref="GetAttribute(string)"/>
186188
/// method or the <see cref="GetDomProperty(string)"/> method.
187189
/// </remarks>
188-
string GetDomAttribute(string attributeName);
190+
string? GetDomAttribute(string attributeName);
189191

190192
/// <summary>
191193
/// Gets the value of a JavaScript property of this element.
@@ -194,7 +196,7 @@ public interface IWebElement : ISearchContext
194196
/// <returns>The JavaScript property's current value. Returns a <see langword="null"/> if the
195197
/// value is not set or the property does not exist.</returns>
196198
/// <exception cref="StaleElementReferenceException">Thrown when the target element is no longer valid in the document DOM.</exception>
197-
string GetDomProperty(string propertyName);
199+
string? GetDomProperty(string propertyName);
198200

199201
/// <summary>
200202
/// Gets the value of a CSS property of this element.

‎dotnet/src/webdriver/RelativeBy.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public override ReadOnlyCollection<IWebElement> FindElements(ISearchContext cont
108108
filterParameters["root"] = GetSerializableObject(this.root);
109109
filterParameters["filters"] = this.filters;
110110
parameters["relative"] = filterParameters;
111-
object rawElements = js.ExecuteScript(wrappedAtom, parameters);
111+
object? rawElements = js.ExecuteScript(wrappedAtom, parameters);
112112

113113
if (rawElements is ReadOnlyCollection<IWebElement> elements)
114114
{

‎dotnet/src/webdriver/ShadowRoot.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public IWebElement FindElement(By by)
9999
parameters.Add("value", by.Criteria);
100100

101101
Response commandResponse = this.driver.InternalExecute(DriverCommand.FindShadowChildElement, parameters);
102-
return this.driver.GetElementFromResponse(commandResponse);
102+
return this.driver.GetElementFromResponse(commandResponse)!;
103103
}
104104

105105
/// <summary>

‎dotnet/src/webdriver/TargetLocator.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public IWebDriver Window(string windowHandleOrName)
166166
foreach (string handle in this.driver.WindowHandles)
167167
{
168168
this.Window(handle);
169-
if (windowHandleOrName == this.driver.ExecuteScript("return window.name").ToString())
169+
if (windowHandleOrName == this.driver.ExecuteScript("return window.name")!.ToString())
170170
{
171171
return this.driver; // found by name
172172
}
@@ -223,7 +223,7 @@ public IWebDriver DefaultContent()
223223
public IWebElement ActiveElement()
224224
{
225225
Response response = this.driver.InternalExecute(DriverCommand.GetActiveElement, null);
226-
return this.driver.GetElementFromResponse(response);
226+
return this.driver.GetElementFromResponse(response)!;
227227
}
228228

229229
/// <summary>

‎dotnet/src/webdriver/WebDriver.cs

+32-34
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
using System.Globalization;
2929
using System.Threading.Tasks;
3030

31+
#nullable enable
32+
3133
namespace OpenQA.Selenium
3234
{
3335
/// <summary>
@@ -40,10 +42,10 @@ public class WebDriver : IWebDriver, ISearchContext, IJavaScriptExecutor, IFinds
4042
/// </summary>
4143
protected static readonly TimeSpan DefaultCommandTimeout = TimeSpan.FromSeconds(60);
4244
private IFileDetector fileDetector = new DefaultFileDetector();
43-
private NetworkManager network;
45+
private readonly NetworkManager network;
4446
private WebElementFactory elementFactory;
4547

46-
private List<string> registeredCommands = new List<string>();
48+
private readonly List<string> registeredCommands = new List<string>();
4749

4850
/// <summary>
4951
/// Initializes a new instance of the <see cref="WebDriver"/> class.
@@ -108,7 +110,7 @@ public string Url
108110
Response commandResponse = this.Execute(DriverCommand.GetCurrentUrl, null);
109111

110112
commandResponse.EnsureValueIsNotNull();
111-
return commandResponse.Value.ToString();
113+
return commandResponse.Value.ToString()!;
112114
}
113115

114116
set => new Navigator(this).GoToUrl(value);
@@ -122,13 +124,11 @@ public string Title
122124
get
123125
{
124126
Response commandResponse = this.Execute(DriverCommand.GetTitle, null);
125-
object returnedTitle = commandResponse.Value ?? string.Empty;
126127

127-
return returnedTitle.ToString();
128+
return commandResponse.Value?.ToString() ?? string.Empty;
128129
}
129130
}
130131

131-
132132
/// <summary>
133133
/// Gets the source of the page last loaded by the browser.
134134
/// </summary>
@@ -139,7 +139,7 @@ public string PageSource
139139
Response commandResponse = this.Execute(DriverCommand.GetPageSource, null);
140140

141141
commandResponse.EnsureValueIsNotNull();
142-
return commandResponse.Value.ToString();
142+
return commandResponse.Value.ToString()!;
143143
}
144144
}
145145

@@ -154,7 +154,7 @@ public string CurrentWindowHandle
154154
Response commandResponse = this.Execute(DriverCommand.GetCurrentWindowHandle, null);
155155

156156
commandResponse.EnsureValueIsNotNull();
157-
return commandResponse.Value.ToString();
157+
return commandResponse.Value.ToString()!;
158158
}
159159
}
160160

@@ -168,11 +168,11 @@ public ReadOnlyCollection<string> WindowHandles
168168
Response commandResponse = this.Execute(DriverCommand.GetWindowHandles, null);
169169

170170
commandResponse.EnsureValueIsNotNull();
171-
object[] handles = (object[])commandResponse.Value;
171+
object?[] handles = (object?[])commandResponse.Value;
172172
List<string> handleList = new List<string>(handles.Length);
173-
foreach (object handle in handles)
173+
foreach (object? handle in handles)
174174
{
175-
handleList.Add(handle.ToString());
175+
handleList.Add(handle!.ToString()!);
176176
}
177177

178178
return handleList.AsReadOnly();
@@ -184,8 +184,6 @@ public ReadOnlyCollection<string> WindowHandles
184184
/// </summary>
185185
public bool IsActionExecutor => true;
186186

187-
#nullable enable
188-
189187
/// <summary>
190188
/// Gets the <see cref="Selenium.SessionId"/> for the current session of this driver.
191189
/// </summary>
@@ -272,8 +270,6 @@ public void Dispose()
272270
return this.ExecuteScript(script.MakeExecutionScript(), args);
273271
}
274272

275-
#nullable restore
276-
277273
/// <summary>
278274
/// Finds the first element in the page that matches the <see cref="By"/> object
279275
/// </summary>
@@ -310,7 +306,7 @@ public virtual IWebElement FindElement(string mechanism, string value)
310306

311307
Response commandResponse = this.Execute(DriverCommand.FindElement, parameters);
312308

313-
return this.GetElementFromResponse(commandResponse);
309+
return this.GetElementFromResponse(commandResponse)!;
314310
}
315311

316312
/// <summary>
@@ -351,8 +347,6 @@ public virtual ReadOnlyCollection<IWebElement> FindElements(string mechanism, st
351347
return this.GetElementsFromResponse(commandResponse);
352348
}
353349

354-
#nullable enable
355-
356350
/// <summary>
357351
/// Gets a <see cref="Screenshot"/> object representing the image of the page on the screen.
358352
/// </summary>
@@ -527,14 +521,8 @@ internal bool RegisterDriverCommand(string commandName, [NotNullWhen(true)] Comm
527521
/// </summary>
528522
/// <param name="response">Response from the browser</param>
529523
/// <returns>Element from the page, or <see langword="null"/> if the response does not contain a dictionary.</returns>
530-
/// <exception cref="ArgumentNullException">If <paramref name="response"/> is <see langword="null"/>.</exception>
531524
internal IWebElement? GetElementFromResponse(Response response)
532525
{
533-
if (response == null)
534-
{
535-
throw new NoSuchElementException();
536-
}
537-
538526
if (response.Value is Dictionary<string, object?> elementDictionary)
539527
{
540528
return this.elementFactory.CreateElement(elementDictionary);
@@ -566,16 +554,18 @@ internal ReadOnlyCollection<IWebElement> GetElementsFromResponse(Response respon
566554
return toReturn.AsReadOnly();
567555
}
568556

569-
#nullable restore
570-
571557
/// <summary>
572558
/// Executes commands with the driver
573559
/// </summary>
574560
/// <param name="driverCommandToExecute">Command that needs executing</param>
575561
/// <param name="parameters">Parameters needed for the command</param>
576562
/// <returns>WebDriver Response</returns>
577563
/// <exception cref="ArgumentNullException">If <paramref name="driverCommandToExecute"/> is <see langword="null"/>.</exception>
578-
internal Response InternalExecute(string driverCommandToExecute, Dictionary<string, object> parameters)
564+
internal Response InternalExecute(string driverCommandToExecute, Dictionary<string,
565+
#nullable disable
566+
object
567+
#nullable enable
568+
>? parameters)
579569
{
580570
return Task.Run(() => this.InternalExecuteAsync(driverCommandToExecute, parameters)).GetAwaiter().GetResult();
581571
}
@@ -587,8 +577,11 @@ internal Response InternalExecute(string driverCommandToExecute, Dictionary<stri
587577
/// <param name="parameters">Parameters needed for the command</param>
588578
/// <returns>A task object representing the asynchronous operation</returns>
589579
/// <exception cref="ArgumentNullException">If <paramref name="driverCommandToExecute"/> is <see langword="null"/>.</exception>
590-
internal Task<Response> InternalExecuteAsync(string driverCommandToExecute,
591-
Dictionary<string, object> parameters)
580+
internal Task<Response> InternalExecuteAsync(string driverCommandToExecute, Dictionary<string,
581+
#nullable disable
582+
object
583+
#nullable enable
584+
>? parameters)
592585
{
593586
return this.ExecuteAsync(driverCommandToExecute, parameters);
594587
}
@@ -600,8 +593,11 @@ internal Task<Response> InternalExecuteAsync(string driverCommandToExecute,
600593
/// <param name="parameters">A <see cref="Dictionary{K, V}"/> containing the names and values of the parameters of the command.</param>
601594
/// <returns>A <see cref="Response"/> containing information about the success or failure of the command and any data returned by the command.</returns>
602595
/// <exception cref="ArgumentNullException">If <paramref name="driverCommandToExecute"/> is <see langword="null"/>.</exception>
603-
protected virtual Response Execute(string driverCommandToExecute,
604-
Dictionary<string, object> parameters)
596+
protected virtual Response Execute(string driverCommandToExecute, Dictionary<string,
597+
#nullable disable
598+
object
599+
#nullable enable
600+
>? parameters)
605601
{
606602
return Task.Run(() => this.ExecuteAsync(driverCommandToExecute, parameters)).GetAwaiter().GetResult();
607603
}
@@ -613,7 +609,11 @@ protected virtual Response Execute(string driverCommandToExecute,
613609
/// <param name="parameters">A <see cref="Dictionary{K, V}"/> containing the names and values of the parameters of the command.</param>
614610
/// <returns>A <see cref="Response"/> containing information about the success or failure of the command and any data returned by the command.</returns>
615611
/// <exception cref="ArgumentNullException">If <paramref name="driverCommandToExecute"/> is <see langword="null"/>.</exception>
616-
protected virtual async Task<Response> ExecuteAsync(string driverCommandToExecute, Dictionary<string, object> parameters)
612+
protected virtual async Task<Response> ExecuteAsync(string driverCommandToExecute, Dictionary<string,
613+
#nullable disable
614+
object
615+
#nullable enable
616+
>? parameters)
617617
{
618618
Command commandToExecute = new Command(SessionId, driverCommandToExecute, parameters);
619619

@@ -702,8 +702,6 @@ protected virtual Dictionary<string, object> GetCapabilitiesDictionary(ICapabili
702702
return capabilitiesDictionary;
703703
}
704704

705-
#nullable enable
706-
707705
/// <summary>
708706
/// Registers a command to be executed with this driver instance as an internally known driver command.
709707
/// </summary>

‎dotnet/src/webdriver/WebElement.cs

+9-17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
using System.IO.Compression;
2929
using System.Linq;
3030

31+
#nullable enable
32+
3133
namespace OpenQA.Selenium
3234
{
3335
/// <summary>
@@ -40,8 +42,6 @@ public class WebElement : IWebElement, IFindsElement, IWrapsDriver, ILocatable,
4042
/// </summary>
4143
public const string ElementReferencePropertyName = "element-6066-11e4-a52e-4f735466cecf";
4244

43-
#nullable enable
44-
4545
private readonly WebDriver driver;
4646

4747
/// <summary>
@@ -327,8 +327,6 @@ public virtual void Click()
327327
this.Execute(DriverCommand.ClickElement, parameters);
328328
}
329329

330-
#nullable restore
331-
332330
/// <summary>
333331
/// Finds the first <see cref="IWebElement"/> using the given method.
334332
/// </summary>
@@ -346,8 +344,6 @@ public virtual IWebElement FindElement(By by)
346344
return by.FindElement(this);
347345
}
348346

349-
#nullable enable
350-
351347
/// <summary>
352348
/// Finds a child element matching the given mechanism and value.
353349
/// </summary>
@@ -363,11 +359,9 @@ public virtual IWebElement FindElement(string mechanism, string value)
363359

364360
Response commandResponse = this.Execute(DriverCommand.FindChildElement, parameters);
365361

366-
return this.driver.GetElementFromResponse(commandResponse);
362+
return this.driver.GetElementFromResponse(commandResponse)!;
367363
}
368364

369-
#nullable restore
370-
371365
/// <summary>
372366
/// Finds all <see cref="IWebElement">IWebElements</see> within the current context
373367
/// using the given mechanism.
@@ -385,8 +379,6 @@ public virtual ReadOnlyCollection<IWebElement> FindElements(By by)
385379
return by.FindElements(this);
386380
}
387381

388-
#nullable enable
389-
390382
/// <summary>
391383
/// Finds all child elements matching the given mechanism and value.
392384
/// </summary>
@@ -701,24 +693,24 @@ Dictionary<string, object> IWebDriverObjectReference.ToDictionary()
701693
return elementDictionary;
702694
}
703695

704-
#nullable restore
705-
706696
/// <summary>
707697
/// Executes a command on this element using the specified parameters.
708698
/// </summary>
709699
/// <param name="commandToExecute">The <see cref="DriverCommand"/> to execute against this element.</param>
710700
/// <param name="parameters">A <see cref="Dictionary{K, V}"/> containing names and values of the parameters for the command.</param>
711701
/// <returns>The <see cref="Response"/> object containing the result of the command execution.</returns>
712-
protected virtual Response Execute(string commandToExecute, Dictionary<string, object> parameters)
702+
protected virtual Response Execute(string commandToExecute, Dictionary<string,
703+
#nullable disable
704+
object
705+
#nullable enable
706+
>? parameters)
713707
{
714708
return this.driver.InternalExecute(commandToExecute, parameters);
715709
}
716710

717-
#nullable enable
718-
719711
private static string GetAtom(string atomResourceName)
720712
{
721-
string atom = string.Empty;
713+
string atom;
722714
using (Stream atomStream = ResourceUtilities.GetResourceStream(atomResourceName, atomResourceName))
723715
{
724716
using (StreamReader atomReader = new StreamReader(atomStream))

‎dotnet/src/webdriver/WebElementFactory.cs

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public WebElementFactory(WebDriver parentDriver)
4949
/// </summary>
5050
/// <param name="elementDictionary">The dictionary containing the element reference.</param>
5151
/// <returns>A <see cref="WebElement"/> containing the information from the specified dictionary.</returns>
52+
/// <exception cref="ArgumentNullException">If <paramref name="elementDictionary"/> is <see langword="null"/>.</exception>
53+
/// <exception cref="ArgumentException">If the dictionary does not contain the element reference property name.</exception>
54+
/// <exception cref="InvalidOperationException">If the element property is <see langword="null"/> or <see cref="string.Empty"/>.</exception>
5255
public virtual WebElement CreateElement(Dictionary<string, object?> elementDictionary)
5356
{
5457
string elementId = this.GetElementId(elementDictionary);

0 commit comments

Comments
 (0)
Please sign in to comment.