Skip to content

Conversation

@nvborisenko
Copy link
Member

This change improves type safety and better reflects scenarios where dictionary values may be null.

💥 What does this PR do?

Enable nullability for driver.Execute.

🔄 Types of changes

  • Cleanup (formatting, renaming)

Copilot AI review requested due to automatic review settings February 11, 2026 23:43
@selenium-ci selenium-ci added the C-dotnet .NET Bindings label Feb 11, 2026
@qodo-code-review
Copy link
Contributor

PR Type

Enhancement


Description

  • Enable nullable dictionary values in driver command execution

  • Update Dictionary<string, object> to Dictionary<string, object?> across codebase

  • Improve type safety for parameters passed to driver.Execute methods

  • Simplify nullable annotation syntax by removing pragma directives


File Walkthrough

Relevant files
Enhancement
16 files
Alert.cs
Enable nullable values in alert parameters dictionary       
+1/-1     
ChromiumDriver.cs
Enable nullable values in Chromium command parameters       
+10/-10 
CookieJar.cs
Enable nullable values in cookie operation parameters       
+3/-3     
FirefoxDriver.cs
Enable nullable values in Firefox command parameters         
+3/-3     
ICustomDriverCommandExecutor.cs
Update interface signature for nullable parameter values 
+1/-1     
Logs.cs
Enable nullable values in log retrieval parameters             
+1/-1     
Navigator.cs
Enable nullable values in navigation parameters                   
+1/-1     
RemoteWebDriver.cs
Enable nullable values and simplify nullable syntax in Execute methods
+1/-1     
SafariDriver.cs
Enable nullable values in Safari permission parameters     
+1/-1     
ShadowRoot.cs
Enable nullable values in shadow root search parameters   
+2/-2     
TargetLocator.cs
Enable nullable values in frame and window switching parameters
+5/-5     
Timeouts.cs
Enable nullable values in timeout configuration parameters
+1/-1     
Credential.cs
Enable nullable values in credential serialization dictionary
+2/-2     
VirtualAuthenticatorOptions.cs
Enable nullable values in authenticator options dictionary
+2/-2     
WebDriver.cs
Enable nullable values and simplify nullable syntax throughout
+14/-22 
Window.cs
Enable nullable values in window position and size parameters
+2/-2     

@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
No audit logging shown: The diff primarily changes parameter dictionary nullability and does not show whether any
critical actions are audited with user/context, so audit-trail compliance cannot be
verified from the provided changes.

Referred Code
protected internal virtual Response Execute(string driverCommandToExecute, Dictionary<string, object?>? parameters)
{
    return Task.Run(() => this.ExecuteAsync(driverCommandToExecute, parameters)).GetAwaiter().GetResult();
}

/// <summary>
/// Executes a command with this driver.
/// </summary>
/// <param name="driverCommandToExecute">A <see cref="DriverCommand"/> value representing the command to execute.</param>
/// <param name="parameters">A <see cref="Dictionary{K, V}"/> containing the names and values of the parameters of the command.</param>
/// <returns>A <see cref="Response"/> containing information about the success or failure of the command and any data returned by the command.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="driverCommandToExecute"/> is <see langword="null"/>.</exception>
protected internal virtual async Task<Response> ExecuteAsync(string driverCommandToExecute, Dictionary<string, object?>? parameters)
{
    Command commandToExecute = new Command(SessionId, driverCommandToExecute, parameters);

    Response commandResponse = await this.CommandExecutor.ExecuteAsync(commandToExecute).ConfigureAwait(false);

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Nullable parameter values: The PR expands multiple command parameter dictionaries to Dictionary<string,
object?>, and without seeing downstream serialization/command-executor behavior it is
not verifiable whether null values are safely handled/validated before being sent
externally.

Referred Code
public object? ExecuteCdpCommand(string commandName, Dictionary<string, object?> commandParameters)
{
    if (commandName == null)
    {
        throw new ArgumentNullException(nameof(commandName), "commandName must not be null");
    }

    Dictionary<string, object?> parameters = new Dictionary<string, object?>();
    parameters["cmd"] = commandName;
    parameters["params"] = commandParameters;
    Response response = this.Execute(ExecuteCdp, parameters);
    return response.Value;

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Filter out null parameters before sending

In the Execute method, filter out any parameters with null values from the
parameters dictionary before dispatching the command to prevent potential issues
with remote endpoints.

dotnet/src/webdriver/WebDriver.cs [561-564]

 protected internal virtual Response Execute(string driverCommandToExecute, Dictionary<string, object?>? parameters)
 {
+    if (parameters != null)
+    {
+        parameters = parameters
+          .Where(kv => kv.Value is not null)
+          .ToDictionary(kv => kv.Key, kv => kv.Value);
+    }
     return Task.Run(() => this.ExecuteAsync(driverCommandToExecute, parameters)).GetAwaiter().GetResult();
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a potential issue where null values in the parameters dictionary might cause problems with remote endpoints and proposes a valid improvement by filtering them out.

Medium
General
Omit null option entries

In the ToDictionary method, conditionally add protocol and transport to the
dictionary only if they are not null to avoid sending null values.

dotnet/src/webdriver/VirtualAuth/VirtualAuthenticatorOptions.cs [173-185]

 public Dictionary<string, object?> ToDictionary()
 {
     Dictionary<string, object?> toReturn = new Dictionary<string, object?>();
-
-    toReturn["protocol"] = this.protocol;
-    toReturn["transport"] = this.transport;
-    toReturn["hasResidentKey"] = this.hasResidentKey;
+    if (this.protocol    is not null) toReturn["protocol"]           = this.protocol;
+    if (this.transport   is not null) toReturn["transport"]          = this.transport;
+    toReturn["hasResidentKey"]   = this.hasResidentKey;
     toReturn["hasUserVerification"] = this.hasUserVerification;
     toReturn["isUserConsenting"] = this.isUserConsenting;
-    toReturn["isUserVerified"] = this.isUserVerified;
-
+    toReturn["isUserVerified"]   = this.isUserVerified;
     return toReturn;
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that sending null values for optional protocol fields can be problematic and proposes a good practice of omitting them from the dictionary, which improves robustness.

Medium
  • More

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the .NET WebDriver command-parameter dictionaries to allow nullable values, aligning the parameter types with scenarios where JSON payloads may legitimately include null.

Changes:

  • Switches many command parameters dictionaries from Dictionary<string, object> to Dictionary<string, object?>.
  • Updates WebDriver.Execute(...) / ExecuteAsync(...) to accept nullable dictionary values (object?) and nullable parameter dictionaries.
  • Adjusts several public APIs (ExecuteCustomDriverCommand, ExecuteCdpCommand, and ToDictionary() methods) to reflect nullable dictionary values.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
dotnet/src/webdriver/Window.cs Uses Dictionary<string, object?> for window rect command parameters.
dotnet/src/webdriver/WebDriver.cs Updates Execute/ExecuteAsync and various call sites to nullable dictionary values.
dotnet/src/webdriver/VirtualAuth/VirtualAuthenticatorOptions.cs Changes ToDictionary() to return Dictionary<string, object?>.
dotnet/src/webdriver/VirtualAuth/Credential.cs Changes ToDictionary() to return Dictionary<string, object?>.
dotnet/src/webdriver/Timeouts.cs Uses Dictionary<string, object?> for timeout command parameters.
dotnet/src/webdriver/TargetLocator.cs Uses Dictionary<string, object?> for switch-to frame/window command parameters.
dotnet/src/webdriver/ShadowRoot.cs Uses Dictionary<string, object?> for shadow root find-element(s) parameters.
dotnet/src/webdriver/Safari/SafariDriver.cs Uses Dictionary<string, object?> for permissions command parameters.
dotnet/src/webdriver/Remote/RemoteWebDriver.cs Uses Dictionary<string, object?> for download command parameters.
dotnet/src/webdriver/Navigator.cs Uses Dictionary<string, object?> for navigation command parameters.
dotnet/src/webdriver/Logs.cs Uses Dictionary<string, object?> for log retrieval parameters.
dotnet/src/webdriver/ICustomDriverCommandExecutor.cs Updates public interface method to accept Dictionary<string, object?>.
dotnet/src/webdriver/Firefox/FirefoxDriver.cs Uses Dictionary<string, object?> for several Firefox custom commands.
dotnet/src/webdriver/CookieJar.cs Uses Dictionary<string, object?> for cookie commands (and empty parameter dictionaries).
dotnet/src/webdriver/Chromium/ChromiumDriver.cs Updates CDP command APIs and parameters to object? values.
dotnet/src/webdriver/Alert.cs Uses Dictionary<string, object?> for alert text parameters.

@nvborisenko nvborisenko merged commit 303f43a into SeleniumHQ:trunk Feb 12, 2026
28 checks passed
@nvborisenko nvborisenko deleted the dotnet-nullability-execute branch February 12, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants