Skip to content

[rb] add ClientConfig for HTTP client customization - #17699

Merged
titusfortner merged 3 commits into
trunkfrom
client_config-rb
Jun 26, 2026
Merged

[rb] add ClientConfig for HTTP client customization#17699
titusfortner merged 3 commits into
trunkfrom
client_config-rb

Conversation

@titusfortner

Copy link
Copy Markdown
Member

🔗 Related Issues

Implements Ruby portion of #12368 and replaces previous implementation #16486

💥 What does this PR do?

  • Adds a ClientConfig for Ruby that centralizes HTTP transport settings for: open/read timeouts, max redirects, proxy, extra headers, user-agent, and server URL
  • Users can pass this or an HTTP Client instance to any driver constructor, but not both
  • ClientConfig owns the defaults

🔧 Implementation Notes

  • Using the read-timeout default change recommended in [🚀 Feature]: Configurable HTTP Client settings across bindings #12368 (60s → 120s).
  • Decouples http client creation from the Bridge; the Bridge only sees the http_client instance
  • The HTTP Client instance stores the client config and makes it accessible to the Bridge for future compatibility (socket information)
  • The implementation in [rb] implement client config class #16486 was an immutable Data class, but that's the wrong approach; this should take the same approach as Options allowing setting values after creation before usage

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code
    • What was generated: Implementation, tests, and type signatures
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

  • Consider deprecating http_client as a parameter the user can pass in and require everyone to use ClientConfig
  • Deprecate the legacy Http::Common class methods in favor of ClientConfig class methods
  • ClientConfig is positioned to carry the WebSocket settings for the BiDi follow-up.

🔄 Types of changes

  • New feature (non-breaking change which adds functionality and tests!)
  • Breaking change (default read timeout 60s → 120s)

@selenium-ci selenium-ci added the C-rb Ruby Bindings label Jun 21, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Add ClientConfig to centralize Ruby HTTP client customization
✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

Description

• Introduce ClientConfig to centralize HTTP transport defaults and per-driver overrides.
• Decouple Bridge from URL handling by requiring a configured http_client instance.
• Update drivers, type signatures, and tests to enforce mutually exclusive
 http_client/client_config.
Diagram

graph TD
  D["Browser Drivers"] --> LD["LocalDriver"] --> HTTP["Remote::Http::Default"] --> BR["Remote::Bridge/BiDiBridge"]
  RD["Remote::Driver"] --> HTTP
  SVC["Local Service"] --> LD
  CFG(["ClientConfig"]) --> HTTP
  CFG --> ENV{{"Proxy ENV"}}
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make ClientConfig the only supported customization API (deprecate http_client param)
  • ➕ Removes ambiguous wiring rules and double-configuration hazards
  • ➕ Enables consistent future additions (e.g., WebSocket/BiDi settings)
  • ➖ Breaks advanced users supplying custom HTTP adapters today
  • ➖ Requires a migration/deprecation plan and timeline
2. Keep Bridge accepting url: and constructing the default HTTP client internally
  • ➕ Minimizes churn in Bridge/Driver APIs and existing tests
  • ➕ Keeps the 'single argument (url)' ergonomics for simple usage
  • ➖ Re-couples Bridge to client construction and config evolution
  • ➖ Harder to expose connection details (e.g., sockets) through a single transport object
3. Provide a ClientConfig#build_http_client factory method
  • ➕ Gives users an explicit supported way to obtain a configured transport
  • ➕ Keeps configuration + instantiation co-located and testable
  • ➖ Adds another public surface area to maintain
  • ➖ Doesn't eliminate the need to validate 'http_client vs client_config' at call sites

Recommendation: The PR’s approach (ClientConfig as the single source of transport defaults, with Driver wiring a configured http_client and Bridge depending only on that client) is the best long-term direction for extensibility and BiDi/WebSocket follow-ups. Consider adding an explicit deprecation plan for passing :http_client (or at least documenting the precedence/compat rules prominently) to reduce long-term API complexity.

Files changed (37) +416 / -128

Enhancement (9) +166 / -47
driver.rbAllow Chrome::Driver to accept http_client or client_config +3/-3

Allow Chrome::Driver to accept http_client or client_config

• Extends the initializer signature to accept :http_client and :client_config, and routes local initialization through a configured HTTP client instead of a raw URL.

rb/lib/selenium/webdriver/chrome/driver.rb

client_config.rbIntroduce ClientConfig for HTTP transport defaults and overrides +88/-0

Introduce ClientConfig for HTTP transport defaults and overrides

• Adds a mutable ClientConfig object that centralizes timeouts, redirects, proxy resolution, extra headers, user-agent, and optional server_url normalization.

rb/lib/selenium/webdriver/common/client_config.rb

local_driver.rbWire local services through an HTTP client configured via ClientConfig +13/-4

Wire local services through an HTTP client configured via ClientConfig

• Builds a default HTTP client using ClientConfig, sets the service-provided server_url on it, and enforces that callers cannot set server URL or provide both http_client and client_config.

rb/lib/selenium/webdriver/common/local_driver.rb

driver.rbAllow Edge::Driver to accept http_client or client_config +3/-3

Allow Edge::Driver to accept http_client or client_config

• Extends the initializer signature and passes a configured HTTP client into the base driver instead of passing a URL.

rb/lib/selenium/webdriver/edge/driver.rb

driver.rbAllow Firefox::Driver to accept http_client or client_config +3/-3

Allow Firefox::Driver to accept http_client or client_config

• Extends the initializer signature and routes local initialization through a configured HTTP client.

rb/lib/selenium/webdriver/firefox/driver.rb

driver.rbAllow IE::Driver to accept http_client or client_config +3/-3

Allow IE::Driver to accept http_client or client_config

• Extends the initializer signature and routes local initialization through a configured HTTP client.

rb/lib/selenium/webdriver/ie/driver.rb

driver.rbBuild Remote::Driver HTTP transport from client_config and resolve server URL +6/-3

Build Remote::Driver HTTP transport from client_config and resolve server URL

• Adds :client_config support, enforces mutual exclusion with :http_client, and ensures the resolved server URL is written onto the HTTP client (and its underlying config).

