Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions rb/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ Metrics/PerceivedComplexity:
Exclude:
- '../rake_tasks/**/*'

Metrics/ParameterLists:
CountKeywordArgs: false

Naming/BlockForwarding:
EnforcedStyle: explicit

Expand Down
6 changes: 3 additions & 3 deletions rb/lib/selenium/webdriver/chrome/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ module Chrome
class Driver < Chromium::Driver
include LocalDriver

def initialize(options: nil, service: nil, url: nil, **)
initialize_local_driver(options, service, url) do |caps, driver_url|
super(caps: caps, url: driver_url, **)
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
super(caps: caps, http_client: client, **)
end
end

Expand Down
1 change: 1 addition & 0 deletions rb/lib/selenium/webdriver/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# under the License.

require 'selenium/webdriver/common/error'
require 'selenium/webdriver/common/client_config'
require 'selenium/webdriver/common/local_driver'
require 'selenium/webdriver/common/driver_finder'
require 'selenium/webdriver/common/platform'
Expand Down
97 changes: 97 additions & 0 deletions rb/lib/selenium/webdriver/common/client_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

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
end

attr_accessor :open_timeout, :read_timeout, :max_redirects, :proxy
attr_writer :extra_headers, :user_agent
attr_reader :server_url

#
# @param [Numeric] open_timeout Seconds to wait for the connection to open.
# @param [Numeric] read_timeout Seconds to wait for a response.
# @param [Integer] max_redirects Maximum number of redirects to follow.
# @param [Proxy, Hash] proxy Proxy to use for the connection.
# @param [Hash] extra_headers Additional headers to send with each request.
# @param [String] user_agent Value to send as the User-Agent header.
# @param [String, URI] server_url URL of the server to connect to.
#
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
Comment thread
titusfortner marked this conversation as resolved.
Comment on lines +66 to +74

private

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 +78 to +85
end
end
end
4 changes: 2 additions & 2 deletions rb/lib/selenium/webdriver/common/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,9 @@ def ref

attr_reader :bridge

def create_bridge(caps:, url:, http_client: nil)
def create_bridge(caps:, http_client:)
klass = caps['webSocketUrl'] ? Remote::BiDiBridge : Remote::Bridge
klass.new(http_client: http_client, url: url).tap do |bridge|
klass.new(http_client: http_client).tap do |bridge|
bridge.create_session(caps)
end
end
Expand Down
17 changes: 13 additions & 4 deletions rb/lib/selenium/webdriver/common/local_driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,30 @@
module Selenium
module WebDriver
module LocalDriver
def initialize_local_driver(options, service, url)
raise ArgumentError, "Can't initialize #{self.class} with :url" if url
def initialize_local_driver(options, service, url, http_client, client_config)
assert_local_arguments(url, http_client, client_config)

service ||= Service.send(browser)
caps = process_options(options, service)
url = service_url(service)
http_client ||= Remote::Http::Default.new(client_config: client_config)
http_client.server_url = service_url(service)

begin
yield(caps, url) if block_given?
yield(caps, http_client) if block_given?
rescue Selenium::WebDriver::Error::WebDriverError
@service_manager&.stop
raise
end
end

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 Error::WebDriverError, 'Cannot use both :http_client and :client_config'
end
end

def service_url(service)
@service_manager = service.launch
@service_manager.uri
Expand Down
6 changes: 3 additions & 3 deletions rb/lib/selenium/webdriver/edge/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ module Edge
class Driver < Chromium::Driver
include LocalDriver

def initialize(options: nil, service: nil, url: nil, **)
initialize_local_driver(options, service, url) do |caps, driver_url|
super(caps: caps, url: driver_url, **)
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
super(caps: caps, http_client: client, **)
end
end

Expand Down
6 changes: 3 additions & 3 deletions rb/lib/selenium/webdriver/firefox/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class Driver < WebDriver::Driver

include LocalDriver

def initialize(options: nil, service: nil, url: nil, **)
initialize_local_driver(options, service, url) do |caps, driver_url|
super(caps: caps, url: driver_url, **)
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
super(caps: caps, http_client: client, **)
end
end

Expand Down
6 changes: 3 additions & 3 deletions rb/lib/selenium/webdriver/ie/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class Driver < WebDriver::Driver

include LocalDriver

def initialize(options: nil, service: nil, url: nil, **)
initialize_local_driver(options, service, url) do |caps, driver_url|
super(caps: caps, url: driver_url, **)
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
super(caps: caps, http_client: client, **)
end
end

Expand Down
13 changes: 3 additions & 10 deletions rb/lib/selenium/webdriver/remote/bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,13 @@ def element_class
end

#
# Initializes the bridge with the given server URL
# @param [String, URI] url url for the remote server
# @param [Object] http_client an HTTP client instance that implements the same protocol as Http::Default
# @param [Object] http_client a configured HTTP client implementing the same protocol as Http::Default
# @api private
#

def initialize(url:, http_client: nil)
uri = url.is_a?(URI) ? url : URI.parse(url)
uri.path += '/' unless uri.path.end_with?('/')

@http = http_client || Http::Default.new
@http.server_url = uri
def initialize(http_client:)
@http = http_client
@file_detector = nil

@locator_converter = self.class.locator_converter
end

Expand Down
9 changes: 6 additions & 3 deletions rb/lib/selenium/webdriver/remote/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ class Driver < WebDriver::Driver
include DriverExtensions::HasFileDownloads
include DriverExtensions::HasSessionEvents

def initialize(capabilities: nil, options: nil, service: nil, url: nil, **)
def initialize(capabilities: nil, options: nil, service: nil, url: nil, http_client: nil, client_config: nil,
**)
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 36 to +40
http_client.server_url = url || client_config&.server_url || "http://#{Platform.localhost}:4444/wd/hub"
super(caps: caps, http_client: http_client, **)
@bridge.file_detector = ->((filename, *)) { File.exist?(filename) && filename.to_s }
command_list = @bridge.command_list
@bridge.extend(WebDriver::Remote::Features)
Expand Down
37 changes: 25 additions & 12 deletions rb/lib/selenium/webdriver/remote/http/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,32 @@ class Common
BINARY_ENCODINGS = [Encoding::BINARY, Encoding::ASCII_8BIT].freeze

class << self
attr_accessor :extra_headers
attr_writer :user_agent

def user_agent
@user_agent ||= "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})"
ClientConfig.default_user_agent
end

def user_agent=(value)
ClientConfig.default_user_agent = value
end

def extra_headers
ClientConfig.default_extra_headers
end

def extra_headers=(value)
ClientConfig.default_extra_headers = value
end
end

attr_writer :server_url
attr_reader :client_config

def initialize(client_config: nil)
@client_config = client_config || ClientConfig.new
end

def server_url=(url)
client_config.server_url = url
end

def quit_errors
[IOError]
Expand Down Expand Up @@ -76,17 +93,13 @@ def call(verb, url, command_hash)
def common_headers
@common_headers ||= begin
headers = DEFAULT_HEADERS.dup
headers['User-Agent'] = Common.user_agent
headers = headers.merge(Common.extra_headers || {})

headers
headers['User-Agent'] = client_config.user_agent
headers.merge(client_config.extra_headers || {})
end
end

def server_url
return @server_url if @server_url

raise Error::WebDriverError, 'server_url not set'
client_config.server_url || raise(Error::WebDriverError, 'server_url not set')
end

def request(*)
Expand Down
Loading