Skip to content

Conversation

nvborisenko
Copy link
Member

@nvborisenko nvborisenko commented Aug 15, 2025

User description

Simplify type naming of internal command parameters

💥 What does this PR do?

Rename internal classes to see less code, aligned with specification type names.

🔄 Types of changes

  • Cleanup (formatting, renaming)

PR Type

Other


Description

  • Rename internal command parameter classes for brevity

  • Remove "Command" prefix from parameter type names

  • Simplify base class names from CommandOptions to Options

  • Update all BiDi module command implementations consistently


Diagram Walkthrough

flowchart LR A["CommandParameters"] --> B["Parameters"] C["CommandOptions"] --> D["Options"] E["*CommandParameters"] --> F["*Parameters"] 
Loading

File Walkthrough

Relevant files
Formatting
52 files
BrowserModule.cs
Update parameter type references                                                 
+2/-2     
CloseCommand.cs
Rename base classes                                                                           
+2/-2     
CreateUserContextCommand.cs
Rename parameter and options classes                                         
+4/-4     
GetClientWindowsCommand.cs
Update base class names                                                                   
+2/-2     
GetUserContextsCommand.cs
Update base class names                                                                   
+2/-2     
RemoveUserContextCommand.cs
Rename parameter and options classes                                         
+4/-4     
ActivateCommand.cs
Rename parameter and options classes                                         
+4/-4     
BrowsingContextModule.cs
Update all parameter type references                                         
+12/-12 
CaptureScreenshotCommand.cs
Rename parameter and options classes                                         
+4/-4     
CloseCommand.cs
Rename parameter and options classes                                         
+4/-4     
CreateCommand.cs
Rename parameter and options classes                                         
+4/-4     
GetTreeCommand.cs
Rename parameter and options classes                                         
+4/-4     
HandleUserPromptCommand.cs
Rename parameter and options classes                                         
+4/-4     
LocateNodesCommand.cs
Rename parameter and options classes                                         
+4/-4     
NavigateCommand.cs
Rename parameter and options classes                                         
+4/-4     
PrintCommand.cs
Rename parameter and options classes                                         
+4/-4     
ReloadCommand.cs
Rename parameter and options classes                                         
+4/-4     
SetViewportCommand.cs
Rename parameter and options classes                                         
+4/-4     
TraverseHistoryCommand.cs
Rename parameter and options classes                                         
+4/-4     
Broker.cs
Update method parameter types                                                       
+2/-2     
Command.cs
Rename base parameter classes                                                       
+6/-6     
CommandOptions.cs
Rename class from CommandOptions to Options                           
+1/-1     
InputModule.cs
Update parameter type references                                                 
+3/-3     
PerformActionsCommand.cs
Rename parameter and options classes                                         
+4/-4     
ReleaseActionsCommand.cs
Rename parameter and options classes                                         
+4/-4     
SetFilesCommand.cs
Rename parameter and options classes                                         
+4/-4     
AddInterceptCommand.cs
Rename parameter and options classes                                         
+4/-4     
ContinueRequestCommand.cs
Rename parameter and options classes                                         
+4/-4     
ContinueResponseCommand.cs
Rename parameter and options classes                                         
+4/-4     
ContinueWithAuthCommand.cs
Update base class and options                                                       
+2/-2     
FailRequestCommand.cs
Rename parameter and options classes                                         
+4/-4     
NetworkModule.cs
Update all parameter type references                                         
+7/-7     
ProvideResponseCommand.cs
Rename parameter and options classes                                         
+4/-4     
RemoveInterceptCommand.cs
Rename parameter and options classes                                         
+4/-4     
SetCacheBehaviorCommand.cs
Rename parameter and options classes                                         
+4/-4     
AddPreloadScriptCommand.cs
Rename parameter and options classes                                         
+4/-4     
CallFunctionCommand.cs
Rename parameter and options classes                                         
+4/-4     
DisownCommand.cs
Rename parameter class                                                                     
+3/-3     
EvaluateCommand.cs
Rename parameter and options classes                                         
+4/-4     
GetRealmsCommand.cs
Rename parameter and options classes                                         
+4/-4     
RemovePreloadScriptCommand.cs
Rename parameter and options classes                                         
+4/-4     
ScriptModule.cs
Update parameter type references                                                 
+5/-5     
EndCommand.cs
Update base class names                                                                   
+2/-2     
NewCommand.cs
Rename parameter and options classes                                         
+4/-4     
SessionModule.cs
Update parameter type references                                                 
+4/-4     
StatusCommand.cs
Update base class names                                                                   
+2/-2     
SubscribeCommand.cs
Rename parameter and options classes                                         
+4/-4     
UnsubscribeCommand.cs
Rename parameter and options classes                                         
+9/-9     
DeleteCookiesCommand.cs
Rename parameter and options classes                                         
+4/-4     
GetCookiesCommand.cs
Rename parameter and options classes                                         
+4/-4     
SetCookieCommand.cs
Rename parameter and options classes                                         
+4/-4     
StorageModule.cs
Update parameter type references                                                 
+3/-3     

@selenium-ci selenium-ci added the C-dotnet .NET Bindings label Aug 15, 2025
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

API Break

The renaming of base types from CommandParameters to Parameters and CommandOptions to Options, as well as generic constraints and Empty static member changes, is a public API change for internal modules. Validate no external/public consumers rely on the old names or members and that all references across the codebase (including serialization expectations) are updated consistently.

internal abstract class Command<TParameters, TResult>(TParameters @params, string method) : Command(method, typeof(TResult)) where TParameters : Parameters where TResult : EmptyResult { [JsonPropertyOrder(2)] public TParameters Params { get; } = @params; } internal record Parameters { public static Parameters Empty { get; } = new Parameters(); }
Signature Change

ExecuteCommandAsync and its core overload now accept Options? instead of CommandOptions?. Ensure all call sites across the solution were updated and that there are no implicit/extension method conflicts. Also confirm XML docs and any public surface area expectations are maintained.

public async Task<TResult> ExecuteCommandAsync<TCommand, TResult>(TCommand command, Options? options) where TCommand : Command where TResult : EmptyResult { var result = await ExecuteCommandCoreAsync(command, options).ConfigureAwait(false); return (TResult)result; } private async Task<EmptyResult> ExecuteCommandCoreAsync<TCommand>(TCommand command, Options? options)
Nullability Semantics

The new parameter records are constructed with many options?.X values; confirm downstream serialization excludes nulls as before and that required fields (e.g., type, context, url) are still enforced by constructors to avoid sending malformed commands.

public async Task<NavigateResult> NavigateAsync(BrowsingContext context, string url, NavigateOptions? options = null) { var @params = new NavigateParameters(context, url, options?.Wait); return await Broker.ExecuteCommandAsync<NavigateCommand, NavigateResult>(new NavigateCommand(@params), options).ConfigureAwait(false); } public async Task<EmptyResult> ActivateAsync(BrowsingContext context, ActivateOptions? options = null) { var @params = new ActivateParameters(context); return await Broker.ExecuteCommandAsync<ActivateCommand, EmptyResult>(new ActivateCommand(@params), options).ConfigureAwait(false); } public async Task<LocateNodesResult> LocateNodesAsync(BrowsingContext context, Locator locator, LocateNodesOptions? options = null) { var @params = new LocateNodesParameters(context, locator, options?.MaxNodeCount, options?.SerializationOptions, options?.StartNodes); return await Broker.ExecuteCommandAsync<LocateNodesCommand, LocateNodesResult>(new LocateNodesCommand(@params), options).ConfigureAwait(false); } public async Task<CaptureScreenshotResult> CaptureScreenshotAsync(BrowsingContext context, CaptureScreenshotOptions? options = null) { var @params = new CaptureScreenshotParameters(context, options?.Origin, options?.Format, options?.Clip); return await Broker.ExecuteCommandAsync<CaptureScreenshotCommand, CaptureScreenshotResult>(new CaptureScreenshotCommand(@params), options).ConfigureAwait(false); } public async Task<EmptyResult> CloseAsync(BrowsingContext context, CloseOptions? options = null) { var @params = new CloseParameters(context, options?.PromptUnload); return await Broker.ExecuteCommandAsync<CloseCommand, EmptyResult>(new CloseCommand(@params), options).ConfigureAwait(false); } public async Task<TraverseHistoryResult> TraverseHistoryAsync(BrowsingContext context, int delta, TraverseHistoryOptions? options = null) { var @params = new TraverseHistoryParameters(context, delta); return await Broker.ExecuteCommandAsync<TraverseHistoryCommand, TraverseHistoryResult>(new TraverseHistoryCommand(@params), options).ConfigureAwait(false); } public async Task<NavigateResult> ReloadAsync(BrowsingContext context, ReloadOptions? options = null) { var @params = new ReloadParameters(context, options?.IgnoreCache, options?.Wait); return await Broker.ExecuteCommandAsync<ReloadCommand, NavigateResult>(new ReloadCommand(@params), options).ConfigureAwait(false); } public async Task<EmptyResult> SetViewportAsync(BrowsingContext context, SetViewportOptions? options = null) { var @params = new SetViewportParameters(context, options?.Viewport, options?.DevicePixelRatio); return await Broker.ExecuteCommandAsync<SetViewportCommand, EmptyResult>(new SetViewportCommand(@params), options).ConfigureAwait(false); } public async Task<GetTreeResult> GetTreeAsync(GetTreeOptions? options = null) { var @params = new GetTreeParameters(options?.MaxDepth, options?.Root); return await Broker.ExecuteCommandAsync<GetTreeCommand, GetTreeResult>(new GetTreeCommand(@params), options).ConfigureAwait(false); } public async Task<PrintResult> PrintAsync(BrowsingContext context, PrintOptions? options = null) { var @params = new PrintParameters(context, options?.Background, options?.Margin, options?.Orientation, options?.Page, options?.PageRanges, options?.Scale, options?.ShrinkToFit); return await Broker.ExecuteCommandAsync<PrintCommand, PrintResult>(new PrintCommand(@params), options).ConfigureAwait(false); } public async Task<EmptyResult> HandleUserPromptAsync(BrowsingContext context, HandleUserPromptOptions? options = null) { var @params = new HandleUserPromptParameters(context, options?.Accept, options?.UserText); return await Broker.ExecuteCommandAsync<HandleUserPromptCommand, EmptyResult>(new HandleUserPromptCommand(@params), options).ConfigureAwait(false);
Copy link
Contributor

qodo-merge-pro bot commented Aug 15, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Verify external API compatibility

This PR renames base types from CommandOptions/CommandParameters to
Options/Parameters and updates generic constraints across the BiDi layer. Ensure
there are no public or semi-public APIs (consumed outside this assembly) that
relied on the old types, and confirm binary/source compatibility for downstream
users. If any classes are public (e.g., options types exposed to SDK consumers),
provide type-forwarding or transitional shims to prevent breaking changes.

Examples:

dotnet/src/webdriver/BiDi/Communication/CommandOptions.cs [24-27]
public abstract class Options { public TimeSpan? Timeout { get; set; } }
dotnet/src/webdriver/BiDi/Browser/CloseCommand.cs [27]
public sealed class CloseOptions : Options;

Solution Walkthrough:

Before:

// Public API base class public abstract class CommandOptions { ... } // Public options class for consumers public sealed class CloseOptions : CommandOptions; // Method signature in public API public async Task<TResult> ExecuteCommandAsync<TCommand, TResult>(TCommand command, CommandOptions? options)

After:

// Public API base class is renamed, a breaking change public abstract class Options { ... } // Public options class now has a different base type public sealed class CloseOptions : Options; // Method signature in public API is changed public async Task<TResult> ExecuteCommandAsync<TCommand, TResult>(TCommand command, Options? options)
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a critical breaking change in the public API (CommandOptions renamed to Options), which contradicts the PR's description as a simple cleanup.

High
Possible issue
Preserve "params" JSON name

Ensure the JSON property name for the parameters remains "params" to match the
BiDi protocol. Without an explicit JsonPropertyName, serializer policies could
rename it and break compatibility. Add an attribute to lock the property name.

dotnet/src/webdriver/BiDi/Communication/Command.cs [43-49]

 internal abstract class Command<TParameters, TResult>(TParameters @params, string method) : Command(method, typeof(TResult)) where TParameters : Parameters where TResult : EmptyResult { [JsonPropertyOrder(2)] + [JsonPropertyName("params")] public TParameters Params { get; } = @params; }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This is a valid suggestion that improves robustness by explicitly enforcing the JSON property name params as required by the BiDi protocol, preventing potential issues from changes in serializer configurations.

Medium
Learned
best practice
Validate positive timeout values

Validate that Timeout (when set) is positive to avoid misconfiguration and
potential hangs or immediate timeouts. Add a setter guard or helper ensuring
non-negative and non-zero durations.

dotnet/src/webdriver/BiDi/Communication/CommandOptions.cs [24-27]

 public abstract class Options { - public TimeSpan? Timeout { get; set; } + private TimeSpan? _timeout; + public TimeSpan? Timeout + { + get => _timeout; + set + { + if (value is { } t && t <= TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(Timeout), "Timeout must be greater than zero."); + } + _timeout = value; + } + } }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add null checks and validation for parameters; validate option values such as timeouts to prevent invalid or negative configurations.

Low
General
Use readonly singleton instance

Make the empty singleton more allocation-friendly and thread-safe by using
'static readonly' and caching a single instance explicitly. Although
functionally similar, this avoids any edge cases with property initialization
order during serialization.

dotnet/src/webdriver/BiDi/Communication/Command.cs [51-54]

 internal record Parameters { - public static Parameters Empty { get; } = new Parameters(); + public static readonly Parameters Empty = new Parameters(); }
  • Apply / Chat
Suggestion importance[1-10]: 2

__

Why: The suggestion to change a static get-only property to a static readonly field is a minor stylistic preference with negligible performance or thread-safety impact in this context.

Low
  • Update
@nvborisenko
Copy link
Member Author

CI format failure is not relates to these changes, @cgoldberg please check 706495a

@nvborisenko nvborisenko merged commit 61b10bc into SeleniumHQ:trunk Aug 15, 2025
9 of 10 checks passed
@nvborisenko nvborisenko deleted the dotnet-bidi-commandparameters branch August 15, 2025 20:08
@cgoldberg
Copy link
Member

please check 706495a

I just fixed it it trunk. It was a whitespace change I couldn't see in the PR, and I got a little trigger happy with merging before CI ran :)

This was referenced Oct 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3 participants