Skip to content

[rb] add ClientConfig for HTTP client customization#17699

Open
titusfortner wants to merge 2 commits into
trunkfrom
client_config-rb
Open

[rb] add ClientConfig for HTTP client customization#17699
titusfortner wants to merge 2 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 (4) 📘 Rule violations (2) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 19 rules

Grey Divider


Action required

1. 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


2. instance_double introduced in tests 📘 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

3. proxy param documents Hash 📘 Rule violation ✧ Quality ⭐ New
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


4. 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


5. Redirect drops config headers 🐞 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


View more (1)
6. 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

7. 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

Previous review results

Review updated until commit 8f5d153

Results up to commit dcd2e89


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


Action required
1. 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


2. instance_double introduced in tests 📘 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
3. 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


4. Redirect drops config headers 🐞 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


5. 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



Informational
6. 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


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 on lines +78 to +85
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.start_with?('http://')
Proxy.new(http: proxy, no_proxy: no_proxy)
end
Comment on lines +66 to +74
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
Comment on lines 36 to +40
raise ArgumentError, "Can not set :service object on #{self.class}" if service
raise Error::WebDriverError, 'Cannot use both :http_client and :client_config' if http_client && client_config

url ||= "http://#{Platform.localhost}:4444/wd/hub"
caps = process_options(options, capabilities)
super(caps: caps, url: url, **)
http_client ||= Remote::Http::Default.new(client_config: client_config)
Comment on lines +9 to +24
attr_accessor open_timeout: Integer?
attr_accessor read_timeout: Integer?
attr_accessor max_redirects: Integer?
attr_accessor proxy: Selenium::WebDriver::Proxy?
def extra_headers: -> Hash[String, String]?
attr_writer extra_headers: Hash[String, String]?
def user_agent: -> String
attr_writer user_agent: String?
attr_reader server_url: URI?

def server_url=: ((String | URI)? url) -> void

def initialize: (
?open_timeout: Integer?,
?read_timeout: Integer?,
?max_redirects: Integer?,
Comment on lines +126 to +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
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.

3 participants