Skip to content

[dotnet] Make CI green again according to the 4.41 breaking changes#2588

Draft
nvborisenko wants to merge 11 commits into
SeleniumHQ:trunkfrom
nvborisenko:dotnet-4.41
Draft

[dotnet] Make CI green again according to the 4.41 breaking changes#2588
nvborisenko wants to merge 11 commits into
SeleniumHQ:trunkfrom
nvborisenko:dotnet-4.41

Conversation

@nvborisenko

@nvborisenko nvborisenko commented Feb 20, 2026

Copy link
Copy Markdown
Member

User description

Selenium v4.41 has small breaking changes for SeleniumManager and DriverFinder. Both have more robust public API.

Description

Motivation and Context

Actualize examples.

Types of changes

  • Change to the site (I have double-checked the Netlify deployment, and my changes look good)
  • Code example added (and I also added the example to all translated languages)
  • Improved translation
  • Added new translation (and I also added a notice to each document missing translation)

Checklist

  • I have read the contributing document.
  • I have used hugo to render the site/docs locally and I am sure it works.

PR Type

Enhancement


Description

  • Upgrade Selenium WebDriver NuGet packages from 4.38.0 to 4.41.0

  • Update DevTools API references from V142 to V145

  • Convert DriverFinder methods to async with new API

  • Add System.Threading.Tasks imports for async support


Diagram Walkthrough

flowchart LR
  A["Selenium 4.38.0"] -- "upgrade packages" --> B["Selenium 4.41.0"]
  C["DevTools V142"] -- "update API version" --> D["DevTools V145"]
  E["Sync DriverFinder methods"] -- "convert to async" --> F["Async DriverFinder methods"]
  B --> G["Updated Examples"]
  D --> G
  F --> G
Loading

File Walkthrough

Relevant files
Dependencies
SeleniumDocs.csproj
Upgrade Selenium NuGet packages to 4.41.0                               

examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

  • Updated Selenium.Support package from 4.38.0 to 4.41.0
  • Updated Selenium.WebDriver package from 4.38.0 to 4.41.0
+2/-2     
Enhancement
NetworkTest.cs
Update DevTools API from V142 to V145                                       

examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

  • Updated DevTools imports from V142 to V145
  • Updated GetVersionSpecificDomains calls to use V145 API
  • Updated EnableCommandSettings references to V145 namespace
+6/-6     
ChromeTest.cs
Convert Chrome browser location methods to async                 

examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

  • Added System.Threading.Tasks import for async support
  • Converted SetBrowserLocation() method to async Task
  • Converted GetChromeLocation() to GetChromeLocationAsync() with async
    implementation
  • Updated DriverFinder.GetBrowserPath() to GetBrowserPathAsync() with
    await
+5/-4     
EdgeTest.cs
Convert Edge browser location methods to async                     

examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

  • Added System.Threading.Tasks import for async support
  • Converted SetBrowserLocation() method to async Task
  • Converted GetEdgeLocation() to GetEdgeLocationAsync() with async
    implementation
  • Updated DriverFinder.GetBrowserPath() to GetBrowserPathAsync() with
    await
+5/-4     
FirefoxTest.cs
Convert Firefox browser location methods to async               

examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

  • Added System.Threading.Tasks import for async support
  • Converted SetBinary() method to async Task
  • Converted GetFirefoxLocation() to GetFirefoxLocationAsync() with async
    implementation
  • Updated DriverFinder.GetBrowserPath() to GetBrowserPathAsync() with
    await
+5/-4     
ServiceTest.cs
Convert driver location method to async                                   

examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

  • Added System.Threading.Tasks import for async support
  • Converted DriverLocation() method to async Task
  • Converted GetDriverLocation() to GetDriverLocationAsync() with async
    implementation
  • Updated DriverFinder.GetDriverPath() to GetDriverPathAsync() with
    await
