@@ -40,6 +40,8 @@ public class WebElement : IWebElement, IFindsElement, IWrapsDriver, ILocatable,
4040 /// </summary>
4141 public const string ElementReferencePropertyName = "element-6066-11e4-a52e-4f735466cecf" ;
4242
43+ #nullable enable
44+
4345 private readonly WebDriver driver ;
4446
4547 /// <summary>
@@ -77,7 +79,8 @@ public virtual string TagName
7779
7880 Response commandResponse = this . Execute ( DriverCommand . GetElementTagName , parameters ) ;
7981
80- return commandResponse . Value . ToString ( ) ;
82+ commandResponse . EnsureValueIsNotNull ( ) ;
83+ return commandResponse . Value . ToString ( ) ! ;
8184 }
8285 }
8386
@@ -95,7 +98,8 @@ public virtual string Text
9598
9699 Response commandResponse = this . Execute ( DriverCommand . GetElementText , parameters ) ;
97100
98- return commandResponse . Value . ToString ( ) ;
101+ commandResponse . EnsureValueIsNotNull ( ) ;
102+ return commandResponse . Value . ToString ( ) ! ;
99103 }
100104 }
101105
@@ -151,7 +155,11 @@ public virtual Point Location
151155
152156 Response commandResponse = this . Execute ( DriverCommand . GetElementRect , parameters ) ;
153157
154- Dictionary < string , object > rawPoint = ( Dictionary < string , object > ) commandResponse . Value ;
158+ if ( commandResponse . Value is not Dictionary < string , object ? > rawPoint )
159+ {
160+ throw new WebDriverException ( $ "GetElementRect command was successful, but response was not an object: { commandResponse . Value } ") ;
161+ }
162+
155163 int x = Convert . ToInt32 ( rawPoint [ "x" ] , CultureInfo . InvariantCulture ) ;
156164 int y = Convert . ToInt32 ( rawPoint [ "y" ] , CultureInfo . InvariantCulture ) ;
157165 return new Point ( x , y ) ;
@@ -171,7 +179,11 @@ public virtual Size Size
171179
172180 Response commandResponse = this . Execute ( DriverCommand . GetElementRect , parameters ) ;
173181
174- Dictionary < string , object > rawSize = ( Dictionary < string , object > ) commandResponse . Value ;
182+ if ( commandResponse . Value is not Dictionary < string , object ? > rawSize )
183+ {
184+ throw new WebDriverException ( $ "GetElementRect command was successful, but response was not an object: { commandResponse . Value } ") ;
185+ }
186+
175187 int width = Convert . ToInt32 ( rawSize [ "width" ] , CultureInfo . InvariantCulture ) ;
176188 int height = Convert . ToInt32 ( rawSize [ "height" ] , CultureInfo . InvariantCulture ) ;
177189 return new Size ( width , height ) ;
@@ -207,7 +219,7 @@ public virtual Point LocationOnScreenOnceScrolledIntoView
207219 {
208220 get
209221 {
210- object scriptResponse = this . driver . ExecuteScript ( "var rect = arguments[0].getBoundingClientRect(); return {'x': rect.left, 'y': rect.top};" , this ) ;
222+ object scriptResponse = this . driver . ExecuteScript ( "var rect = arguments[0].getBoundingClientRect(); return {'x': rect.left, 'y': rect.top};" , this ) ! ;
211223
212224 Dictionary < string , object > rawLocation = ( Dictionary < string , object > ) scriptResponse ;
213225
@@ -229,7 +241,8 @@ public virtual string ComputedAccessibleLabel
229241
230242 Response commandResponse = this . Execute ( DriverCommand . GetComputedAccessibleLabel , parameters ) ;
231243
232- return commandResponse . Value . ToString ( ) ;
244+ commandResponse . EnsureValueIsNotNull ( ) ;
245+ return commandResponse . Value . ToString ( ) ! ;
233246 }
234247 }
235248
@@ -240,16 +253,18 @@ public virtual string ComputedAccessibleRole
240253 {
241254 get
242255 {
243- // TODO: Returning this as a string is incorrect. The W3C WebDriver Specification
244- // needs to be updated to more thoroughly document the structure of what is returned
245- // by this command. Once that is done, a type-safe class will be created, and will
246- // be returned by this property.
247256 Dictionary < string , object > parameters = new Dictionary < string , object > ( ) ;
248257 parameters . Add ( "id" , this . Id ) ;
249258
250259 Response commandResponse = this . Execute ( DriverCommand . GetComputedAccessibleRole , parameters ) ;
251260
261+ #nullable disable
262+ // TODO: Returning this as a string is incorrect. The W3C WebDriver Specification
263+ // needs to be updated to more thoroughly document the structure of what is returned
264+ // by this command. Once that is done, a type-safe class will be created, and will
265+ // be returned by this property.
252266 return commandResponse . Value . ToString ( ) ;
267+ #nullable enable
253268 }
254269 }
255270
@@ -312,11 +327,14 @@ public virtual void Click()
312327 this . Execute ( DriverCommand . ClickElement , parameters ) ;
313328 }
314329
330+ #nullable restore
331+
315332 /// <summary>
316333 /// Finds the first <see cref="IWebElement"/> using the given method.
317334 /// </summary>
318335 /// <param name="by">The locating mechanism to use.</param>
319336 /// <returns>The first matching <see cref="IWebElement"/> on the current context.</returns>
337+ /// <exception cref="ArgumentNullException">If <paramref name="by"/> is <see langword="null"/>.</exception>
320338 /// <exception cref="NoSuchElementException">If no element matches the criteria.</exception>
321339 public virtual IWebElement FindElement ( By by )
322340 {
@@ -328,6 +346,8 @@ public virtual IWebElement FindElement(By by)
328346 return by . FindElement ( this ) ;
329347 }
330348
349+ #nullable enable
350+
331351 /// <summary>
332352 /// Finds a child element matching the given mechanism and value.
333353 /// </summary>
@@ -346,6 +366,8 @@ public virtual IWebElement FindElement(string mechanism, string value)
346366 return this . driver . GetElementFromResponse ( commandResponse ) ;
347367 }
348368
369+ #nullable restore
370+
349371 /// <summary>
350372 /// Finds all <see cref="IWebElement">IWebElements</see> within the current context
351373 /// using the given mechanism.
@@ -363,6 +385,8 @@ public virtual ReadOnlyCollection<IWebElement> FindElements(By by)
363385 return by . FindElements ( this ) ;
364386 }
365387
388+ #nullable enable
389+
366390 /// <summary>
367391 /// Finds all child elements matching the given mechanism and value.
368392 /// </summary>
@@ -418,15 +442,14 @@ public virtual ReadOnlyCollection<IWebElement> FindElements(string mechanism, st
418442 /// via JavaScript.
419443 /// </remarks>
420444 /// <exception cref="StaleElementReferenceException">Thrown when the target element is no longer valid in the document DOM.</exception>
421- public virtual string GetAttribute ( string attributeName )
445+ public virtual string ? GetAttribute ( string attributeName )
422446 {
423- Response commandResponse = null ;
424- string attributeValue = string . Empty ;
425447 Dictionary < string , object > parameters = new Dictionary < string , object > ( ) ;
426448 string atom = GetAtom ( "get-attribute.js" ) ;
427449 parameters . Add ( "script" , atom ) ;
428450 parameters . Add ( "args" , new object [ ] { ( ( IWebDriverObjectReference ) this ) . ToDictionary ( ) , attributeName } ) ;
429- commandResponse = this . Execute ( DriverCommand . ExecuteScript , parameters ) ;
451+
452+ Response commandResponse = Execute ( DriverCommand . ExecuteScript , parameters ) ;
430453
431454
432455 // Normalize string values of boolean results as lowercase.
@@ -451,7 +474,7 @@ public virtual string GetAttribute(string attributeName)
451474 /// of an IDL property of the element, either use the <see cref="GetAttribute(string)"/>
452475 /// method or the <see cref="GetDomProperty(string)"/> method.
453476 /// </remarks>
454- public virtual string GetDomAttribute ( string attributeName )
477+ public virtual string ? GetDomAttribute ( string attributeName )
455478 {
456479 Dictionary < string , object > parameters = new Dictionary < string , object > ( ) ;
457480 parameters . Add ( "id" , this . Id ) ;
@@ -469,7 +492,7 @@ public virtual string GetDomAttribute(string attributeName)
469492 /// <returns>The JavaScript property's current value. Returns a <see langword="null"/> if the
470493 /// value is not set or the property does not exist.</returns>
471494 /// <exception cref="StaleElementReferenceException">Thrown when the target element is no longer valid in the document DOM.</exception>
472- public virtual string GetDomProperty ( string propertyName )
495+ public virtual string ? GetDomProperty ( string propertyName )
473496 {
474497 Dictionary < string , object > parameters = new Dictionary < string , object > ( ) ;
475498 parameters . Add ( "id" , this . Id ) ;
@@ -492,12 +515,12 @@ public virtual ISearchContext GetShadowRoot()
492515 parameters . Add ( "id" , this . Id ) ;
493516
494517 Response commandResponse = this . Execute ( DriverCommand . GetElementShadowRoot , parameters ) ;
495- if ( commandResponse . Value is not Dictionary < string , object > shadowRootDictionary )
518+ if ( commandResponse . Value is not Dictionary < string , object ? > shadowRootDictionary )
496519 {
497520 throw new WebDriverException ( "Get shadow root command succeeded, but response value does not represent a shadow root." ) ;
498521 }
499522
500- if ( ! ShadowRoot . TryCreate ( this . driver , shadowRootDictionary , out ShadowRoot shadowRoot ) )
523+ if ( ! ShadowRoot . TryCreate ( this . driver , shadowRootDictionary , out ShadowRoot ? shadowRoot ) )
501524 {
502525 throw new WebDriverException ( "Get shadow root command succeeded, but response value does not have a shadow root key value." ) ;
503526 }
@@ -523,7 +546,9 @@ public virtual string GetCssValue(string propertyName)
523546 parameters . Add ( "name" , propertyName ) ;
524547
525548 Response commandResponse = this . Execute ( DriverCommand . GetElementValueOfCssProperty , parameters ) ;
526- return commandResponse . Value . ToString ( ) ;
549+
550+ commandResponse . EnsureValueIsNotNull ( ) ;
551+ return commandResponse . Value . ToString ( ) ! ;
527552 }
528553
529554 /// <summary>
@@ -537,7 +562,9 @@ public virtual Screenshot GetScreenshot()
537562
538563 // Get the screenshot as base64.
539564 Response screenshotResponse = this . Execute ( DriverCommand . ElementScreenshot , parameters ) ;
540- string base64 = screenshotResponse . Value . ToString ( ) ;
565+
566+ screenshotResponse . EnsureValueIsNotNull ( ) ;
567+ string base64 = screenshotResponse . Value . ToString ( ) ! ;
541568
542569 // ... and convert it.
543570 return new Screenshot ( base64 ) ;
@@ -595,7 +622,7 @@ public virtual void SendKeys(string text)
595622 /// <exception cref="StaleElementReferenceException">Thrown when the target element is no longer valid in the document DOM.</exception>
596623 public virtual void Submit ( )
597624 {
598- string elementType = this . GetAttribute ( "type" ) ;
625+ string ? elementType = this . GetAttribute ( "type" ) ;
599626 if ( elementType != null && elementType == "submit" )
600627 {
601628 this . Click ( ) ;
@@ -639,7 +666,7 @@ public override int GetHashCode()
639666 /// </summary>
640667 /// <param name="obj">Object to compare against</param>
641668 /// <returns>A boolean if it is equal or not</returns>
642- public override bool Equals ( object obj )
669+ public override bool Equals ( object ? obj )
643670 {
644671 if ( obj is not IWebElement other )
645672 {
@@ -674,6 +701,8 @@ Dictionary<string, object> IWebDriverObjectReference.ToDictionary()
674701 return elementDictionary ;
675702 }
676703
704+ #nullable restore
705+
677706 /// <summary>
678707 /// Executes a command on this element using the specified parameters.
679708 /// </summary>
@@ -685,6 +714,8 @@ protected virtual Response Execute(string commandToExecute, Dictionary<string, o
685714 return this . driver . InternalExecute ( commandToExecute , parameters ) ;
686715 }
687716
717+ #nullable enable
718+
688719 private static string GetAtom ( string atomResourceName )
689720 {
690721 string atom = string . Empty ;
@@ -719,7 +750,9 @@ private string UploadFile(string localFile)
719750 Dictionary < string , object > parameters = new Dictionary < string , object > ( ) ;
720751 parameters . Add ( "file" , base64zip ) ;
721752 Response response = this . Execute ( DriverCommand . UploadFile , parameters ) ;
722- return response . Value . ToString ( ) ;
753+
754+ response . EnsureValueIsNotNull ( ) ;
755+ return response . Value . ToString ( ) ! ;
723756 }
724757 catch ( IOException e )
725758 {
0 commit comments