Skip to content

[dotnet] [bidi] FileDialogOpened event in Input module#16934

Merged
nvborisenko merged 4 commits intoSeleniumHQ:trunkfrom
nvborisenko:bidi-file-dialog
Jan 18, 2026
Merged

[dotnet] [bidi] FileDialogOpened event in Input module#16934
nvborisenko merged 4 commits intoSeleniumHQ:trunkfrom
nvborisenko:bidi-file-dialog

Conversation

@nvborisenko
Copy link
Member

@nvborisenko nvborisenko commented Jan 17, 2026

User description

https://w3c.github.io/webdriver-bidi/#event-input-fileDialogOpened

💥 What does this PR do?

Implements new FileDialogOpened event.

🔄 Types of changes

  • New feature (non-breaking change which adds functionality and tests!)

PR Type

Enhancement


Description

  • Implements FileDialogOpened event in Input module per W3C WebDriver BiDi spec

  • Adds context-aware event subscription with async and sync handler support

  • Creates FileDialogInfo record to represent file dialog event data

  • Adds concrete SharedReference implementation for shared object references

  • Includes comprehensive test coverage for file dialog event listening


Diagram Walkthrough

flowchart LR
  A["InputModule"] -->|"subscribes to"| B["input.fileDialogOpened"]
  B -->|"emits"| C["FileDialogInfo"]
  C -->|"contains"| D["Context, Multiple, Element"]
  E["BrowsingContextInputModule"] -->|"wraps"| A
  E -->|"filters by"| F["Context"]
  G["Test"] -->|"verifies"| E
Loading

File Walkthrough

Relevant files
Enhancement
FileDialogInfo.cs
Create FileDialogInfo event data record                                   

dotnet/src/webdriver/BiDi/Input/FileDialogInfo.cs

  • New sealed record implementing file dialog event data structure
  • Contains browsing context, multiple flag, and optional element
    reference
  • Inherits from EventArgs for event handling compatibility
+23/-0   
InputModule.cs
Add file dialog event subscription methods                             

dotnet/src/webdriver/BiDi/Input/InputModule.cs

  • Adds two overloads of OnFileDialogOpenedAsync for async and sync
    handlers
  • Subscribes to "input.fileDialogOpened" event via Broker
  • Registers FileDialogInfo in JSON serializer context
  • Imports System namespace for Func and Action delegates
+12/-0   
BrowsingContextInputModule.cs
Add context-aware file dialog event handlers                         

dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextInputModule.cs

  • Adds two context-aware overloads of OnFileDialogOpenedAsync
  • Filters events to only trigger for matching browsing context
  • Supports both async and sync handler patterns
  • Imports System namespace for Func delegate
+23/-0   
IRemoteReference.cs
Implement SharedReference concrete class                                 

dotnet/src/webdriver/BiDi/Script/IRemoteReference.cs

  • Implements concrete SharedReference record class
  • Provides default implementation of ISharedReference interface
  • Includes mutable Handle property for reference management
+5/-0     
Tests
InputEventsTest.cs
Add FileDialogOpened event test coverage                                 

dotnet/test/common/BiDi/Input/InputEventsTest.cs

  • New test class for Input module events
  • Tests FileDialogOpened event subscription and event data
  • Verifies context matching, multiple flag, and element reference
  • Uses TaskCompletionSource for async event verification
+47/-0   

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 17, 2026

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: Comprehensive Audit Trails

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

Status: Passed

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

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: 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: Security-First Input Validation and Data Handling

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

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:
Null options risk: The new OnFileDialogOpenedAsync overloads call options.WithContext(context) without an
explicit null-guard, which may throw if options is null depending on WithContext
implementation.

Referred Code
public Task<Subscription> OnFileDialogOpenedAsync(Func<FileDialogInfo, Task> handler, ContextSubscriptionOptions? options = null)
{
    return inputModule.OnFileDialogOpenedAsync(async e =>
    {
        if (context.Equals(e.Context))
        {
            await handler(e).ConfigureAwait(false);
        }
    }, options.WithContext(context));
}

public Task<Subscription> OnFileDialogOpenedAsync(Action<FileDialogInfo> handler, ContextSubscriptionOptions? options = null)
{
    return inputModule.OnFileDialogOpenedAsync((e) =>
    {
        if (context.Equals(e.Context))
        {
            handler(e);
        }
    }, options.WithContext(context));
}

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

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

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 17, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix potential null reference exception

Fix a potential NullReferenceException by handling the case where the options
parameter is null. Initialize a new ContextSubscriptionOptions if options is not
provided before calling WithContext.

dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextInputModule.cs [44-64]

 public Task<Subscription> OnFileDialogOpenedAsync(Func<FileDialogInfo, Task> handler, ContextSubscriptionOptions? options = null)
 {
     return inputModule.OnFileDialogOpenedAsync(async e =>
     {
         if (context.Equals(e.Context))
         {
             await handler(e).ConfigureAwait(false);
         }
-    }, options.WithContext(context));
+    }, (options ?? new()).WithContext(context));
 }
 
 public Task<Subscription> OnFileDialogOpenedAsync(Action<FileDialogInfo> handler, ContextSubscriptionOptions? options = null)
 {
     return inputModule.OnFileDialogOpenedAsync((e) =>
     {
         if (context.Equals(e.Context))
         {
             handler(e);
         }
-    }, options.WithContext(context));
+    }, (options ?? new()).WithContext(context));
 }
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a NullReferenceException that will occur when options is null, as it is by default. This is a critical bug that would crash the newly added functionality, and the proposed fix is correct and idiomatic.

High
High-level
Expose interface instead of concrete class

To improve API consistency, the Element property in the new FileDialogInfo
record should be changed from the concrete SharedReference class to the
ISharedReference interface. This aligns with existing methods like
SetFilesAsync.

Examples:

dotnet/src/webdriver/BiDi/Input/FileDialogInfo.cs [22-23]
public sealed record FileDialogInfo(BrowsingContext.BrowsingContext Context, bool Multiple, Script.SharedReference? Element)
    : EventArgs;
dotnet/src/webdriver/BiDi/Input/InputModule.cs [47]
    public async Task<SetFilesResult> SetFilesAsync(BrowsingContext.BrowsingContext context, Script.ISharedReference element, IEnumerable<string> files, SetFilesOptions? options = null)

Solution Walkthrough:

Before:

// file: dotnet/src/webdriver/BiDi/Input/FileDialogInfo.cs

public sealed record FileDialogInfo(
    BrowsingContext.BrowsingContext Context, 
    bool Multiple, 
    Script.SharedReference? Element // Exposes concrete class
) : EventArgs;

After:

// file: dotnet/src/webdriver/BiDi/Input/FileDialogInfo.cs

public sealed record FileDialogInfo(
    BrowsingContext.BrowsingContext Context, 
    bool Multiple, 
    Script.ISharedReference? Element // Exposes interface for better design
) : EventArgs;
Suggestion importance[1-10]: 7

__

Why: This is a valid API design suggestion that correctly identifies an inconsistency; using the ISharedReference interface instead of the concrete SharedReference class improves API consistency and flexibility.

Medium
Learned
best practice
Validate event handler arguments

Validate handler is non-null before passing it into the broker to fail fast with
a clear exception.

dotnet/src/webdriver/BiDi/Input/InputModule.cs [54-62]

-public async Task<Subscription> OnFileDialogOpenedAsync(Func<FileDialogInfo, Task> handler, SubscriptionOptions? options = null)
+public Task<Subscription> OnFileDialogOpenedAsync(Func<FileDialogInfo, Task> handler, SubscriptionOptions? options = null)
 {
-    return await Broker.SubscribeAsync("input.fileDialogOpened", handler, options, _jsonContext.FileDialogInfo).ConfigureAwait(false);
+    ArgumentNullException.ThrowIfNull(handler);
+    return Broker.SubscribeAsync("input.fileDialogOpened", handler, options, _jsonContext.FileDialogInfo);
 }
 
-public async Task<Subscription> OnFileDialogOpenedAsync(Action<FileDialogInfo> handler, SubscriptionOptions? options = null)
+public Task<Subscription> OnFileDialogOpenedAsync(Action<FileDialogInfo> handler, SubscriptionOptions? options = null)
 {
-    return await Broker.SubscribeAsync("input.fileDialogOpened", handler, options, _jsonContext.FileDialogInfo).ConfigureAwait(false);
+    ArgumentNullException.ThrowIfNull(handler);
+    return Broker.SubscribeAsync("input.fileDialogOpened", handler, options, _jsonContext.FileDialogInfo);
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add explicit validation and null/availability guards at integration boundaries (e.g., event handlers/options) before use.

Low
  • Update

@nvborisenko nvborisenko merged commit 1fefb89 into SeleniumHQ:trunk Jan 18, 2026
12 checks passed
@nvborisenko nvborisenko deleted the bidi-file-dialog branch January 18, 2026 15:57
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