rb/lib/selenium/webdriver/remote/driver.rb

default.rbBack Http::Default timeouts, redirects, and proxy behavior with ClientConfig +44/-25

Back Http::Default timeouts, redirects, and proxy behavior with ClientConfig

• Accepts client_config (or legacy direct timeouts), enforces exclusivity, uses config-driven max_redirects/proxy, and changes the default read timeout to 120 seconds.

rb/lib/selenium/webdriver/remote/http/default.rb

driver.rbAllow Safari::Driver to accept http_client or client_config +3/-3

Allow Safari::Driver to accept http_client or client_config

• Extends the initializer signature and routes local initialization through a configured HTTP client.

rb/lib/selenium/webdriver/safari/driver.rb

Refactor (4) +31 / -24
common.rbLoad ClientConfig in common WebDriver requires +1/-0

Load ClientConfig in common WebDriver requires

• Adds the new ClientConfig to the common require list so it is available across the Ruby bindings.

rb/lib/selenium/webdriver/common.rb

driver.rbCreate bridges using only a configured http_client +2/-2

Create bridges using only a configured http_client

• Removes URL handling from create_bridge and requires callers to supply a fully configured HTTP client instance.

rb/lib/selenium/webdriver/common/driver.rb

bridge.rbRequire Bridge to be initialized with a configured http_client +3/-10

Require Bridge to be initialized with a configured http_client

• Removes Bridge URL parsing and default HTTP client creation; Bridge now depends only on an injected HTTP client.

rb/lib/selenium/webdriver/remote/bridge.rb

common.rbMove headers, user-agent, and server_url storage into ClientConfig +25/-12

Move headers, user-agent, and server_url storage into ClientConfig

• Makes Http::Common hold a ClientConfig instance, deriving default User-Agent/extra headers from ClientConfig class defaults and resolving server_url through the config.

rb/lib/selenium/webdriver/remote/http/common.rb

Tests (11) +146 / -33
driver_spec.rbAdd local-driver argument validation coverage for client_config/http_client +13/-0

Add local-driver argument validation coverage for client_config/http_client

• Adds unit tests asserting local drivers reject client_config.server_url and reject providing both http_client and client_config.

rb/spec/unit/selenium/webdriver/chrome/driver_spec.rb

service_spec.rbAdjust Chrome service spec for new server URL validation message +1/-1

Adjust Chrome service spec for new server URL validation message

• Updates expected error matching for providing :url now that validation is centralized in LocalDriver.

rb/spec/unit/selenium/webdriver/chrome/service_spec.rb

service_spec.rbAdjust Edge service spec for new server URL validation message +1/-1

Adjust Edge service spec for new server URL validation message

• Updates expected error matching for providing :url now that validation is centralized in LocalDriver.

rb/spec/unit/selenium/webdriver/edge/service_spec.rb

service_spec.rbAdjust Firefox service spec for new server URL validation message +1/-1

Adjust Firefox service spec for new server URL validation message

• Updates expected error matching for providing :url now that validation is centralized in LocalDriver.

rb/spec/unit/selenium/webdriver/firefox/service_spec.rb

service_spec.rbAdjust IE service spec for new server URL validation message +1/-1

Adjust IE service spec for new server URL validation message

• Updates expected error matching for providing :url now that validation is centralized in LocalDriver.

rb/spec/unit/selenium/webdriver/ie/service_spec.rb

bridge_spec.rbUpdate Bridge specs to inject configured http_client without url +9/-13

Update Bridge specs to inject configured http_client without url

• Refactors Bridge tests to set server_url on the HTTP client and verify Bridge uses the provided client instance.

rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb

driver_spec.rbAdd Remote::Driver tests for client_config wiring and URL resolution +25/-0

Add Remote::Driver tests for client_config wiring and URL resolution

• Adds coverage for building an HTTP client from client_config, persisting the resolved server_url back onto the config, and rejecting http_client+client_config together.

rb/spec/unit/selenium/webdriver/remote/driver_spec.rb

features_spec.rbUpdate Features specs to inject configured http_client without url +4/-2

Update Features specs to inject configured http_client without url

• Updates test setup to configure server_url on the HTTP client before constructing the Bridge.

rb/spec/unit/selenium/webdriver/remote/features_spec.rb

common_spec.rbUpdate Http::Common specs to use ClientConfig overrides +26/-10

Update Http::Common specs to use ClientConfig overrides

• Shifts header/User-Agent tests from global Http::Common setters to per-client ClientConfig, while keeping the legacy global setter behavior working via ClientConfig defaults.

rb/spec/unit/selenium/webdriver/remote/http/common_spec.rb

default_spec.rbUpdate Http::Default specs for ClientConfig defaults and redirect limits +64/-3

Update Http::Default specs for ClientConfig defaults and redirect limits

• Updates default read timeout expectation (120s), adds initialization exclusivity tests, validates config-driven fields, and adds max_redirects behavior coverage.

rb/spec/unit/selenium/webdriver/remote/http/default_spec.rb

service_spec.rbAdjust Safari service spec for new server URL validation message +1/-1

Adjust Safari service spec for new server URL validation message

• Updates expected error matching for providing :url now that validation is centralized in LocalDriver.

rb/spec/unit/selenium/webdriver/safari/service_spec.rb

Other (13) +73 / -24
.rubocop.ymlRelax keyword-arg counting for parameter list metrics +3/-0

Relax keyword-arg counting for parameter list metrics

• Configures Metrics/ParameterLists to not count keyword arguments, reducing RuboCop noise for expanded initializer signatures.

rb/.rubocop.yml

driver.rbsUpdate Chrome::Driver initializer types for client_config/http_client +1/-1

Update Chrome::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/chrome/driver.rbs

client_config.rbsAdd RBS for ClientConfig API +36/-0

Add RBS for ClientConfig API

• Introduces type signatures for ClientConfig fields, defaults, and server_url normalization setter.

rb/sig/lib/selenium/webdriver/common/client_config.rbs

driver.rbsTighten create_bridge signature to require http_client only +1/-1

Tighten create_bridge signature to require http_client only

• Updates the RBS to reflect that create_bridge no longer accepts a URL and returns a Remote::Bridge with a typed http_client parameter.

rb/sig/lib/selenium/webdriver/common/driver.rbs

local_driver.rbsUpdate LocalDriver signatures for http_client/client_config validation +3/-1

Update LocalDriver signatures for http_client/client_config validation

• Updates initialize_local_driver to accept http_client and client_config and adds assert_local_arguments typing.

rb/sig/lib/selenium/webdriver/common/local_driver.rbs

driver.rbsUpdate Edge::Driver initializer types for client_config/http_client +1/-1

Update Edge::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/edge/driver.rbs

driver.rbsUpdate Firefox::Driver initializer types for client_config/http_client +1/-1

Update Firefox::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/firefox/driver.rbs

driver.rbsUpdate IE::Driver initializer types for client_config/http_client +1/-1

Update IE::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/ie/driver.rbs

bridge.rbsUpdate Bridge initializer type to require http_client only +1/-1

Update Bridge initializer type to require http_client only

• Removes url: from the Bridge initializer signature to match the injected-client model.

rb/sig/lib/selenium/webdriver/remote/bridge.rbs

driver.rbsUpdate Remote::Driver initializer types for client_config/http_client +1/-1

Update Remote::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/remote/driver.rbs

common.rbsUpdate Http::Common RBS for ClientConfig-backed configuration +13/-5

Update Http::Common RBS for ClientConfig-backed configuration

• Types the new client_config field, updated class setters, and server_url accessor type changes (String→URI).

rb/sig/lib/selenium/webdriver/remote/http/common.rbs

default.rbsUpdate Http::Default RBS for ClientConfig initialization and accessors +10/-10

Update Http::Default RBS for ClientConfig initialization and accessors

• Types the new initializer contract (client_config vs direct timeouts), adds follow_redirect signature, and refines use_proxy? return type.

rb/sig/lib/selenium/webdriver/remote/http/default.rbs

driver.rbsUpdate Safari::Driver initializer types for client_config/http_client +1/-1

Update Safari::Driver initializer types for client_config/http_client

• Adds client_config and http_client keyword args to the RBS initializer signature.

rb/sig/lib/selenium/webdriver/safari/driver.rbs

@qodo-code-review

qodo-code-review Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (9) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 19 rules

Grey Divider


Action required

1. Redirect leaks extra headers 🐞 Bug ⛨ Security
Description
Remote::Http::Default#follow_redirect replays redirected requests using common_headers, so
ClientConfig.extra_headers (e.g., Authorization/Cookie) are sent to whatever host appears in the
Location header without any origin checks. This can leak credentials/session tokens if a redirect
crosses hosts.
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R126-131]

+          def follow_redirect(response, redirects)
+            WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
+            raise Error::WebDriverError, 'too many redirects' if redirects >= client_config.max_redirects
+
+            request(:get, URI.parse(response['Location']), common_headers.dup, nil, redirects + 1)
+          end
Evidence
Redirects are followed by calling request() with common_headers, and common_headers is built by
merging in client_config.extra_headers, which are documented as additional headers sent with each
request; no host/origin check is performed before reusing them for the redirect target.

rb/lib/selenium/webdriver/remote/http/default.rb[126-131]
rb/lib/selenium/webdriver/remote/http/common.rb[93-99]
rb/lib/selenium/webdriver/common/client_config.rb[42-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
`Remote::Http::Default#follow_redirect` re-issues redirected requests with `common_headers`, which includes `ClientConfig.extra_headers`. If the redirect `Location` points to a different host, this forwards potentially sensitive headers (e.g., `Authorization`, `Cookie`) to an unintended origin.

### Issue Context
- `common_headers` includes `client_config.extra_headers`.
- `follow_redirect` uses those headers unconditionally for the next request.

### Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/default.rb[126-131]

### Suggested fix approach
- Parse the redirect URL and compare its origin (scheme/host/port) to `server_url`.
- If the redirect target is cross-origin, either:
 - drop `client_config.extra_headers` entirely, or
 - explicitly strip sensitive headers (`Authorization`, `Cookie`, `Proxy-Authorization`) while keeping safe ones like `User-Agent`.
- Keep current behavior for same-origin redirects.

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


2. assert_local_arguments missing @api private ✓ Resolved 📘 Rule violation ✧ Quality
Description
assert_local_arguments appears to be an internal helper but is introduced as a public method
without a YARD @api private marker. This expands the public surface area unintentionally and
violates the internal-API marking requirement.
Code

rb/lib/selenium/webdriver/common/local_driver.rb[R39-45]

+      def assert_local_arguments(url, http_client, client_config)
+        if url || client_config&.server_url
+          raise ArgumentError, "Can't set the server URL for #{self.class}; the service provides it"
+        elsif http_client && client_config
+          raise ArgumentError, 'Cannot use both :http_client and :client_config'
+        end
+      end
Evidence
The checklist requires internal Ruby APIs to be marked with # @api private in the YARD doc block.
The new assert_local_arguments helper is added without any @api private marker and is not made
private via Ruby visibility controls.

Rule 389237: Mark internal Ruby APIs with @api private in YARD docs
rb/lib/selenium/webdriver/common/local_driver.rb[39-45]

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 internal helper method (`assert_local_arguments`) is publicly exposed and lacks a `# @api private` YARD tag.

## Issue Context
This helper is used only to validate constructor arguments for local drivers and is not intended as a supported API.

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/local_driver.rb[39-45]

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


3. ClientConfig#initialize lacks YARD ✓ Resolved 📘 Rule violation ✧ Quality
Description
The new public ClientConfig API is missing YARD @param/@return documentation for its
initializer and accessors, making the public contract unclear for users. This violates the
requirement to document public API methods with YARD tags.
Code

rb/lib/selenium/webdriver/common/client_config.rb[R24-74]

+    #
+    # Configuration for HTTP clients.
+    #
+
+    class ClientConfig
+      class << self
+        attr_accessor :default_extra_headers
+        attr_writer :default_user_agent
+
+        def default_user_agent
+          @default_user_agent ||= "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})"
+        end
+      end
+
+      attr_accessor :open_timeout, :read_timeout, :max_redirects, :proxy
+      attr_writer :extra_headers, :user_agent
+      attr_reader :server_url
+
+      def initialize(open_timeout: 60,
+                     read_timeout: 120,
+                     max_redirects: 20,
+                     proxy: nil,
+                     extra_headers: nil,
+                     user_agent: nil,
+                     server_url: nil)
+        @open_timeout = open_timeout
+        @read_timeout = read_timeout
+        @max_redirects = max_redirects
+        @proxy = proxy || proxy_from_environment
+        @extra_headers = extra_headers
+        @user_agent = user_agent
+        self.server_url = server_url
+      end
+
+      def user_agent
+        @user_agent || self.class.default_user_agent
+      end
+
+      def extra_headers
+        @extra_headers || self.class.default_extra_headers
+      end
+
+      def server_url=(url)
+        if url.nil?
+          @server_url = nil
+        else
+          url = url.to_s
+          url += '/' unless url.end_with?('/')
+          @server_url = URI.parse(url)
+        end
+      end
Evidence
PR Compliance ID 389240 requires public Ruby API methods to include YARD documentation with a
description plus @param tags for all parameters and a @return tag. The new ClientConfig class
and its #initialize definition are added without any such YARD tags above the method definition.

Rule 389240: Document public API methods with YARD tags
rb/lib/selenium/webdriver/common/client_config.rb[24-74]

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

## Issue description
`Selenium::WebDriver::ClientConfig` appears to be a new public API (no `@api private` tag), but its methods (notably `#initialize`) lack the required YARD documentation (`@param`, `@return`, and any relevant `@raise`).

## Issue Context
The compliance checklist requires all public API methods in changed code to be documented with YARD tags and a short description.

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[24-74]

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


View more (1)
4. instance_double introduced in tests ✓ Resolved 📘 Rule violation ▣ Testability
Description
New/modified unit tests introduce RSpec mocking (instance_double) instead of using a real
implementation or a simple in-memory fake. This violates the rule to avoid mocks in tests unless
backed by contract-driven integrations.
Code

rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb[R55-60]

        describe '#initialize' do
-          it 'raises ArgumentError if passed invalid options' do
-            expect { described_class.new(foo: 'bar') }.to raise_error(ArgumentError)
+          it 'uses the provided http client' do
+            custom_http = instance_double(Remote::Http::Default)
+            bridge = described_class.new(http_client: custom_http)
+            expect(bridge.http).to eq(custom_http)
          end
Evidence
PR Compliance ID 389270 disallows introducing mocking frameworks in touched tests unless they are
contract-driven. The PR adds instance_double(Remote::Http::Default) in bridge_spec and
instance_double(Proxy) in default_spec, which are new mocking usages in the modified code.

Rule 389270: Avoid mocks in tests; use real or contract-driven integrations
rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb[55-60]
rb/spec/unit/selenium/webdriver/remote/http/default_spec.rb[67-86]

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

## Issue description
The changed tests use RSpec mocks (`instance_double`), which is disallowed by the compliance rule unless the mock is contract-backed; these tests can use a small fake object or a real HTTP client instance configured for the test.

## Issue Context
This PR adds/changes tests around HTTP client/config plumbing; these behaviors can typically be validated with a minimal fake that implements the required interface without using a mocking framework.

## Fix Focus Areas
- rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb[55-60]
- rb/spec/unit/selenium/webdriver/remote/http/default_spec.rb[67-86]

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



Remediation recommended

5. Curb ignores redirect config 🐞 Bug ≡ Correctness
Description
Remote::Http::Default now enforces redirect limits via ClientConfig#max_redirects, but
Remote::Http::Curb still hard-codes MAX_REDIRECTS, so changing max_redirects on the shared
client_config has no effect when using Curb. This creates inconsistent redirect behavior across HTTP
transports and can break users who switch clients expecting ClientConfig settings to apply
uniformly.
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R126-131]

+          def follow_redirect(response, redirects)
+            WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
+            raise Error::WebDriverError, 'too many redirects' if redirects >= client_config.max_redirects
+
+            request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
+          end
Evidence
The new Default redirect behavior is driven by client_config.max_redirects, but Curb still reads
the old constant, so a config change won’t be honored when using the Curb transport.

rb/lib/selenium/webdriver/remote/http/default.rb[118-131]
rb/lib/selenium/webdriver/remote/http/common.rb[24-31]
rb/lib/selenium/webdriver/remote/http/curb.rb[84-93]

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

## Issue description
`Remote::Http::Default` now uses `client_config.max_redirects` to cap redirects, but `Remote::Http::Curb` still uses the legacy `MAX_REDIRECTS` constant. As a result, `ClientConfig#max_redirects` is ignored when users choose the Curb transport.

## Issue Context
- `Remote::Http::Common` still defines `MAX_REDIRECTS = 20`.
- `Remote::Http::Default#follow_redirect` enforces redirects with `client_config.max_redirects`.
- `Remote::Http::Curb#client` sets `c.max_redirects = MAX_REDIRECTS`.

## Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/curb.rb[84-93]
- rb/lib/selenium/webdriver/remote/http/common.rb[24-31]
- rb/lib/selenium/webdriver/remote/http/default.rb[126-131]

## Suggested fix
- Change `Remote::Http::Curb#client` to set `c.max_redirects = client_config.max_redirects` (and ensure it’s applied at client creation time).
- Optionally remove or clearly document `MAX_REDIRECTS` to avoid future divergence, or keep it only for backward-compat while making the default source of truth `ClientConfig#max_redirects`.

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


6. client_config interface unvalidated 🐞 Bug ☼ Reliability
Description
Remote::Http::Default assumes any provided :client_config responds to ClientConfig’s accessors
(open_timeout/read_timeout/proxy/server_url), so passing an incompatible object triggers
NoMethodError during initialization. Since :client_config is now a public driver/HTTP-client
parameter, this produces a confusing runtime failure instead of a clear ArgumentError.
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R33-41]

+          def initialize(client_config: nil, open_timeout: nil, read_timeout: nil)
+            if client_config && (open_timeout || read_timeout)
+              raise ArgumentError, 'Cannot use both :client_config and :open_timeout/:read_timeout'
+            end
+
+            client_config ||= ClientConfig.new
+            client_config.open_timeout = open_timeout if open_timeout
+            client_config.read_timeout = read_timeout if read_timeout
+            super(client_config: client_config)
Evidence
Default#initialize calls open_timeout=/read_timeout= on the provided client_config without any
checks, and Remote::Driver forwards the user-supplied client_config directly into Default.new,
making a misuse crash likely and hard to diagnose.

rb/lib/selenium/webdriver/remote/http/default.rb[33-42]
rb/lib/selenium/webdriver/remote/driver.rb[34-41]
rb/lib/selenium/webdriver/common/local_driver.rb[23-30]

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

### Issue description
The new `:client_config` parameter is accepted publicly, but `Remote::Http::Default#initialize` immediately calls methods on it (e.g., `open_timeout=`). If a caller passes a non-conforming object, they get a `NoMethodError` instead of a clear `ArgumentError` explaining the expected interface.

### Issue Context
Ruby supports duck typing, so either:
- explicitly require `ClientConfig` instances, or
- validate required methods (`server_url=`, `open_timeout`, `open_timeout=`, `read_timeout`, `read_timeout=`, `max_redirects`, `proxy`) and raise a targeted `ArgumentError` when missing.

### Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/default.rb[33-42]
- rb/lib/selenium/webdriver/remote/driver.rb[34-41]
- rb/lib/selenium/webdriver/common/local_driver.rb[23-30]

### Suggested fix approach
- Add a guard in `Remote::Http::Default#initialize` (and/or in driver constructors) that rejects non-conforming `client_config` with a clear message.
- If you want to preserve duck-typing, check `respond_to?` for the required methods; otherwise check `is_a?(Selenium::WebDriver::ClientConfig)`.

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


7. read_timeout default changed to 120 📘 Rule violation ≡ Correctness
Description
The default read_timeout is changed to 120, which is user-visible behavior and called out as
breaking in the PR description, but there is no in-code evidence of cross-binding comparison. This
risks diverging defaults across language bindings without documentation.
Code

rb/lib/selenium/webdriver/common/client_config.rb[R51-53]

+      def initialize(open_timeout: 60,
+                     read_timeout: 120,
+                     max_redirects: 20,
Evidence
The checklist requires cross-language comparison when changing user-visible behavior. The diff shows
the Ruby default read_timeout is now 120, but there is no nearby documentation indicating which
other binding(s) were compared or why divergence is acceptable.

Rule 389265: Compare cross-language bindings when changing user-visible behavior
rb/lib/selenium/webdriver/common/client_config.rb[51-53]

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

## Issue description
Ruby’s default HTTP `read_timeout` is changed to 120 seconds, which may diverge from other bindings.

## Issue Context
The compliance rule requires comparing other bindings (or explicitly documenting intentional divergence) when changing user-visible behavior like defaults.

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[51-53]

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


View more (7)
8. ClientConfig server_url leaks 🐞 Bug ≡ Correctness
Description
LocalDriver#initialize_local_driver always sets http_client.server_url, which writes back into the
caller-provided ClientConfig via Remote::Http::Common#server_url=. Reusing that same ClientConfig
later can silently target a stale local service URL or make Remote::Driver raise because
ClientConfig#server_url is already set.
Code

rb/lib/selenium/webdriver/common/local_driver.rb[R28-29]

+        http_client ||= Remote::Http::Default.new(client_config: client_config)
+        http_client.server_url = service_url(service)
Evidence
LocalDriver assigns server_url on the HTTP client; in the default HTTP stack this setter stores
into client_config.server_url. Remote::Driver both uses client_config.server_url as an implicit
default and rejects :url when client_config.server_url is set, so a mutated config can cause
wrong routing or unexpected ArgumentError later.

rb/lib/selenium/webdriver/common/local_driver.rb[23-33]
rb/lib/selenium/webdriver/remote/http/common.rb[53-59]
rb/lib/selenium/webdriver/remote/driver.rb[39-54]

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

## Issue description
`LocalDriver#initialize_local_driver` mutates the user-supplied `ClientConfig` by setting `http_client.server_url`, which flows into `client_config.server_url`. This creates surprising, externally-visible state that can break reusing the same config object across multiple driver instantiations.

## Issue Context
A caller can reasonably reuse a single `ClientConfig` for shared defaults (timeouts/headers). After creating a local driver, that config now has `server_url` set to the ephemeral local service URL; a later `Remote::Driver` may use it (or reject a provided `:url`).

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/local_driver.rb[23-45]
- rb/lib/selenium/webdriver/remote/http/common.rb[53-60]
- rb/lib/selenium/webdriver/remote/driver.rb[34-54]

## Suggested fix approach
- When `client_config` is provided to a *local* driver path and an internal `Remote::Http::Default` is constructed, duplicate the config before assigning `server_url` (e.g., `effective_config = client_config&.dup`) so the service URL does not persist back into the caller’s object.
- Keep the resolved service URL accessible via `http_client.client_config.server_url` (internal), without mutating the original `ClientConfig` provided by the user.

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


9. ClientConfig load-order fragility 🐞 Bug ☼ Reliability
Description
ClientConfig references WebDriver::VERSION/Platform.os and Proxy but only requires 'uri', so calling
ClientConfig.default_user_agent or initializing when proxy env vars are set can raise NameError if
client_config.rb is required standalone or before those constants are loaded. This makes the new
public API fragile to load order.
Code

rb/lib/selenium/webdriver/common/client_config.rb[R20-35]

+require 'uri'
+
+module Selenium
+  module WebDriver
+    #
+    # Configuration for HTTP clients.
+    #
+
+    class ClientConfig
+      class << self
+        attr_accessor :default_extra_headers
+        attr_writer :default_user_agent
+
+        def default_user_agent
+          @default_user_agent ||= "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})"
+        end
Evidence
ClientConfig only requires uri but directly references constants defined in other files: VERSION,
Platform, and Proxy. Without requiring those definitions first, the referenced methods can raise
NameError when executed.

rb/lib/selenium/webdriver/common/client_config.rb[20-35]
rb/lib/selenium/webdriver/common/client_config.rb[87-94]
rb/lib/selenium/webdriver/version.rb[20-23]
rb/lib/selenium/webdriver/common/platform.rb[37-51]
rb/lib/selenium/webdriver/common/proxy.rb[20-23]

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

## Issue description
`ClientConfig` uses `WebDriver::VERSION`, `Platform.os`, and `Proxy` but does not `require` the files that define them. If a user (or internal code) loads `selenium/webdriver/common/client_config` without the broader `selenium/webdriver` load path, invoking these codepaths can raise `NameError`.

## Issue Context
This is especially relevant because `ClientConfig` is a new, user-facing entry point and may be required directly in scripts.

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[20-36]
- rb/lib/selenium/webdriver/common/client_config.rb[87-94]

## Suggested fix approach
- Add explicit requires at the top of `client_config.rb` for the constants it uses, e.g.:
 - `require 'selenium/webdriver/version'`
 - `require 'selenium/webdriver/common/platform'`
 - `require 'selenium/webdriver/common/proxy'`
- Keep `require 'uri'` as-is.

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


10. Empty proxy env breaks 🐞 Bug ☼ Reliability
Description
ClientConfig#proxy_from_environment treats an empty http_proxy/HTTP_PROXY env var as a valid proxy
(Ruby empty strings are truthy), producing an invalid proxy URL like "http://".
Remote::Http::Default then parses and uses this value to configure Net::HTTP proxy settings, which
can fail at runtime due to missing proxy host/port.
Code

rb/lib/selenium/webdriver/common/client_config.rb[R87-93]

+      def proxy_from_environment
+        proxy = ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil)
+        return unless proxy
+
+        no_proxy = ENV.fetch('no_proxy', nil) || ENV.fetch('NO_PROXY', nil)
+        proxy = "http://#{proxy}" unless proxy.match?(%r{\Ahttps?://})
+        Proxy.new(http: proxy, no_proxy: no_proxy)
Evidence
ClientConfig builds a Proxy from http_proxy/HTTP_PROXY whenever the env value is non-nil, even if it
is an empty string; that proxy is then consumed by Http::Default to build a proxied Net::HTTP
instance using URI.parse(proxy.http) and proxy host/port, which will be nil/invalid for values
like "http://".

rb/lib/selenium/webdriver/common/client_config.rb[87-94]
rb/lib/selenium/webdriver/remote/http/default.rb[147-162]
rb/lib/selenium/webdriver/remote/http/default.rb[168-187]

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

### Issue description
`ClientConfig#proxy_from_environment` currently treats an empty-string proxy environment value as a configured proxy and builds an invalid proxy URL (e.g., `"http://"`). This can later break HTTP client creation.

### Issue Context
In Ruby, `""` is truthy, so `return unless proxy` does not guard against empty environment values.

### Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[87-94]

### Suggested fix
Treat blank/whitespace-only proxy env values as unset:
- `proxy = proxy.strip`
- `return if proxy.empty?`
Optionally apply the same normalization to `no_proxy` and set it to `nil` when blank.

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


11. proxy param documents Hash ✓ Resolved 📘 Rule violation ✧ Quality
Description
ClientConfig#initialize documents proxy as accepting a Hash, but it stores the value as-is
while the HTTP stack later expects a Proxy-like object responding to methods such as http and
no_proxy. This documentation/behavior mismatch misleads users and can cause runtime errors when a
Hash is passed per the docs.
Code

rb/lib/selenium/webdriver/common/client_config.rb[46]

+      # @param [Proxy, Hash] proxy Proxy to use for the connection.
Evidence
The YARD documentation for ClientConfig#initialize advertises proxy as supporting Hash, but
Remote::Http::Default later dereferences the configured proxy via calls like proxy.http and
proxy.no_proxy (e.g., in #use_proxy? and when building the HTTP client), which implies the value
must be a Selenium::WebDriver::Proxy (or at least an object that responds to those methods) rather
than a plain Hash; since ClientConfig does not normalize/convert Hashes, a Hash provided according
to the docs will fail at runtime, violating the expectation that public API YARD tags accurately
describe supported parameter types.

Rule 389240: Document public API methods with YARD tags
rb/lib/selenium/webdriver/common/client_config.rb[42-50]
rb/lib/selenium/webdriver/remote/http/default.rb[147-187]
rb/lib/selenium/webdriver/common/client_config.rb[42-64]
rb/lib/selenium/webdriver/remote/http/default.rb[147-166]

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

## Issue description
`ClientConfig#initialize` YARD docs indicate `proxy` can be provided as a `Hash`, but the implementation stores the value directly and downstream HTTP transport code expects a `Selenium::WebDriver::Proxy` (or proxy-like object) that responds to `http`/`no_proxy`, leading to runtime errors for users who pass a Hash as documented.

## Issue Context
`Remote::Http::Default#use_proxy?` and the HTTP-client construction path (e.g., `#new_http_client`) call `proxy.http` and `proxy.no_proxy`, which a Ruby `Hash` does not provide. Because this is a public API surface, users following the YARD docs may pass a hash such as `{http: 'http://proxy:8080'}` and encounter failures when the HTTP transport is built.

Implementation options (choose one):
1) **Docs-only**: change YARD to only accept `Proxy` (keep current behavior).
2) **Support Hash**: accept `Hash` by converting it to a `Proxy` during initialization and/or assignment (e.g., in `initialize` or `proxy=`), and update the YARD (and any related type definitions such as RBS) accordingly.

## Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[42-64]
- rb/lib/selenium/webdriver/remote/http/default.rb[147-187]

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


12. Nil max_redirects crashes 🐞 Bug ☼ Reliability
Description
Remote::Http::Default#follow_redirect compares redirects >= client_config.max_redirects without
guarding against nil, so setting ClientConfig#max_redirects to nil raises a TypeError during
redirect handling. ClientConfig exposes max_redirects as nullable in the type signatures and via
attr_accessor.
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R126-129]

+          def follow_redirect(response, redirects)
+            WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
+            raise Error::WebDriverError, 'too many redirects' if redirects >= client_config.max_redirects
+
Evidence
ClientConfig allows max_redirects to be nil at the type/API level, while follow_redirect uses it in
a numeric comparison without nil handling.

rb/lib/selenium/webdriver/remote/http/default.rb[126-130]
rb/lib/selenium/webdriver/common/client_config.rb[38-56]
rb/sig/lib/selenium/webdriver/common/client_config.rbs[9-12]

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

### Issue description
`follow_redirect` does `redirects >= client_config.max_redirects` which will raise when `max_redirects` is `nil`.

### Issue Context
`ClientConfig#max_redirects` is mutable and typed as `Integer?`, so nil is an allowed value at the API boundary.

### Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/default.rb[126-129]
- rb/lib/selenium/webdriver/common/client_config.rb[42-56]

### Implementation notes
- Decide on semantics for `nil` (e.g., treat as default 20/MAX_REDIRECTS, or as unlimited).
- Implement a nil-safe max in `follow_redirect` (e.g., `max = client_config.max_redirects || MAX_REDIRECTS`).
- Optionally validate/coerce in `ClientConfig` to keep `max_redirects` non-nil.

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


13. Redirect drops config headers ✓ Resolved 🐞 Bug ☼ Reliability
Description
Remote::Http::Default#follow_redirect re-issues redirected requests using DEFAULT_HEADERS only,
dropping ClientConfig-provided User-Agent and extra_headers that Common#common_headers otherwise
applies. This makes ClientConfig header customization inconsistent across redirect chains.
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R126-131]

+          def follow_redirect(response, redirects)
+            WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
+            raise Error::WebDriverError, 'too many redirects' if redirects >= client_config.max_redirects
+
+            request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
+          end
Evidence
Common constructs per-client headers from ClientConfig, but follow_redirect bypasses that and uses
only DEFAULT_HEADERS for the redirected request.

rb/lib/selenium/webdriver/remote/http/common.rb[93-99]
rb/lib/selenium/webdriver/remote/http/default.rb[126-131]

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

### Issue description
Redirect-following currently rebuilds headers with `DEFAULT_HEADERS.dup`, which omits `client_config.user_agent` and `client_config.extra_headers` that are included in normal requests.

### Issue Context
`Remote::Http::Common#common_headers` is the centralized place that merges `User-Agent` and `extra_headers` from `client_config`. Redirects should preserve these headers for consistency.

### Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/default.rb[126-131]

### Implementation notes
- In `follow_redirect`, use `common_headers.dup` instead of `DEFAULT_HEADERS.dup` when calling `request`.
- Ensure any redirect-specific header adjustments (if needed) are preserved.

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


14. Server URL slash misplacement 🐞 Bug ≡ Correctness
Description
ClientConfig#server_url= appends '/' to the full URL string before parsing, which changes semantics
when the URL contains a query or fragment (the slash is appended after the query/fragment rather
than to the path). This can lead to requests being sent to an unintended endpoint when users provide
server_url values like ".../wd/hub?x=1".
Code

rb/lib/selenium/webdriver/common/client_config.rb[R66-73]

+      def server_url=(url)
+        if url.nil?
+          @server_url = nil
+        else
+          url = url.to_s
+          url += '/' unless url.end_with?('/')
+          @server_url = URI.parse(url)
+        end
Evidence
The setter appends a slash to the raw string representation of the URL, which affects query/fragment
placement, instead of normalizing URI#path as a distinct component.

rb/lib/selenium/webdriver/common/client_config.rb[66-73]

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

### Issue description
`ClientConfig#server_url=` currently does `url = url.to_s; url += '/' unless url.end_with?('/')` prior to `URI.parse`. For URLs that include `?query` or `#fragment`, this appends the slash to the query/fragment portion instead of ensuring the *path* ends with `/`.

### Issue Context
This method is now the central normalization point for server URLs passed through `Remote::Http::Common#server_url=` and driver initialization.

### Fix Focus Areas
- rb/lib/selenium/webdriver/common/client_config.rb[66-73]

### Implementation notes
- Parse first (`uri = url.is_a?(URI) ? url.dup : URI.parse(url.to_s)`), then ensure `uri.path` ends with `/` (e.g., `uri.path = uri.path.end_with?('/') ? uri.path : "#{uri.path}/"`).
- Preserve existing query/fragment/userinfo unchanged.
- Keep `nil` behavior as-is.

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



Informational

15. ClientConfig require missing 🐞 Bug ☼ Reliability
Description
Remote::Http::Common and Remote::Http::Default reference ClientConfig but do not require the file
that defines it, making require 'selenium/webdriver/remote/http/common' or .../default fragile
depending on load order. This can raise NameError when these internal files are required directly
(without selenium/webdriver/common).
Code

rb/lib/selenium/webdriver/remote/http/default.rb[R33-42]

+          def initialize(client_config: nil, open_timeout: nil, read_timeout: nil)
+            if client_config && (open_timeout || read_timeout)
+              raise Error::WebDriverError, 'Cannot use both :client_config and :open_timeout/:read_timeout'
+            end
+
+            client_config ||= ClientConfig.new
+            client_config.open_timeout = open_timeout if open_timeout
+            client_config.read_timeout = read_timeout if read_timeout
+            super(client_config: client_config)
+          end
Evidence
The Remote::Http files reference ClientConfig, while remote.rb does not require common.rb (where
ClientConfig is required), so direct requires of these internal files can leave ClientConfig
undefined.

rb/lib/selenium/webdriver/remote/http/common.rb[20-55]
rb/lib/selenium/webdriver/remote/http/default.rb[19-42]
rb/lib/selenium/webdriver/remote.rb[20-36]
rb/lib/selenium/webdriver/common.rb[20-26]

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

### Issue description
`Remote::Http::Common`/`Default` use `ClientConfig`, but the files themselves don't `require` the definition, so loading them in isolation can fail.

### Issue Context
`ClientConfig` is defined in `selenium/webdriver/common/client_config`. It is required by the main `selenium/webdriver/common` entrypoint, but `selenium/webdriver/remote` does not itself require `common`.

### Fix Focus Areas
- rb/lib/selenium/webdriver/remote/http/common.rb[1-60]
- rb/lib/selenium/webdriver/remote/http/default.rb[19-42]

### Implementation notes
- Add `require 'selenium/webdriver/common/client_config'` near the top of both files (or require `selenium/webdriver/common` if that’s the preferred layering).
- Keep requires minimal to avoid circular dependencies.

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


Grey Divider

Qodo Logo

Comment thread rb/lib/selenium/webdriver/common/client_config.rb
Comment thread rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 8f5d153

Copilot AI left a comment

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.

Pull request overview

Adds a Ruby ClientConfig object to centralize HTTP client settings (timeouts, redirects, proxy, headers, user-agent, server URL), and refactors driver/bridge construction so the Bridge only consumes a configured http_client.

Changes:

  • Introduces Selenium::WebDriver::ClientConfig with defaults (including read timeout 120s) and environment proxy support.
  • Updates local + remote driver constructors to accept client_config: (mutually exclusive with http_client:) and to pass only an HTTP client into the Bridge.
  • Updates unit tests and RBS signatures for the new constructor shapes and config behavior.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
rb/spec/unit/selenium/webdriver/safari/service_spec.rb Updates expected error message when :url is provided for a local driver.
rb/spec/unit/selenium/webdriver/remote/http/default_spec.rb Updates timeout defaults and adds coverage for ClientConfig + redirect limits.
rb/spec/unit/selenium/webdriver/remote/http/common_spec.rb Shifts header/user-agent expectations to ClientConfig defaults.
rb/spec/unit/selenium/webdriver/remote/features_spec.rb Updates Bridge construction to rely on http_client.server_url.
rb/spec/unit/selenium/webdriver/remote/driver_spec.rb Adds coverage for client_config in remote driver initialization and conflicts.
rb/spec/unit/selenium/webdriver/remote/bridge_spec.rb Updates Bridge initialization expectations (now http_client: only).
rb/spec/unit/selenium/webdriver/ie/service_spec.rb Updates expected error message when :url is provided for a local driver.
rb/spec/unit/selenium/webdriver/firefox/service_spec.rb Updates expected error message when :url is provided for a local driver.
rb/spec/unit/selenium/webdriver/edge/service_spec.rb Updates expected error message when :url is provided for a local driver.
rb/spec/unit/selenium/webdriver/chrome/service_spec.rb Updates expected error message when :url is provided for a local driver.
rb/spec/unit/selenium/webdriver/chrome/driver_spec.rb Adds coverage for rejecting client_config.server_url on local drivers and conflict handling.
rb/sig/lib/selenium/webdriver/safari/driver.rbs Updates Safari driver initializer signature with http_client/client_config.
rb/sig/lib/selenium/webdriver/remote/http/default.rbs Updates Http::Default initializer and accessors signatures.
rb/sig/lib/selenium/webdriver/remote/http/common.rbs Updates Http::Common to accept client_config: and return URI server_url.
rb/sig/lib/selenium/webdriver/remote/driver.rbs Updates Remote driver initializer signature with http_client/client_config.
rb/sig/lib/selenium/webdriver/remote/bridge.rbs Updates Bridge initializer signature (now only http_client:).
rb/sig/lib/selenium/webdriver/ie/driver.rbs Updates IE driver initializer signature with http_client/client_config.
rb/sig/lib/selenium/webdriver/firefox/driver.rbs Updates Firefox driver initializer signature with http_client/client_config.
rb/sig/lib/selenium/webdriver/edge/driver.rbs Updates Edge driver initializer signature with http_client/client_config.
rb/sig/lib/selenium/webdriver/common/local_driver.rbs Updates LocalDriver helper signatures for new parameters.
rb/sig/lib/selenium/webdriver/common/driver.rbs Updates create_bridge signature (drops url:).
rb/sig/lib/selenium/webdriver/common/client_config.rbs Adds RBS for the new ClientConfig class.
rb/sig/lib/selenium/webdriver/chrome/driver.rbs Updates Chrome driver initializer signature with http_client/client_config.
rb/lib/selenium/webdriver/safari/driver.rb Passes http_client through local driver initialization into base Driver.
rb/lib/selenium/webdriver/remote/http/default.rb Refactors HTTP default client to be backed by ClientConfig and to use config for redirects/proxy/timeouts.
rb/lib/selenium/webdriver/remote/http/common.rb Moves per-instance headers/user-agent and server URL storage into ClientConfig.
rb/lib/selenium/webdriver/remote/driver.rb Allows client_config: to build/configure the HTTP client and enforces exclusivity with http_client:.
rb/lib/selenium/webdriver/remote/bridge.rb Removes url: from Bridge initialization; uses provided configured HTTP client.
rb/lib/selenium/webdriver/ie/driver.rb Passes http_client through local driver initialization into base Driver.
rb/lib/selenium/webdriver/firefox/driver.rb Passes http_client through local driver initialization into base Driver.
rb/lib/selenium/webdriver/edge/driver.rb Passes http_client through local driver initialization into base Driver.
rb/lib/selenium/webdriver/common/local_driver.rb Builds/configures HTTP client for local services and validates url/config conflicts.
rb/lib/selenium/webdriver/common/driver.rb Updates bridge creation to only pass http_client:.
rb/lib/selenium/webdriver/common/client_config.rb Adds the new ClientConfig implementation and defaults.
rb/lib/selenium/webdriver/common.rb Requires the new ClientConfig.
rb/lib/selenium/webdriver/chrome/driver.rb Passes http_client through local driver initialization into base Driver.
rb/.rubocop.yml Updates RuboCop parameter list metrics config.

Comment thread rb/lib/selenium/webdriver/common/client_config.rb
Comment thread rb/lib/selenium/webdriver/common/client_config.rb
Comment thread rb/lib/selenium/webdriver/remote/driver.rb Outdated
Comment thread rb/sig/lib/selenium/webdriver/common/client_config.rbs Outdated
Comment thread rb/lib/selenium/webdriver/remote/http/default.rb
Comment thread rb/lib/selenium/webdriver/remote/http/default.rb
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 06b7fd2

Comment thread rb/lib/selenium/webdriver/common/local_driver.rb Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 46f2685

Comment thread rb/lib/selenium/webdriver/remote/http/default.rb
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 4848282

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 56cbcc9

This was referenced Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-rb Ruby Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants