Skip to content

Commit 375dcea

Browse files
[dotnet] Annotate nullability on elements and WebDriver (#15352)
* [dotnet] Annotate nullability on elements and `WebDriver` * Fix null warnings
1 parent f6c1e8c commit 375dcea

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>

0 commit comments

Comments
 (0)