+5/-4     
LoggingTest.cs
Update imports for Selenium 4.41 API                                         

examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

  • Removed unused OpenQA.Selenium import
  • Added OpenQA.Selenium.Manager import for new API
+1/-1     

@netlify

netlify Bot commented Feb 20, 2026

Copy link
Copy Markdown

👷 Deploy request for selenium-dev pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit e96e911

@qodo-code-review

qodo-code-review Bot commented Feb 20, 2026

Copy link
Copy Markdown
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: 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: 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: 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

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

@qodo-code-review

qodo-code-review Bot commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to 4e2f512

CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure custom tests run reliably

Revert the DriverLocation test method to be synchronous (void) and use
.GetAwaiter().GetResult() to block on the async call, ensuring compatibility
with the TestMethodCustom attribute.

examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs [19-27]

 [TestMethodCustom]
 [EnabledOnOs("OSX")]
-public async Task DriverLocation()
+public void DriverLocation()
 {
     var options = GetLatestChromeOptions();
-    var service = ChromeDriverService.CreateDefaultService(await GetDriverLocationAsync(options));
+    var driverLocation = GetDriverLocationAsync(options).GetAwaiter().GetResult();
+    var service = ChromeDriverService.CreateDefaultService(driverLocation);
 
     driver = new ChromeDriver(service, options);
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a potential issue where a custom test attribute TestMethodCustom may not support async Task, proposing a robust synchronous blocking pattern to prevent unreliable test execution.

Medium
General
Prevent temp directory leaks

Wrap the logic in SetBrowserLocation in a try/catch block to ensure the
temporary userDataDir directory is deleted if an exception occurs during driver
initialization, preventing resource leaks.

examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs [46-59]

 [TestMethod]
 public async Task SetBrowserLocation()
 {
     string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
     Directory.CreateDirectory(userDataDir);
-    var options = new ChromeOptions();
-    options.AddArgument($"--user-data-dir={userDataDir}");
-    options.AddArgument("--no-sandbox");
-    options.AddArgument("--disable-dev-shm-usage");
 
-    options.BinaryLocation = await GetChromeLocationAsync();
+    try
+    {
+        var options = new ChromeOptions();
+        options.AddArgument($"--user-data-dir={userDataDir}");
+        options.AddArgument("--no-sandbox");
+        options.AddArgument("--disable-dev-shm-usage");
 
-    driver = new ChromeDriver(options);
+        options.BinaryLocation = await GetChromeLocationAsync();
+
+        driver = new ChromeDriver(options);
+    }
+    catch
+    {
+        if (Directory.Exists(userDataDir))
+        {
+            Directory.Delete(userDataDir, recursive: true);
+        }
+        throw;
+    }
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a resource leak (temporary directory) on exceptions and proposes a try/catch block to handle cleanup, which improves the test's robustness.

Low
  • Update

Previous suggestions

✅ Suggestions up to commit 676da4d
CategorySuggestion                                                                                                                                    Impact
Possible issue
Align DevTools startup version
Suggestion Impact:The commit resolved the identified version mismatch by updating StartDriver from 142 to 150 while also advancing all DevTools imports and domain references from V145 to V150.

code diff:

-using OpenQA.Selenium.DevTools.V145.Network;
-using OpenQA.Selenium.DevTools.V145.Performance;
+using OpenQA.Selenium.DevTools.V150.Network;
+using OpenQA.Selenium.DevTools.V150.Performance;
 
 
 namespace SeleniumDocs.BiDi.CDP
@@ -16,7 +16,7 @@
         [TestInitialize]
         public void Startup()
         {
-            StartDriver("142");
+            StartDriver("150");
         }
 
         [TestMethod]
@@ -109,9 +109,9 @@
             driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";
 
             var session = ((IDevTools)driver).GetDevToolsSession();
-            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
+            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V150.DevToolsSessionDomains>();
 
-            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
+            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V150.Performance.EnableCommandSettings());
             var metricsResponse =
                 await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                     new GetMetricsCommandSettings()
@@ -130,8 +130,8 @@
         public async Task SetCookie()
         {
             var session = ((IDevTools)driver).GetDevToolsSession();
-            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
-            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());
+            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V150.DevToolsSessionDomains>();
+            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V150.Network.EnableCommandSettings());

Update the DevTools version in the Startup method from "142" to "145" to align
with the updated V145 imports.

examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs [17-20]

 public void Startup()
 {
-    StartDriver("142");
+    StartDriver("145");
 }
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical version mismatch between the driver initialization (142) and the DevTools API usage (V145), which would cause test failures.

High

VietND96
VietND96 previously approved these changes Feb 24, 2026
@diemol

diemol commented Jul 15, 2026

Copy link
Copy Markdown
Member

Current version is 4.46 and it was bumped already.

@diemol diemol closed this Jul 15, 2026
@nvborisenko

Copy link
Copy Markdown
Member Author

This PR is about to adjust code slightly according the latest small breaking changes. Reopening, here I am going to make CI green again since trunk is already updated to 4.46

@nvborisenko nvborisenko reopened this Jul 15, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Upgrade .NET examples to Selenium 4.41 (async DriverFinder + DevTools V145)

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Bump Selenium .NET example project dependencies to Selenium 4.41.
• Update CDP/DevTools examples to use V145 version-specific domains.
• Migrate DriverFinder-based path lookups to new async APIs and adjust MSTest methods.
Diagram

graph TD
  A[".NET example tests"] --> B[("Selenium 4.41 packages")] --> C["DriverFinder Get*PathAsync()"] --> F["Resolved paths"]
  A --> D["DevTools V145 domains"] --> H["CDP Network/Performance"]
  A --> E["SeleniumManager logging"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep synchronous tests via blocking on async APIs
  • ➕ Avoids converting MSTest methods to async Task
  • ➕ Keeps call sites closer to prior example text
  • ➖ Encourages .Result/.GetAwaiter().GetResult() patterns that can deadlock in some contexts
  • ➖ Doesn’t model the new Selenium 4.41 API shape as intended
2. Centralize path resolution in a shared helper with caching
  • ➕ Reduces repeated DriverFinder setup across browser/service examples
  • ➕ Can avoid repeated async resolution if multiple tests run in-process
  • ➖ Adds indirection to documentation examples
  • ➖ Caching can obscure the core API usage the examples aim to demonstrate

Recommendation: Proceed with the PR’s approach: updating examples to use the official async DriverFinder APIs is the most future-proof and aligns the examples with Selenium 4.41’s public surface. Consider only minor follow-ups like optional helper extraction if repetition becomes problematic across more files.

Files changed (7) +29 / -25

Enhancement (5) +26 / -22
NetworkTest.csUpdate CDP DevTools domain types to V145 +6/-6

Update CDP DevTools domain types to V145

• Swaps DevTools Network/Performance imports and version-specific domain generics from V142 to V145. Updates the corresponding Enable command settings types used in the PerformanceMetrics and SetCookie examples.

examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

ChromeTest.csUse async DriverFinder browser path lookup for Chrome binary +5/-4

Use async DriverFinder browser path lookup for Chrome binary

• Converts the browser-binary location example to async by introducing GetChromeLocationAsync and awaiting DriverFinder.GetBrowserPathAsync(). Updates the MSTest method signature to async Task and adds the required Tasks using.

examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

EdgeTest.csUse async DriverFinder browser path lookup for Edge binary +5/-4

Use async DriverFinder browser path lookup for Edge binary

• Converts the browser-binary location example to async by introducing GetEdgeLocationAsync and awaiting DriverFinder.GetBrowserPathAsync(). Updates the MSTest method signature to async Task and adds the required Tasks using.

examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

FirefoxTest.csUse async DriverFinder browser path lookup for Firefox binary +5/-4

Use async DriverFinder browser path lookup for Firefox binary

• Converts the Firefox binary-location example to async by introducing GetFirefoxLocationAsync and awaiting DriverFinder.GetBrowserPathAsync(). Updates the MSTest method signature to async Task and adds the required Tasks using.

examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

ServiceTest.csUse async DriverFinder driver path lookup for ChromeDriverService +5/-4

Use async DriverFinder driver path lookup for ChromeDriverService

• Converts the driver-location example to async by introducing GetDriverLocationAsync and awaiting DriverFinder.GetDriverPathAsync(). Updates the MSTest method signature to async Task and adds the required Tasks using.

examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

Bug fix (1) +1 / -1
LoggingTest.csUpdate SeleniumManager namespace import for logging example +1/-1

Update SeleniumManager namespace import for logging example

• Replaces the generic OpenQA.Selenium import with OpenQA.Selenium.Manager so the example can reference SeleniumManager under Selenium 4.41’s namespace layout.

examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

Other (1) +2 / -2
SeleniumDocs.csprojBump Selenium.Support and Selenium.WebDriver to 4.41.0 +2/-2

Bump Selenium.Support and Selenium.WebDriver to 4.41.0

• Updates NuGet package references for Selenium.Support and Selenium.WebDriver from 4.38.0 to 4.41.0 to match the new example API usage.

examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

@qodo-code-review

qodo-code-review Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. CDP version mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
NetworkTest was updated to use V145 version-specific DevTools domains, but the test still calls
StartDriver("142"), which sets ChromeOptions.BrowserVersion="142". This makes the example
potentially incompatible/flaky because V145 CDP bindings are not guaranteed to work correctly
against a Chrome 142 browser.
Code

examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs[R111-114]

            var session = ((IDevTools)driver).GetDevToolsSession();
-            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V142.DevToolsSessionDomains>();
+            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

-            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V142.Performance.EnableCommandSettings());
+            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
Evidence
The PR switches the CDP domain types used by PerformanceMetrics/SetCookie to V145, but the test
setup still pins Chrome to version 142 via StartDriver("142"), and StartDriver maps that string
directly into ChromeOptions.BrowserVersion—so the browser version and CDP binding version can
diverge.

examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs[16-20]
examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs[107-115]
examples/dotnet/SeleniumDocs/BaseTest.cs[36-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`NetworkTest` now uses `OpenQA.Selenium.DevTools.V145.*` version-specific domain types, but it still requests Chrome browser version `142` via `StartDriver("142")`. This creates a mismatch between the browser/CDP protocol level and the strongly-typed CDP bindings used by the example.

### Issue Context
`BaseTest.StartDriver(string browserVersion)` sets `ChromeOptions.BrowserVersion = browserVersion` when a value is provided.

### Fix Focus Areas
- examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs[16-20]
- examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs[107-115]
- examples/dotnet/SeleniumDocs/BaseTest.cs[36-49]

### Recommended fix
Update the test to either:
1) Request a browser version that matches the CDP bindings (e.g., change `StartDriver("142")` to `StartDriver("145")`), **or**
2) Keep the browser pinned to 142 and revert the CDP imports/domains back to V142.

(Option 1 is likely intended given the PR’s V145 upgrade.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs Outdated
@nvborisenko nvborisenko changed the title [dotnet] Upgrade examples to selenium 4.41 [dotnet] Make CI green again according to the 4.41 breaking changes Jul 15, 2026
@nvborisenko
nvborisenko marked this pull request as draft July 15, 2026 15:12
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Line number shifting, risky.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Line number shifting, risky.

@@ -1,3 +1,4 @@
using System.Threading.Tasks;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Line number shifting, risky.

@@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Line number shifting, risky.

@nvborisenko

Copy link
Copy Markdown
Member Author

Interesting issue that executable webdriver doesn't release log file handler in time, need deeper investigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants