Skip to content

report language version to plausible - #16733

Open
titusfortner wants to merge 8 commits into
trunkfrom
lang_version
Open

report language version to plausible#16733
titusfortner wants to merge 8 commits into
trunkfrom
lang_version

Conversation

@titusfortner

@titusfortner titusfortner commented Dec 15, 2025

Copy link
Copy Markdown
Member

User description

Note: this PR includes the code from #16736 to get the tests to pass

🔗 Related Issues

Implements #16731

💥 What does this PR do?

Each language obtains version to send to selenium manager
Selenium Manager reports to Plausible

🔧 Implementation Notes

The only nonstandard one is that .NET reports both the target framework and the Runtime Version:

Scenario lang_version
.NET 8 user net8.0/8
.NET 10 user net8.0/10
.NET 6 user netstandard2.0/6
.NET Framework user net462

🔄 Types of changes

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

PR Type

Enhancement


Description

  • Add language version reporting to Selenium Manager across all bindings

  • Java reports runtime feature version via Runtime.version().feature()

  • .NET reports target framework and runtime version with conditional compilation

  • JavaScript reports Node.js version via process.versions.node

  • Python reports major.minor version via sys.version_info

  • Ruby reports version via RUBY_VERSION constant

  • Rust infrastructure updated to parse and forward language-version argument


Diagram Walkthrough

flowchart LR
  Java["Java<br/>Runtime.version()"] --> SM["Selenium Manager<br/>--language-version"]
  DotNet[".NET<br/>Target Framework"] --> SM
  JS["JavaScript<br/>Node.js version"] --> SM
  Python["Python<br/>sys.version_info"] --> SM
  Ruby["Ruby<br/>RUBY_VERSION"] --> SM
  SM --> Rust["Rust Config<br/>language_binding_version"]
  Rust --> Stats["Stats/Metadata<br/>lang_version field"]
  Stats --> Plausible["Plausible Analytics"]
Loading

File Walkthrough

Relevant files
Enhancement
10 files
SeleniumManager.java
Add Java runtime version reporting                                             
+3/-1     
SeleniumManager.cs
Add .NET framework and runtime version reporting                 
+7/-0     
driverFinder.js
Add Node.js version reporting                                                       
+10/-1   
selenium_manager.py
Add Python version reporting                                                         
+2/-0     
selenium_manager.rb
Add Ruby version reporting                                                             
+1/-0     
config.rs
Add language_binding_version field to config                         
+2/-0     
lib.rs
Add getter/setter for language binding version                     
+11/-0   
main.rs
Add language-version CLI argument parsing                               
+5/-0     
metadata.rs
Add lang_version to stats metadata structures                       
+3/-0     
stats.rs
Add lang_version field to Props struct                                     
+1/-0     

@selenium-ci selenium-ci added C-py Python Bindings C-rb Ruby Bindings C-dotnet .NET Bindings C-java Java Bindings C-nodejs JavaScript Bindings C-rust Rust code is mostly Selenium Manager B-manager Selenium Manager labels Dec 15, 2025
@qodo-code-review

qodo-code-review Bot commented Dec 15, 2025

Copy link
Copy Markdown
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Telemetry privacy

Description: The PR adds collection and forwarding of lang_version (derived from runtime/framework
version) into usage stats sent to Plausible, which can increase fingerprinting/telemetry
granularity and may require a privacy review to ensure it aligns with project policy and
user expectations.
lib.rs [903-915]

Referred Code
    browser: self.get_browser_name().to_ascii_lowercase(),
    browser_version: self.get_browser_version().to_ascii_lowercase(),
    os: self.get_os().to_ascii_lowercase(),
    arch: self
        .get_normalized_arch()
        .unwrap_or(ARCH_OTHER)
        .to_ascii_lowercase(),
    lang: self.get_language_binding().to_ascii_lowercase(),
    lang_version: self.get_language_binding_version().to_ascii_lowercase(),
    selenium_version: self.get_selenium_version().to_ascii_lowercase(),
};
let http_client = self.get_http_client().to_owned();
let sender = self.get_sender().to_owned();
Ticket Compliance
🟡
🎫 #1234
🔴 Ensure that clicking a link with JavaScript in its href triggers the JavaScript (alert) in
Selenium 2.48.x with Firefox (regression vs 2.47.1).
🟡
🎫 #5678
🔴 Prevent or fix repeated ChromeDriver instantiation failures showing ConnectFailure
(Connection refused) after the first instance on Ubuntu/Chrome.
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:
Unvalidated CLI input: The new --language-version CLI argument is accepted and forwarded into config/stats
without visible validation or length/character constraints, so a human should verify it
cannot be abused (e.g., oversized or malformed values) before being stored or sent to
analytics.

Referred Code
/// Version of the language binding invoking Selenium Manager (e.g., 4.18.1, 3.12, net8.0/8)
#[clap(long)]
language_version: Option<String>,

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 Dec 15, 2025

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Learned
best practice
Sanitize telemetry input values
Suggestion Impact:Instead of adding sanitization for language_binding_version, the commit removed language_binding_version from the telemetry payload and deleted the getter/setter entirely, eliminating the need to sanitize that field.

code diff:

@@ -908,7 +908,6 @@
                     .unwrap_or(ARCH_OTHER)
                     .to_ascii_lowercase(),
                 lang: self.get_language_binding().to_ascii_lowercase(),
-                lang_version: self.get_language_binding_version().to_ascii_lowercase(),
                 selenium_version: self.get_selenium_version().to_ascii_lowercase(),
             };
             let http_client = self.get_http_client().to_owned();
@@ -1606,16 +1605,6 @@
         }
     }
 
-    fn get_language_binding_version(&self) -> &str {
-        self.get_config().language_binding_version.as_str()
-    }
-
-    fn set_language_binding_version(&mut self, language_binding_version: String) {
-        if !language_binding_version.is_empty() {
-            self.get_config_mut().language_binding_version = language_binding_version;
-        }
-    }
-

Sanitize language_binding_version (trim, clamp length, and restrict characters)
before storing/sending it, since it can come from CLI/env/config and is later
persisted and sent to Plausible.

rust/src/lib.rs [1613-1617]

 fn set_language_binding_version(&mut self, language_binding_version: String) {
-    if !language_binding_version.is_empty() {
-        self.get_config_mut().language_binding_version = language_binding_version;
+    let sanitized = language_binding_version.trim();
+    if sanitized.is_empty() {
+        return;
+    }
+
+    // Keep telemetry stable and avoid unexpected values.
+    let sanitized: String = sanitized
+        .chars()
+        .filter(|c| c.is_ascii_alphanumeric() || matches!(c, '.' | '-' | '_' | '/'))
+        .take(32)
+        .collect();
+
+    if !sanitized.is_empty() {
+        self.get_config_mut().language_binding_version = sanitized;
     }
 }

[Suggestion processed]

Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Validate and sanitize external inputs before using them in downstream APIs/telemetry to avoid unexpected or invalid requests.

Low
General
Ensure consistent version reporting format
Suggestion Impact:The commit changed the same `--language-version` logic, but instead of appending `/{Environment.Version.Major}` for NET462, it removed the entire target-framework-specific `--language-version` block (including the NET462 case), effectively eliminating the inconsistency by dropping version reporting altogether.

code diff:

-#if NET8_0_OR_GREATER
-        argsBuilder.Append($" --language-version net8.0/{Environment.Version.Major}");
-#elif NETSTANDARD2_0
-        argsBuilder.Append($" --language-version netstandard2.0/{Environment.Version.Major}");
-#elif NET462
-        argsBuilder.Append(" --language-version net462");
-#endif

For consistency, append the major runtime version for the NET462 target
framework, similar to how it's done for NET8_0_OR_GREATER and NETSTANDARD2_0.

dotnet/src/webdriver/SeleniumManager.cs [185-187]

 #elif NET462
-        argsBuilder.Append(" --language-version net462");
+        argsBuilder.Append($" --language-version net462/{Environment.Version.Major}");
 #endif

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies an inconsistency in the version reporting format introduced in the PR and proposes a valid change to align the NET462 target with the other .NET targets.

Low
  • Update

@qodo-code-review

Copy link
Copy Markdown
Contributor

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Java / Browser Tests (windows) / Browser Tests (chrome, windows)

Failed stage: Run Bazel [❌]

Failed test name: //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest

Failure summary:

The action failed because Bazel test execution finished with 4 failing test targets on Windows (exit
code 1).

Failing targets and key causes from the logs:
-
//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest failed (5 failures). The stack
trace shows driver creation failed during
NetworkInterceptorRestTest.setup(NetworkInterceptorRestTest.java:60) via
WebDriverBuilder.get(WebDriverBuilder.java:77) /
DefaultDriverSupplier.get(DefaultDriverSupplier.java:47), ending in Optional.orElseThrow, indicating
no suitable WebDriver/driver supplier was available.
-
//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest failed (6 failures). Multiple
tests failed because Selenium could not obtain/start chromedriver:
-
org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Unable to find
matching driver for capabilities at
RemoteWebDriverBuilder.getLocalDriver(RemoteWebDriverBuilder.java:363) /
RemoteWebDriverBuilder.build(RemoteWebDriverBuilder.java:394) (e.g.,
ChromeDriverFunctionalTest.builderOverridesDefaultChromeOptions(ChromeDriverFunctionalTest.java:70)).

- org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver because the
driver-management command failed: error: unexpected argument '--language-version' found (the invoked
command included --language-version, 21).
-
//java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest failed (details are in
.../FirefoxDriverBuilderTest/test.log, but the visible stack trace also goes through
WebDriverBuilder.get(WebDriverBuilder.java:77) / SeleniumExtension.getDriver, consistent with
WebDriver/driver resolution failing).
-
//java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest failed; stack traces show
Grid node/server setup failed while configuring drivers
(NodeOptions.addSpecificDrivers(NodeOptions.java:606)), resulting in
org.openqa.selenium.grid.config.ConfigException: java.lang.reflect.InvocationTargetException during
RemoteWebDriverDownloadTest.setupServers(RemoteWebDriverDownloadTest.java:80).

Note: the cache restore/save messages (Failed to restore ... cache, Unable to reserve cache ...
another job may be creating this cache) are not the job failure cause; the job failed due to the
test failures above.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

381:  "enabled": true,
382:  "files": [
383:  "./MODULE.bazel",
384:  "./WORKSPACE.bazel",
385:  "./WORKSPACE.bzlmod",
386:  "./WORKSPACE"
387:  ],
388:  "name": "repository",
389:  "paths": [
390:  "D://b-repo"
391:  ]
392:  }
393:  }
394:  ##[endgroup]
395:  ##[group]Restore cache for bazelisk
396:  Failed to restore bazelisk cache
397:  ##[endgroup]
398:  ##[group]Restore cache for disk-java-windows-tests
399:  Failed to restore disk-java-windows-tests cache
400:  ##[endgroup]
401:  ##[group]Restore cache for repository
402:  Failed to restore repository cache
403:  ##[endgroup]
404:  ##[group]Restore cache for external-java-windows-tests-manifest
405:  Failed to restore external-java-windows-tests-manifest cache
406:  ##[endgroup]
...

472:  currently loading: java/test/org/openqa/selenium/federatedcredentialmanagement ... (6 packages)
473:  �[32mAnalyzing:�[0m 6 targets (8 packages loaded)
474:  �[32mAnalyzing:�[0m 6 targets (8 packages loaded, 0 targets configured)
475:  �[32mAnalyzing:�[0m 6 targets (8 packages loaded, 0 targets configured)
476:  �[32mAnalyzing:�[0m 6 targets (32 packages loaded, 19 targets configured)
477:  �[32mAnalyzing:�[0m 6 targets (53 packages loaded, 23 targets configured)
478:  �[32mAnalyzing:�[0m 6 targets (81 packages loaded, 23 targets configured)
479:  �[32mAnalyzing:�[0m 6 targets (107 packages loaded, 25 targets configured)
480:  �[32mAnalyzing:�[0m 6 targets (110 packages loaded, 25 targets configured)
481:  �[32mAnalyzing:�[0m 6 targets (119 packages loaded, 25 targets configured)
482:  �[32mAnalyzing:�[0m 6 targets (145 packages loaded, 267 targets configured)
483:  �[32mAnalyzing:�[0m 6 targets (151 packages loaded, 1979 targets configured)
484:  �[32mAnalyzing:�[0m 6 targets (152 packages loaded, 1991 targets configured)
485:  �[33mDEBUG: �[0mD:/b/external/rules_jvm_external+/private/extensions/maven.bzl:295:14: WARNING: The following maven modules appear in multiple sub-modules with potentially different versions. Consider adding one of these to your root module to ensure consistent versions:
486:  com.google.code.findbugs:jsr305
487:  com.google.errorprone:error_prone_annotations
488:  com.google.guava:guava (versions: 30.1.1-jre, 31.0.1-android)
...

821:  �[32mINFO: �[0mFrom Compiling absl/debugging/internal/examine_stack.cc [for tool]:
822:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
823:  �[32m[1,457 / 2,392]�[0m Compiling absl/strings/internal/cordz_info.cc [for tool]; 1s local, disk-cache ... (4 actions running)
824:  �[32mINFO: �[0mFrom Compiling absl/log/internal/conditions.cc [for tool]:
825:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
826:  �[32mINFO: �[0mFrom Compiling absl/strings/internal/cordz_info.cc [for tool]:
827:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
828:  �[32m[1,463 / 2,392]�[0m Compiling absl/log/internal/log_format.cc [for tool]; 1s local, disk-cache ... (4 actions running)
829:  �[32m[1,464 / 2,392]�[0m Compiling absl/log/internal/log_format.cc [for tool]; 2s local, disk-cache ... (4 actions running)
830:  �[32mINFO: �[0mFrom Compiling absl/log/internal/log_format.cc [for tool]:
831:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
832:  �[32mINFO: �[0mFrom Compiling absl/container/internal/hashtablez_sampler_force_weak_definition.cc [for tool]:
833:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
834:  �[32m[1,467 / 2,392]�[0m Building java/src/org/openqa/selenium/remote/libapi-class.jar (63 source files); 2s disk-cache, multiplex-worker ... (4 actions running)
835:  �[32mINFO: �[0mFrom Building java/src/org/openqa/selenium/remote/libapi-class.jar (63 source files):
836:  java\src\org\openqa\selenium\remote\ErrorHandler.java:46: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
837:  private final ErrorCodes errorCodes;
838:  ^
839:  java\src\org\openqa\selenium\remote\ErrorHandler.java:60: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
840:  this.errorCodes = new ErrorCodes();
841:  ^
842:  java\src\org\openqa\selenium\remote\ErrorHandler.java:68: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
843:  public ErrorHandler(ErrorCodes codes, boolean includeServerErrors) {
844:  ^
845:  java\src\org\openqa\selenium\remote\Response.java:100: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
846:  ErrorCodes errorCodes = new ErrorCodes();
847:  ^
848:  java\src\org\openqa\selenium\remote\Response.java:100: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
849:  ErrorCodes errorCodes = new ErrorCodes();
850:  ^
851:  java\src\org\openqa\selenium\remote\ProtocolHandshake.java:181: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
852:  response.setStatus(ErrorCodes.SUCCESS);
853:  ^
854:  java\src\org\openqa\selenium\remote\ProtocolHandshake.java:182: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
855:  response.setState(ErrorCodes.SUCCESS_STRING);
856:  ^
857:  java\src\org\openqa\selenium\remote\W3CHandshakeResponse.java:53: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
858:  new ErrorCodes().toStatus((String) rawError, Optional.of(tuple.getStatusCode())));
859:  ^
860:  java\src\org\openqa\selenium\remote\W3CHandshakeResponse.java:56: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
861:  new ErrorCodes().getExceptionType((String) rawError);
862:  ^
863:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:44: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
864:  private final ErrorCodes errorCodes = new ErrorCodes();
865:  ^
866:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:44: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
867:  private final ErrorCodes errorCodes = new ErrorCodes();
868:  ^
869:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:55: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
870:  int status = response.getStatus() == ErrorCodes.SUCCESS ? HTTP_OK : HTTP_INTERNAL_ERROR;
871:  ^
872:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:101: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
873:  response.setStatus(ErrorCodes.UNKNOWN_COMMAND);
874:  ^
875:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:103: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
876:  response.setStatus(ErrorCodes.UNHANDLED_ERROR);
877:  ^
878:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:117: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
879:  response.setStatus(ErrorCodes.SUCCESS);
880:  ^
881:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:118: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
882:  response.setState(errorCodes.toState(ErrorCodes.SUCCESS));
883:  ^
884:  java\src\org\openqa\selenium\remote\codec\AbstractHttpResponseCodec.java:124: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
885:  response.setState(errorCodes.toState(ErrorCodes.SUCCESS));
886:  ^
887:  java\src\org\openqa\selenium\remote\codec\w3c\W3CHttpResponseCodec.java:69: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
888:  private final ErrorCodes errorCodes = new ErrorCodes();
889:  ^
890:  java\src\org\openqa\selenium\remote\codec\w3c\W3CHttpResponseCodec.java:69: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
891:  private final ErrorCodes errorCodes = new ErrorCodes();
892:  ^
893:  java\src\org\openqa\selenium\remote\codec\w3c\W3CHttpResponseCodec.java:97: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
894:  response.setStatus(ErrorCodes.UNKNOWN_COMMAND);
895:  ^
896:  java\src\org\openqa\selenium\remote\codec\w3c\W3CHttpResponseCodec.java:102: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
897:  response.setStatus(ErrorCodes.UNHANDLED_ERROR);
898:  ^
899:  java\src\org\openqa\selenium\remote\codec\w3c\W3CHttpResponseCodec.java:149: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
900:  response.setStatus(ErrorCodes.SUCCESS);
901:  ^
...

909:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
910:  �[32mINFO: �[0mFrom Compiling absl/container/internal/raw_hash_set.cc [for tool]:
911:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
912:  �[32mINFO: �[0mFrom Compiling absl/crc/internal/crc_non_temporal_memcpy.cc [for tool]:
913:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
914:  �[32mINFO: �[0mFrom Compiling absl/strings/internal/cord_rep_btree.cc [for tool]:
915:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
916:  �[32m[1,485 / 2,392]�[0m Compiling src/google/protobuf/port.cc [for tool]; 0s local, disk-cache ... (4 actions, 3 running)
917:  �[32mINFO: �[0mFrom Compiling absl/strings/internal/cord_rep_btree_navigator.cc [for tool]:
918:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
919:  �[32m[1,486 / 2,392]�[0m Compiling src/google/protobuf/port.cc [for tool]; 1s local, disk-cache ... (4 actions, 3 running)
920:  �[32mINFO: �[0mFrom Compiling absl/crc/internal/crc_memcpy_x86_arm_combined.cc [for tool]:
921:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
922:  �[32mINFO: �[0mFrom Compiling src/google/protobuf/port.cc [for tool]:
923:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
924:  �[32mINFO: �[0mFrom Compiling absl/base/internal/strerror.cc [for tool]:
925:  cl : Command line warning D9002 : ignoring unknown option '-std=c++14'
...

2058:  �[32m[2,345 / 2,392]�[0m Action java/src/org/openqa/selenium/devtools/v142/v142-module-module-info.jar; 4s local, disk-cache ... (4 actions running)
2059:  �[32m[2,346 / 2,392]�[0m Action java/src/org/openqa/selenium/devtools/v142/v142-module-module-info.jar; 5s local, disk-cache ... (4 actions running)
2060:  �[32m[2,348 / 2,392]�[0m Action java/src/org/openqa/selenium/devtools/v142/v142-module-module-info.jar; 6s local, disk-cache ... (4 actions running)
2061:  �[32m[2,352 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 5s disk-cache, multiplex-worker ... (4 actions running)
2062:  �[32m[2,356 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 6s disk-cache, multiplex-worker ... (4 actions running)
2063:  �[32m[2,360 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 7s disk-cache, multiplex-worker ... (4 actions running)
2064:  �[32m[2,362 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 8s disk-cache, multiplex-worker ... (4 actions running)
2065:  �[32m[2,366 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 9s disk-cache, multiplex-worker ... (4 actions running)
2066:  �[32m[2,367 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 10s disk-cache, multiplex-worker ... (4 actions running)
2067:  �[32m[2,370 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 11s disk-cache, multiplex-worker ... (4 actions running)
2068:  �[32m[2,371 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 12s disk-cache, multiplex-worker ... (4 actions running)
2069:  �[32m[2,372 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 13s disk-cache, multiplex-worker ... (4 actions, 3 running)
2070:  �[32m[2,373 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v141/libcdp.jar (1 source jar); 15s disk-cache, multiplex-worker ... (4 actions running)
2071:  �[32m[2,376 / 2,392]�[0m Building java/src/org/openqa/selenium/devtools/v143/libcdp.jar (1 source jar); 9s disk-cache, multiplex-worker ... (4 actions running)
2072:  �[32mINFO: �[0mFrom Building java/test/org/openqa/selenium/remote/libsmall-tests-test-lib.jar (5 source files) and running annotation processors (AutoServiceProcessor):
2073:  java\test\org\openqa\selenium\remote\WebDriverFixture.java:170: warning: [removal] ErrorCodes in org.openqa.selenium.remote has been deprecated and marked for removal
2074:  response.setStatus(new ErrorCodes().toStatus(state, Optional.of(400)));
2075:  ^
...

2093:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 9s local, disk-cache ... (4 actions running)
2094:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 13s local, disk-cache ... (4 actions running)
2095:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test_attempts/attempt_1.log)
2096:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 15s local, disk-cache ... (4 actions running)
2097:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 17s local, disk-cache ... (4 actions running)
2098:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/devtools/NetworkInterceptorRestTest/test_attempts/attempt_2.log)
2099:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 18s local, disk-cache ... (4 actions running)
2100:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test_attempts/attempt_2.log)
2101:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/chrome/ChromeDriverFunctionalTest/test_attempts/attempt_2.log)
2102:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 19s local, disk-cache ... (4 actions running)
2103:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test_attempts/attempt_2.log)
2104:  �[32m[2,394 / 2,398]�[0m 2 / 6 tests;�[0m Testing //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest; 24s local, disk-cache ... (4 actions running)
2105:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/devtools/NetworkInterceptorRestTest/test.log)
2106:  ==================== Test output for //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest:
2107:  Failures: 5
2108:  �[31m�[1mFAILED: �[0m//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest (Summary)
2109:  1) shouldInterceptPostRequest() (org.openqa.selenium.devtools.NetworkInterceptorRestTest)
...

2360:  at java.base/java.util.Optional.orElseThrow(Optional.java:403)
2361:  at org.openqa.selenium.testing.drivers.DefaultDriverSupplier.get(DefaultDriverSupplier.java:47)
2362:  at org.openqa.selenium.testing.drivers.DefaultDriverSupplier.get(DefaultDriverSupplier.java:29)
2363:  at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
2364:  at java.base/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:1034)
2365:  at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
2366:  at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
2367:  at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
2368:  at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
2369:  at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
2370:  at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
2371:  at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
2372:  at org.openqa.selenium.testing.drivers.WebDriverBuilder.get(WebDriverBuilder.java:77)
2373:  at org.openqa.selenium.devtools.NetworkInterceptorRestTest.setup(NetworkInterceptorRestTest.java:60)
2374:  ================================================================================
2375:  �[32m[2,395 / 2,398]�[0m 3 / 6 tests, �[31m�[1m1 failed�[0m;�[0m Testing //java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest; 26s local, disk-cache ... (3 actions running)
2376:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test.log)
2377:  �[31m�[1mFAILED: �[0m//java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest (Summary)
2378:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test.log
...

2502:  at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
2503:  at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
2504:  at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
2505:  at org.openqa.selenium.testing.drivers.WebDriverBuilder.get(WebDriverBuilder.java:77)
2506:  at org.openqa.selenium.testing.SeleniumExtension.actuallyCreateDriver(SeleniumExtension.java:276)
2507:  at org.openqa.selenium.testing.SeleniumExtension.actuallyCreateDriver(SeleniumExtension.java:265)
2508:  at org.openqa.selenium.testing.SeleniumExtension.getDriver(SeleniumExtension.java:254)
2509:  at org.openqa.selenium.testing.JupiterTestBase.prepareEnvironment(JupiterTestBase.java:84)
2510:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2511:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2512:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2513:  ================================================================================
2514:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/chrome/ChromeDriverFunctionalTest/test.log)
2515:  ==================== Test output for //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest:
2516:  Failures: 6
2517:  �[31m�[1mFAILED: �[0m//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest (Summary)
2518:  1) builderGeneratesDefaultChromeOptions() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
...

2549:  at org.openqa.selenium.testing.SeleniumExtension.getDriver(SeleniumExtension.java:254)
2550:  at org.openqa.selenium.testing.JupiterTestBase.prepareEnvironment(JupiterTestBase.java:84)
2551:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2552:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2553:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2554:  3) builderOverridesDefaultChromeOptions() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2555:  org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Unable to find matching driver for capabilities 
2556:  Host info: host: 'runnervm8j6r3', ip: '10.1.0.119'
2557:  Build info: version: '4.40.0-SNAPSHOT', revision: 'Unknown'
2558:  System info: os.name: 'Windows Server 2022', os.arch: 'amd64', os.version: '10.0', java.version: '21.0.4'
2559:  Driver info: driver.version: unknown
2560:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.getLocalDriver(RemoteWebDriverBuilder.java:363)
2561:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.build(RemoteWebDriverBuilder.java:394)
2562:  at org.openqa.selenium.chrome.ChromeDriverFunctionalTest.builderOverridesDefaultChromeOptions(ChromeDriverFunctionalTest.java:70)
2563:  4) driverOverridesDefaultClientConfig() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2564:  java.lang.AssertionError: 
2565:  Expecting actual throwable to be an instance of:
2566:  org.openqa.selenium.SessionNotCreatedException
2567:  but was:
2568:  org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver, error Command failed with code: 2, executed: [--browser, chrome, --language-binding, java, --language-version, 21, --output, json]
2569:  error: unexpected argument '--language-version' found
2570:  tip: a similar argument exists: '--language-binding'
...

2654:  at org.openqa.selenium.testing.SeleniumExtension.getDriver(SeleniumExtension.java:254)
2655:  at org.openqa.selenium.testing.JupiterTestBase.prepareEnvironment(JupiterTestBase.java:84)
2656:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2657:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2658:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2659:  3) builderOverridesDefaultChromeOptions() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2660:  org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Unable to find matching driver for capabilities 
2661:  Host info: host: 'runnervm8j6r3', ip: '10.1.0.119'
2662:  Build info: version: '4.40.0-SNAPSHOT', revision: 'Unknown'
2663:  System info: os.name: 'Windows Server 2022', os.arch: 'amd64', os.version: '10.0', java.version: '21.0.4'
2664:  Driver info: driver.version: unknown
2665:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.getLocalDriver(RemoteWebDriverBuilder.java:363)
2666:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.build(RemoteWebDriverBuilder.java:394)
2667:  at org.openqa.selenium.chrome.ChromeDriverFunctionalTest.builderOverridesDefaultChromeOptions(ChromeDriverFunctionalTest.java:70)
2668:  4) driverOverridesDefaultClientConfig() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2669:  java.lang.AssertionError: 
2670:  Expecting actual throwable to be an instance of:
2671:  org.openqa.selenium.SessionNotCreatedException
2672:  but was:
2673:  org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver, error Command failed with code: 2, executed: [--browser, chrome, --language-binding, java, --language-version, 21, --output, json]
2674:  error: unexpected argument '--language-version' found
2675:  tip: a similar argument exists: '--language-binding'
...

2759:  at org.openqa.selenium.testing.SeleniumExtension.getDriver(SeleniumExtension.java:254)
2760:  at org.openqa.selenium.testing.JupiterTestBase.prepareEnvironment(JupiterTestBase.java:84)
2761:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2762:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2763:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2764:  3) builderOverridesDefaultChromeOptions() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2765:  org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Unable to find matching driver for capabilities 
2766:  Host info: host: 'runnervm8j6r3', ip: '10.1.0.119'
2767:  Build info: version: '4.40.0-SNAPSHOT', revision: 'Unknown'
2768:  System info: os.name: 'Windows Server 2022', os.arch: 'amd64', os.version: '10.0', java.version: '21.0.4'
2769:  Driver info: driver.version: unknown
2770:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.getLocalDriver(RemoteWebDriverBuilder.java:363)
2771:  at org.openqa.selenium.remote.RemoteWebDriverBuilder.build(RemoteWebDriverBuilder.java:394)
2772:  at org.openqa.selenium.chrome.ChromeDriverFunctionalTest.builderOverridesDefaultChromeOptions(ChromeDriverFunctionalTest.java:70)
2773:  4) driverOverridesDefaultClientConfig() (org.openqa.selenium.chrome.ChromeDriverFunctionalTest)
2774:  java.lang.AssertionError: 
2775:  Expecting actual throwable to be an instance of:
2776:  org.openqa.selenium.SessionNotCreatedException
2777:  but was:
2778:  org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver, error Command failed with code: 2, executed: [--browser, chrome, --language-binding, java, --language-version, 21, --output, json]
2779:  error: unexpected argument '--language-version' found
2780:  tip: a similar argument exists: '--language-binding'
...

2820:  at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
2821:  at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
2822:  at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
2823:  at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
2824:  at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
2825:  at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
2826:  at org.openqa.selenium.testing.drivers.WebDriverBuilder.get(WebDriverBuilder.java:77)
2827:  at org.openqa.selenium.testing.SeleniumExtension.actuallyCreateDriver(SeleniumExtension.java:276)
2828:  at org.openqa.selenium.testing.SeleniumExtension.actuallyCreateDriver(SeleniumExtension.java:265)
2829:  at org.openqa.selenium.testing.SeleniumExtension.getDriver(SeleniumExtension.java:254)
2830:  at org.openqa.selenium.testing.JupiterTestBase.prepareEnvironment(JupiterTestBase.java:84)
2831:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2832:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2833:  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
2834:  ================================================================================
2835:  �[32m[2,397 / 2,398]�[0m 5 / 6 tests, �[31m�[1m3 failed�[0m;�[0m Testing //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest; 20s local, disk-cache
2836:  �[31m�[1mFAIL: �[0m//java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest (see D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test.log)
2837:  �[31m�[1mFAILED: �[0m//java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest (Summary)
2838:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test.log
...

2923:  at org.openqa.selenium.grid.node.config.NodeOptions.addSpecificDrivers(NodeOptions.java:606)
2924:  at org.openqa.selenium.grid.node.config.NodeOptions.getSessionFactories(NodeOptions.java:257)
2925:  at org.openqa.selenium.grid.node.local.LocalNodeFactory.create(LocalNodeFactory.java:80)
2926:  at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
2927:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
2928:  at org.openqa.selenium.grid.config.ClassCreation.callCreateMethod(ClassCreation.java:51)
2929:  at org.openqa.selenium.grid.config.MemoizedConfig.lambda$getClass$4(MemoizedConfig.java:104)
2930:  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740)
2931:  at org.openqa.selenium.grid.config.MemoizedConfig.getClass(MemoizedConfig.java:99)
2932:  at org.openqa.selenium.grid.node.config.NodeOptions.getNode(NodeOptions.java:188)
2933:  at org.openqa.selenium.grid.commands.Standalone.createNode(Standalone.java:260)
2934:  at org.openqa.selenium.grid.commands.Standalone.createHandlers(Standalone.java:219)
2935:  at org.openqa.selenium.grid.TemplateGridServerCommand.asServer(TemplateGridServerCommand.java:48)
2936:  at org.openqa.selenium.grid.router.DeploymentTypes$1.start(DeploymentTypes.java:85)
2937:  at org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest.setupServers(RemoteWebDriverDownloadTest.java:80)
2938:  3) errorsWhenCapabilityMissing() (org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest)
2939:  org.openqa.selenium.grid.config.ConfigException: java.lang.reflect.InvocationTargetException
...

3096:  at org.openqa.selenium.grid.node.config.NodeOptions.addSpecificDrivers(NodeOptions.java:606)
3097:  at org.openqa.selenium.grid.node.config.NodeOptions.getSessionFactories(NodeOptions.java:257)
3098:  at org.openqa.selenium.grid.node.local.LocalNodeFactory.create(LocalNodeFactory.java:80)
3099:  at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
3100:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
3101:  at org.openqa.selenium.grid.config.ClassCreation.callCreateMethod(ClassCreation.java:51)
3102:  at org.openqa.selenium.grid.config.MemoizedConfig.lambda$getClass$4(MemoizedConfig.java:104)
3103:  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740)
3104:  at org.openqa.selenium.grid.config.MemoizedConfig.getClass(MemoizedConfig.java:99)
3105:  at org.openqa.selenium.grid.node.config.NodeOptions.getNode(NodeOptions.java:188)
3106:  at org.openqa.selenium.grid.commands.Standalone.createNode(Standalone.java:260)
3107:  at org.openqa.selenium.grid.commands.Standalone.createHandlers(Standalone.java:219)
3108:  at org.openqa.selenium.grid.TemplateGridServerCommand.asServer(TemplateGridServerCommand.java:48)
3109:  at org.openqa.selenium.grid.router.DeploymentTypes$1.start(DeploymentTypes.java:85)
3110:  at org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest.setupServers(RemoteWebDriverDownloadTest.java:80)
3111:  3) errorsWhenCapabilityMissing() (org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest)
3112:  org.openqa.selenium.grid.config.ConfigException: java.lang.reflect.InvocationTargetException
...

3269:  at org.openqa.selenium.grid.node.config.NodeOptions.addSpecificDrivers(NodeOptions.java:606)
3270:  at org.openqa.selenium.grid.node.config.NodeOptions.getSessionFactories(NodeOptions.java:257)
3271:  at org.openqa.selenium.grid.node.local.LocalNodeFactory.create(LocalNodeFactory.java:80)
3272:  at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
3273:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
3274:  at org.openqa.selenium.grid.config.ClassCreation.callCreateMethod(ClassCreation.java:51)
3275:  at org.openqa.selenium.grid.config.MemoizedConfig.lambda$getClass$4(MemoizedConfig.java:104)
3276:  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740)
3277:  at org.openqa.selenium.grid.config.MemoizedConfig.getClass(MemoizedConfig.java:99)
3278:  at org.openqa.selenium.grid.node.config.NodeOptions.getNode(NodeOptions.java:188)
3279:  at org.openqa.selenium.grid.commands.Standalone.createNode(Standalone.java:260)
3280:  at org.openqa.selenium.grid.commands.Standalone.createHandlers(Standalone.java:219)
3281:  at org.openqa.selenium.grid.TemplateGridServerCommand.asServer(TemplateGridServerCommand.java:48)
3282:  at org.openqa.selenium.grid.router.DeploymentTypes$1.start(DeploymentTypes.java:85)
3283:  at org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest.setupServers(RemoteWebDriverDownloadTest.java:80)
3284:  3) errorsWhenCapabilityMissing() (org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest)
3285:  org.openqa.selenium.grid.config.ConfigException: java.lang.reflect.InvocationTargetException
...

3349:  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
3350:  at org.openqa.selenium.grid.config.ClassCreation.callCreateMethod(ClassCreation.java:51)
3351:  at org.openqa.selenium.grid.config.MemoizedConfig.lambda$getClass$4(MemoizedConfig.java:104)
3352:  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740)
3353:  at org.openqa.selenium.grid.config.MemoizedConfig.getClass(MemoizedConfig.java:99)
3354:  at org.openqa.selenium.grid.node.config.NodeOptions.getNode(NodeOptions.java:188)
3355:  at org.openqa.selenium.grid.commands.Standalone.createNode(Standalone.java:260)
3356:  at org.openqa.selenium.grid.commands.Standalone.createHandlers(Standalone.java:219)
3357:  at org.openqa.selenium.grid.TemplateGridServerCommand.asServer(TemplateGridServerCommand.java:48)
3358:  at org.openqa.selenium.grid.router.DeploymentTypes$1.start(DeploymentTypes.java:85)
3359:  at org.openqa.selenium.grid.router.RemoteWebDriverDownloadTest.setupServers(RemoteWebDriverDownloadTest.java:80)
3360:  ================================================================================
3361:  �[32mINFO: �[0mFound 6 test targets...
3362:  �[32mINFO: �[0mElapsed time: 807.224s, Critical Path: 209.60s
3363:  �[32mINFO: �[0m2156 processes: 860 internal, 1094 local, 202 worker.
3364:  �[32mINFO: �[0mBuild completed, 4 tests FAILED, 2156 total actions
3365:  //java/test/org/openqa/selenium/federatedcredentialmanagement:FederatedCredentialManagementTest �[0m�[32mPASSED�[0m in 2.5s
3366:  //java/test/org/openqa/selenium/remote:RemoteWebDriverBuilderTest        �[0m�[32mPASSED�[0m in 6.2s
3367:  //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest        �[0m�[31m�[1mFAILED�[0m in 3 out of 3 in 9.1s
3368:  Stats over 3 runs: max = 9.1s, min = 8.6s, avg = 8.8s, dev = 0.2s
3369:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/chrome/ChromeDriverFunctionalTest/test.log
3370:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/chrome/ChromeDriverFunctionalTest/test_attempts/attempt_1.log
3371:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/chrome/ChromeDriverFunctionalTest/test_attempts/attempt_2.log
3372:  //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest      �[0m�[31m�[1mFAILED�[0m in 3 out of 3 in 9.1s
3373:  Stats over 3 runs: max = 9.1s, min = 7.8s, avg = 8.5s, dev = 0.5s
3374:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/devtools/NetworkInterceptorRestTest/test.log
3375:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/devtools/NetworkInterceptorRestTest/test_attempts/attempt_1.log
3376:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/devtools/NetworkInterceptorRestTest/test_attempts/attempt_2.log
3377:  //java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest         �[0m�[31m�[1mFAILED�[0m in 3 out of 3 in 9.3s
3378:  Stats over 3 runs: max = 9.3s, min = 8.7s, avg = 9.0s, dev = 0.3s
3379:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test.log
3380:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test_attempts/attempt_1.log
3381:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/firefox/FirefoxDriverBuilderTest/test_attempts/attempt_2.log
3382:  //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest  �[0m�[31m�[1mFAILED�[0m in 3 out of 3 in 8.3s
3383:  Stats over 3 runs: max = 8.3s, min = 4.7s, avg = 7.0s, dev = 1.7s
3384:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test.log
3385:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test_attempts/attempt_1.log
3386:  D:/b/execroot/_main/bazel-out/x64_windows-fastbuild/testlogs/java/test/org/openqa/selenium/grid/router/RemoteWebDriverDownloadTest/test_attempts/attempt_2.log
3387:  Executed 6 out of 6 tests: 2 tests pass and �[0m�[31m�[1m4 fail locally�[0m.
3388:  There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
3389:  �[0m
3390:  ##[error]Process completed with exit code 1.
3391:  ##[group]Run actions/upload-artifact@v5
...

3412:  ##[endgroup]
3413:  With the provided path, there will be 60 files uploaded
3414:  Artifact name is valid!
3415:  Root directory input is valid!
3416:  Beginning upload of artifact content to blob storage
3417:  Uploaded bytes 72575
3418:  Finished uploading artifact content to blob storage!
3419:  SHA256 digest of uploaded artifact zip is 0ffbc4db014de4beee314b93845036e241ba7de805e67cc03f0b190c921add0f
3420:  Finalizing artifact upload
3421:  Artifact test-logs-windows-Browser Tests (chrome, windows)-chrome.zip successfully finalized. Artifact ID 4875955875
3422:  Artifact test-logs-windows-Browser Tests (chrome, windows)-chrome has been successfully uploaded! Final size is 72575 bytes. Artifact ID is 4875955875
3423:  Artifact download URL: https://github.com/SeleniumHQ/selenium/actions/runs/20242946371/artifacts/4875955875
3424:  Post job cleanup.
3425:  ##[group]Save cache for bazelisk
3426:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3427:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-bazelisk-1c738f2c94b26698d42161fd2c2da70645e6a68eb05666a970f9d2c0143fbabb, another job may be creating this cache.
3428:  Successfully saved cache
3429:  ##[endgroup]
3430:  ##[group]Save cache for disk-java-windows-tests
3431:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3432:  Sent 33897123 of 235223715 (14.4%), 31.9 MBs/sec
3433:  Sent 235223715 of 235223715 (100.0%), 155.1 MBs/sec
3434:  Successfully saved cache
3435:  ##[endgroup]
3436:  ##[group]Save cache for repository
3437:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3438:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-repository-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3439:  Successfully saved cache
3440:  ##[endgroup]
3441:  ##[group]Save cache for external-com_google_javascript_closure_library
3442:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3443:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-com_google_javascript_closure_library-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3444:  Successfully saved cache
3445:  ##[endgroup]
3446:  ##[group]Save cache for external-protobuf+
3447:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3448:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-protobuf+-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3449:  Successfully saved cache
3450:  ##[endgroup]
3451:  ##[group]Save cache for external-rules_java++toolchains+remotejdk21_win
3452:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3453:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_java++toolchains+remotejdk21_win-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3454:  Successfully saved cache
3455:  ##[endgroup]
3456:  ##[group]Save cache for external-rules_java++toolchains+remote_java_tools
3457:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3458:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_java++toolchains+remote_java_tools-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3459:  Successfully saved cache
3460:  ##[endgroup]
3461:  ##[group]Save cache for external-rules_java++toolchains+remote_java_tools_windows
3462:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3463:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_java++toolchains+remote_java_tools_windows-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3464:  Successfully saved cache
3465:  ##[endgroup]
3466:  ##[group]Save cache for external-rules_kotlin+
3467:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3468:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_kotlin+-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3469:  Successfully saved cache
3470:  ##[endgroup]
3471:  ##[group]Save cache for external-rules_nodejs++node+nodejs_windows_amd64
3472:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3473:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_nodejs++node+nodejs_windows_amd64-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3474:  Successfully saved cache
3475:  ##[endgroup]
3476:  ##[group]Save cache for external-rules_python++python+python_3_10_x86_64-pc-windows-msvc
3477:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3478:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_python++python+python_3_10_x86_64-pc-windows-msvc-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3479:  Successfully saved cache
3480:  ##[endgroup]
3481:  ##[group]Save cache for external-rules_rust+
3482:  [command]"C:\Program Files\Git\usr\bin\tar.exe" --posix -cf cache.tzst --exclude cache.tzst -P -C D:/a/selenium/selenium --files-from manifest.txt --force-local --use-compress-program "zstd -T0"
3483:  Failed to save: Unable to reserve cache with key setup-bazel-2-win32-external-rules_rust+-1ca1cfa3af344ea4b229d5491de5da71c2f3d2a82fa0b95c0316ff6cb7f5101a, another job may be creating this cache.
3484:  Successfully saved cache

@nvborisenko nvborisenko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please elaborate motivation, and most likely we propose good solution in .NET. CC @RenderMichael

{
StringBuilder argsBuilder = new StringBuilder(arguments);
argsBuilder.Append(" --language-binding csharp");
#if NET8_0_OR_GREATER

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Original motivation was:

how many people using the latest version of Selenium

This code doesn't include the version of Selenium binding.

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.

Selenium Manager sets the Selenium version since the versions are in sync: https://github.com/SeleniumHQ/selenium/blob/selenium-4.39.0/rust/src/main.rs#L227

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Plausible analytics are here: https://plausible.io/manager.selenium.dev
navigate to custom properties at the bottom to see specifics.
The reason for the PR is specifically Java, if 50% of our users are still on Java 11, then we aren't going to want to require a move to Java 17, etc
For .NET this means seeing how many people are still using .NET Framework vs NET 6/7 vs NET 8/9/10

Seems reasonable, let's think more about it.

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.

what is your concern?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

OK, it is not about Selenium version, accepted. I propose to see the final output for all bindings and align the format, I mean python 3.14 or PyThoN_3_14. What is our preference?

Interesting, do we really want to see TFM (net8.0, netstandard2.0)? Or runtime version would be enough?..

PS: We can easily implement all variants.

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.

As far as capturing TFM, I was thinking it would be useful to know if someone is targeting netstandard2, even if they are using Net 8 or something. Not essential, but the info was right there, so I figured we'd capture it and it only 3x the values at most.

@titusfortner titusfortner Dec 18, 2025

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.

@RenderMichael {Environment.Version.Major} seems sufficient to me (and limits the number of combinations with TFM). Is there something about the minor version that would give us extra insight?

The goal is to provide understanding about how we focus/update support. We changed targets a couple years ago pretty much blind, and if we had this info it would have made it more obvious what the tradeoffs were.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The minor version is relevant for the .NET Standard 2.0 target. For example, there exists .NET Core 3.0 and .NET Core 3.1 (likewise 2.0 and 2.1, but adoption was so low and only from bleeding-edge folks back that it's completely irrelevant).

The much more relevant examples are on .NET Framework. .NET Standard 2.0 covers 4.7, 4.7.1, 4.7.2, 4.8, and 4.8.1 (as well 4.6.2 but Selenium targets that directly) source. Environment.Version.Major will not give us the information we need there. I don't think Version.Minor will either, actually, given what this outputs on 4.7.2.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We changed targets a couple years ago pretty much blind

I disregards. I proposed to change it, still no issues.

Before:

image

After:

image

Anyway collecting usage stats will be helpful. Let's discuss it instantly in slack channel.

@titusfortner

Copy link
Copy Markdown
Member Author

@nvborisenko
Plausible analytics are here: https://plausible.io/manager.selenium.dev
navigate to custom properties at the bottom to see specifics.

The reason for the PR is specifically Java, if 50% of our users are still on Java 11, then we aren't going to want to require a move to Java 17, etc

For .NET this means seeing how many people are still using .NET Framework vs NET 6/7 vs NET 8/9/10

Comment thread dotnet/src/webdriver/SeleniumManager.cs
Co-authored-by: Michael Render <render.michael@gmail.com>
Comment thread rb/lib/selenium/webdriver/common/selenium_manager.rb Outdated
@github-actions github-actions Bot added the J-stale Applied to issues that become stale, and eventually closed. label Jun 17, 2026
@github-actions github-actions Bot closed this Jul 2, 2026
@titusfortner titusfortner reopened this Jul 2, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Report language binding version in Selenium Manager stats (Plausible)

✨ Enhancement ⚙️ Configuration changes 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add per-binding language version reporting when invoking Selenium Manager.
• Persist language version into Selenium Manager stats metadata sent to Plausible.
• Default Bazel pinned browsers on, and simplify CI/docs test invocations.
Diagram

graph TD
  A["Language bindings"] --> B["Add --language-version"] --> C["Selenium Manager (Rust CLI)"] --> D["ManagerConfig"] --> E["Stats metadata"] --> F{{"Plausible.io"}}
  G["Bazel pin_browsers"] --> H["SM binary selection"] --> C

  subgraph Legend
    direction LR
    _comp["Component"] ~~~ _ext{{"External"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Encode version into --language-binding value
  • ➕ No new CLI flag or config field required
  • ➕ Avoids expanding stats schema
  • ➖ Conflates two concepts (binding identity vs version)
  • ➖ Harder to parse/aggregate reliably in analytics
  • ➖ More likely to introduce inconsistent formatting across languages
2. Infer language version inside Selenium Manager
  • ➕ Bindings remain simpler (no extra argument)
  • ➕ Centralized logic for version formatting
  • ➖ Not feasible across all runtimes without additional env/interop
  • ➖ Would be brittle and platform-specific (e.g., JVM vs Node vs .NET vs Ruby)
  • ➖ Still needs a stable input channel to disambiguate runtime details

Recommendation: Keep the PR’s approach: a dedicated --language-version argument per binding, plumbed into Selenium Manager config and stats. It preserves backward compatibility (empty default), keeps analytics fields cleanly separable (lang vs lang_version), and allows each runtime to provide the most accurate version representation (notably .NET’s target framework + runtime major).

Files changed (19) +87 / -30

Enhancement (10) +47 / -2
SeleniumManager.csSend .NET target framework/runtime language version to Selenium Manager +9/-0

Send .NET target framework/runtime language version to Selenium Manager

• Adds --language-version to the Selenium Manager invocation, with conditional compilation for supported TFMs. .NET 8+/netstandard2.0 include both target framework and runtime major; .NET Framework reports net462.

dotnet/src/webdriver/SeleniumManager.cs

SeleniumManager.javaSend Java runtime feature version to Selenium Manager +3/-1

Send Java runtime feature version to Selenium Manager

• Extends Selenium Manager argument construction to include --language-version. Uses the Java runtime feature version (e.g., 17) for reporting.

java/src/org/openqa/selenium/manager/SeleniumManager.java

driverFinder.jsSend Node.js version to Selenium Manager +10/-1

Send Node.js version to Selenium Manager

• Adds --language-version to the Selenium Manager argument list. Uses process.versions.node so stats reflect the Node runtime version used by selenium-webdriver.

javascript/selenium-webdriver/common/driverFinder.js

selenium_manager.pySend Python major.minor version to Selenium Manager +2/-0

Send Python major.minor version to Selenium Manager

• Adds --language-version to Selenium Manager args and reports Python major.minor (e.g., 3.12). This keeps version reporting stable across patch releases.

py/selenium/webdriver/common/selenium_manager.py

selenium_manager.rbSend Ruby major.minor version to Selenium Manager +1/-0

Send Ruby major.minor version to Selenium Manager

• Adds --language-version to the Ruby Selenium Manager invocation. Reports Ruby major.minor derived from RUBY_VERSION for consistent analytics grouping.

rb/lib/selenium/webdriver/common/selenium_manager.rb

config.rsAdd language binding version to Selenium Manager configuration +2/-0

Add language binding version to Selenium Manager configuration

• Extends ManagerConfig with language_binding_version and wires it to the new --language-version CLI key. This enables downstream stats/reporting to include the provided binding version.

rust/src/config.rs

lib.rsPlumb language version into stats properties and manager trait API +11/-0

Plumb language version into stats properties and manager trait API

• Adds lang_version into the Props built for stats reporting and introduces getter/setter methods for language binding version. Ensures the value is propagated consistently wherever stats props are constructed.

rust/src/lib.rs

main.rsAdd --language-version CLI flag and set config from args +5/-0

Add --language-version CLI flag and set config from args

• Introduces a new CLI option --language-version and documents accepted formats. Passes the parsed value into Selenium Manager configuration for use in stats reporting.

rust/src/main.rs

metadata.rsInclude language version in stats metadata storage and dedupe logic +3/-0

Include language version in stats metadata storage and dedupe logic

• Extends the Stats metadata record with lang_version and includes it in metadata matching logic. Ensures caching/TTL behavior correctly differentiates stats records by language version.

rust/src/metadata.rs

stats.rsAdd language version to stats Props schema +1/-0

Add language version to stats Props schema

• Adds lang_version to the Props struct used to build stats payloads. This completes the schema path from CLI/config through to metadata and reporting.

rust/src/stats.rs

Tests (1) +9 / -1
selenium_manager_tests.pyUpdate Python Selenium Manager tests for language-version argument +9/-1

Update Python Selenium Manager tests for language-version argument

• Updates the expected subprocess argument list to include --language-version and the current Python major.minor. Ensures tests validate the new invocation contract.

py/test/selenium/webdriver/common/selenium_manager_tests.py

Documentation (1) +4 / -4
README.mdDocument pin_browsers defaulting and remove overrides from examples +4/-4

Document pin_browsers defaulting and remove overrides from examples

• Updates the Bazel option documentation to emphasize using --pin_browsers=false to rely on Selenium Manager. Also removes explicit pin_browsers overrides from .NET test command examples.

README.md

Other (7) +27 / -23
.bazelrc.remoteStop forcing pinned browsers in remote Bazel config +0/-3

Stop forcing pinned browsers in remote Bazel config

• Removes the remote build configuration that always enabled pinned browsers. This aligns remote builds with the new defaulting behavior set in the shared Bazel flag definition.

.bazelrc.remote

ci-dotnet.ymlDrop explicit --pin_browsers=true in .NET CI runs +1/-1

Drop explicit --pin_browsers=true in .NET CI runs

• Simplifies the Bazel test invocation by removing an explicit pin_browsers override. CI now relies on the default pin_browsers behavior.

.github/workflows/ci-dotnet.yml

ci-java.ymlDrop explicit --pin_browsers=true in Java CI runs +3/-3

Drop explicit --pin_browsers=true in Java CI runs

• Removes the pin_browsers override from multiple Java workflow test commands. This keeps CI aligned with the Bazel flag default and reduces workflow drift.

.github/workflows/ci-java.yml

ci-python.ymlDrop explicit --pin_browsers=true in Python CI runs +3/-3

Drop explicit --pin_browsers=true in Python CI runs

• Updates Linux/Windows/macOS Python browser test jobs to stop passing the pin_browsers override. The jobs now rely on the shared default behavior.

.github/workflows/ci-python.yml

ci-ruby.ymlDrop explicit --pin_browsers in Ruby CI runs +0/-2

Drop explicit --pin_browsers in Ruby CI runs

• Removes the pin_browsers option from Ruby workflow Bazel invocations for both local and remote integration jobs. This reduces special-case CI configuration.

.github/workflows/ci-ruby.yml

BUILD.bazelDefault pin_browsers to true and retain use_pinned_browser setting +8/-8

Default pin_browsers to true and retain use_pinned_browser setting

• Changes the pin_browsers bool_flag default to True so pinned browser behavior is the standard path. Keeps the use_pinned_browser config_setting available for select() usage elsewhere.

common/BUILD.bazel

BUILD.bazelSelect downloaded vs locally built Selenium Manager by pin_browsers +12/-3

Select downloaded vs locally built Selenium Manager by pin_browsers

• Makes Selenium Manager aliases conditional: use the downloaded pinned Selenium Manager when pin_browsers is enabled, otherwise use the locally built Rust targets. This supports test runs that rely on building Selenium Manager in-repo.

common/manager/BUILD.bazel

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (4) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 42 rules

Grey Divider


Action required

1. Trait language-version methods undocumented 📘 Rule violation ✧ Quality
Description
New public trait methods get_language_binding_version and set_language_binding_version were
added without Rust doc comments, and the setter lacks required # Arguments documentation. This
violates the requirement to document public API items with structured doc comments, reducing API
clarity for downstream users.
Code

rust/src/lib.rs[R1609-1617]

+    fn get_language_binding_version(&self) -> &str {
+        self.get_config().language_binding_version.as_str()
+    }
+
+    fn set_language_binding_version(&mut self, language_binding_version: String) {
+        if !language_binding_version.is_empty() {
+            self.get_config_mut().language_binding_version = language_binding_version;
+        }
+    }
Evidence
The checklist requires public Rust API items (including public trait methods) to have /// doc
comments and structured sections like # Arguments when parameters exist. The added methods in
rust/src/lib.rs have no /// documentation.

Rule 389230: Document public API items with structured doc comments
rust/src/lib.rs[1609-1617]

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

## Issue description
New public trait methods were added without Rust `///` documentation, and the setter is missing a structured `# Arguments` section.

## Issue Context
This is part of the public `SeleniumManager` trait API, so it must be documented with structured Rust doc comments.

## Fix Focus Areas
- rust/src/lib.rs[1609-1617]

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


2. lang_version field undocumented 📘 Rule violation ✧ Quality
Description
A new public field lang_version was added to Props without any Rust doc comment (///)
describing its meaning. This violates the requirement to document public API items with structured
doc comments, making the public data contract unclear.
Code

rust/src/stats.rs[49]

+    pub lang_version: String,
Evidence
The checklist requires public Rust API items to be documented with /// doc comments. The newly
added public lang_version field appears with no accompanying /// doc comment.

Rule 389230: Document public API items with structured doc comments
rust/src/stats.rs[42-51]

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

## Issue description
A new public struct field was added without a Rust doc comment explaining what it represents.

## Issue Context
`Props` is in a `pub mod` and has `pub` fields, so changes add/extend public API surface that must be documented.

## Fix Focus Areas
- rust/src/stats.rs[43-51]

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


3. lang_version metadata undocumented 📘 Rule violation ✧ Quality
Description
A new public field lang_version was added to the public Stats metadata struct without any Rust
doc comment (///) describing its meaning. This violates the requirement to document public API
items with structured doc comments and makes the metadata schema harder to consume correctly.
Code

rust/src/metadata.rs[35]

+    pub lang_version: String,
Evidence
The checklist requires public Rust API items to have /// doc comments. The new lang_version
field in the public Stats struct has no /// doc comment describing it.

Rule 389230: Document public API items with structured doc comments
rust/src/metadata.rs[28-38]

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

## Issue description
A new public metadata field was added without Rust `///` documentation.

## Issue Context
`Stats` is a public struct in a public module and is serialized/deserialized, so its fields form a public schema that must be documented.

## Fix Focus Areas
- rust/src/metadata.rs[28-38]

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


View more (2)
4. language_binding_version undocumented 📘 Rule violation ✧ Quality
Description
A new public field language_binding_version was added to ManagerConfig without any Rust doc
comment (///) explaining its purpose/format. This violates the requirement to document public API
items with structured doc comments and reduces maintainability of this public configuration surface.
Code

rust/src/config.rs[67]

+    pub language_binding_version: String,
Evidence
The checklist requires public Rust API items to be documented with /// doc comments. The new
public language_binding_version field was added without any /// comment describing it.

Rule 389230: Document public API items with structured doc comments
rust/src/config.rs[50-72]

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

## Issue description
A new public configuration field was introduced without Rust `///` documentation.

## Issue Context
`ManagerConfig` is a public struct in a public module, so new fields expand the public API and must be documented.

## Fix Focus Areas
- rust/src/config.rs[50-72]

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


5. Metadata cache incompatible 🐞 Bug ☼ Reliability
Description
rust/src/metadata.rs adds a new required Stats.lang_version field without a serde default, so
older se-metadata.json files will fail deserialization and get_metadata() will drop the entire
cache. That can force online lookups and can fail outright in offline mode when driver/browser
versions are expected to be served from cached metadata.
Code

rust/src/metadata.rs[35]

+    pub lang_version: String,
Evidence
Stats is deserialized from se-metadata.json and the new non-optional lang_version makes older
JSON invalid; get_metadata() replaces the entire metadata on any deserialize error. Browser
manager implementations (e.g., Chrome) depend on this metadata to avoid online lookups and
explicitly error if offline when metadata misses.

rust/src/metadata.rs[28-38]
rust/src/metadata.rs[83-104]
rust/src/chrome.rs[289-310]

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

## Issue description
A new required JSON field (`Stats.lang_version`) was added to the metadata schema, but deserialization does not provide a default. Existing metadata files created by older Selenium Manager versions (without `lang_version`) will fail `serde_json` deserialization, and the current error handling replaces the entire metadata with an empty one.

## Issue Context
The metadata cache is used for TTL-based reuse of discovered browser/driver versions. When it is dropped, Selenium Manager may require online requests again, and in offline mode this can cause failures.

## Fix Focus Areas
- rust/src/metadata.rs[28-38]
- rust/src/metadata.rs[83-104]
- rust/src/chrome.rs[289-310]

## Suggested fix
Make the new field backward-compatible by providing a serde default (or making it optional):
- Option A (simplest):
 - Add `#[serde(default)]` to `lang_version: String` in `Stats`.
- Option B:
 - Change to `pub lang_version: Option<String>` with `#[serde(default)]`, and treat `None` as "" when comparing.

After the change, older metadata will continue to parse and preserve cached driver/browser entries, while newer versions will still write/read `lang_version`.

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


Grey Divider

Qodo Logo

Comment thread rust/src/lib.rs
Comment on lines +1609 to +1617
fn get_language_binding_version(&self) -> &str {
self.get_config().language_binding_version.as_str()
}

fn set_language_binding_version(&mut self, language_binding_version: String) {
if !language_binding_version.is_empty() {
self.get_config_mut().language_binding_version = language_binding_version;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

1. Trait language-version methods undocumented 📘 Rule violation ✧ Quality

New public trait methods get_language_binding_version and set_language_binding_version were
added without Rust doc comments, and the setter lacks required # Arguments documentation. This
violates the requirement to document public API items with structured doc comments, reducing API
clarity for downstream users.
Agent Prompt
## Issue description
New public trait methods were added without Rust `///` documentation, and the setter is missing a structured `# Arguments` section.

## Issue Context
This is part of the public `SeleniumManager` trait API, so it must be documented with structured Rust doc comments.

## Fix Focus Areas
- rust/src/lib.rs[1609-1617]

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

Comment thread rust/src/stats.rs
pub os: String,
pub arch: String,
pub lang: String,
pub lang_version: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

2. lang_version field undocumented 📘 Rule violation ✧ Quality

A new public field lang_version was added to Props without any Rust doc comment (///)
describing its meaning. This violates the requirement to document public API items with structured
doc comments, making the public data contract unclear.
Agent Prompt
## Issue description
A new public struct field was added without a Rust doc comment explaining what it represents.

## Issue Context
`Props` is in a `pub mod` and has `pub` fields, so changes add/extend public API surface that must be documented.

## Fix Focus Areas
- rust/src/stats.rs[43-51]

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

Comment thread rust/src/metadata.rs
pub os: String,
pub arch: String,
pub lang: String,
pub lang_version: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

3. lang_version metadata undocumented 📘 Rule violation ✧ Quality

A new public field lang_version was added to the public Stats metadata struct without any Rust
doc comment (///) describing its meaning. This violates the requirement to document public API
items with structured doc comments and makes the metadata schema harder to consume correctly.
Agent Prompt
## Issue description
A new public metadata field was added without Rust `///` documentation.

## Issue Context
`Stats` is a public struct in a public module and is serialized/deserialized, so its fields form a public schema that must be documented.

## Fix Focus Areas
- rust/src/metadata.rs[28-38]

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

Comment thread rust/src/config.rs
pub force_browser_download: bool,
pub avoid_browser_download: bool,
pub language_binding: String,
pub language_binding_version: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

4. language_binding_version undocumented 📘 Rule violation ✧ Quality

A new public field language_binding_version was added to ManagerConfig without any Rust doc
comment (///) explaining its purpose/format. This violates the requirement to document public API
items with structured doc comments and reduces maintainability of this public configuration surface.
Agent Prompt
## Issue description
A new public configuration field was introduced without Rust `///` documentation.

## Issue Context
`ManagerConfig` is a public struct in a public module, so new fields expand the public API and must be documented.

## Fix Focus Areas
- rust/src/config.rs[50-72]

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

Comment thread rust/src/metadata.rs
pub os: String,
pub arch: String,
pub lang: String,
pub lang_version: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

5. Metadata cache incompatible 🐞 Bug ☼ Reliability

rust/src/metadata.rs adds a new required Stats.lang_version field without a serde default, so
older se-metadata.json files will fail deserialization and get_metadata() will drop the entire
cache. That can force online lookups and can fail outright in offline mode when driver/browser
versions are expected to be served from cached metadata.
Agent Prompt
## Issue description
A new required JSON field (`Stats.lang_version`) was added to the metadata schema, but deserialization does not provide a default. Existing metadata files created by older Selenium Manager versions (without `lang_version`) will fail `serde_json` deserialization, and the current error handling replaces the entire metadata with an empty one.

## Issue Context
The metadata cache is used for TTL-based reuse of discovered browser/driver versions. When it is dropped, Selenium Manager may require online requests again, and in offline mode this can cause failures.

## Fix Focus Areas
- rust/src/metadata.rs[28-38]
- rust/src/metadata.rs[83-104]
- rust/src/chrome.rs[289-310]

## Suggested fix
Make the new field backward-compatible by providing a serde default (or making it optional):
- Option A (simplest):
  - Add `#[serde(default)]` to `lang_version: String` in `Stats`.
- Option B:
  - Change to `pub lang_version: Option<String>` with `#[serde(default)]`, and treat `None` as "" when comparing.

After the change, older metadata will continue to parse and preserve cached driver/browser entries, while newer versions will still write/read `lang_version`.

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

@github-actions github-actions Bot removed the J-stale Applied to issues that become stale, and eventually closed. label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-manager Selenium Manager C-dotnet .NET Bindings C-java Java Bindings C-nodejs JavaScript Bindings C-py Python Bindings C-rb Ruby Bindings C-rust Rust code is mostly Selenium Manager Review effort 3/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants