class Selenium::WebDriver::Remote::Bridge

Constants

COMMANDS
PORT

Attributes

capabilities[R]
context[RW]
dialect[R]
file_detector[RW]
http[RW]

Public Class Methods

handshake(**opts) click to toggle source

Implements protocol handshake which:

1. Creates session with driver.
2. Sniffs response.
3. Based on the response, understands which dialect we should use.

@return [OSS:Bridge, W3C::Bridge]

# File lib/selenium/webdriver/remote/bridge.rb, line 43
def self.handshake(**opts)
  desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.new }

  if desired_capabilities.is_a?(Symbol)
    unless Capabilities.respond_to?(desired_capabilities)
      raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
    end

    desired_capabilities = Capabilities.__send__(desired_capabilities)
  end

  bridge = new(opts)
  capabilities = bridge.create_session(desired_capabilities, opts.delete(:options))

  case bridge.dialect
  when :oss
    Remote::OSS::Bridge.new(capabilities, bridge.session_id, **opts)
  when :w3c
    Remote::W3C::Bridge.new(capabilities, bridge.session_id, **opts)
  else
    raise WebDriverError, 'cannot understand dialect'
  end
end
new(opts = {}) click to toggle source

Initializes the bridge with the given server URL @param [Hash] opts options for the driver @option opts [String] :url url for the remote server @option opts [Object] :http_client an HTTP client instance that implements the same protocol as Http::Default @option opts [Capabilities] :desired_capabilities an instance of Remote::Capabilities describing the capabilities you want @api private

# File lib/selenium/webdriver/remote/bridge.rb, line 76
def initialize(opts = {})
  opts = opts.dup

  http_client = opts.delete(:http_client) { Http::Default.new }
  url = opts.delete(:url) { "http://#{Platform.localhost}:#{PORT}/wd/hub" }
  opts.delete(:options)

  unless opts.empty?
    raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
  end

  uri = url.is_a?(URI) ? url : URI.parse(url)
  uri.path += '/' unless uri.path =~ %r{\/$}

  http_client.server_url = uri

  @http = http_client
  @file_detector = nil
end

Public Instance Methods

browser() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 138
def browser
  @browser ||= begin
    name = @capabilities.browser_name
    name ? name.tr(' ', '_').to_sym : 'unknown'
  end
end
create_session(desired_capabilities, options = nil) click to toggle source

Creates session handling both OSS and W3C dialects.

# File lib/selenium/webdriver/remote/bridge.rb, line 100
def create_session(desired_capabilities, options = nil)
  response = execute(:new_session, {}, merged_capabilities(desired_capabilities, options))

  @session_id = response['sessionId']
  oss_status = response['status']
  value = response['value']

  if value.is_a?(Hash)
    @session_id = value['sessionId'] if value.key?('sessionId')

    if value.key?('capabilities')
      value = value['capabilities']
    elsif value.key?('value')
      value = value['value']
    end
  end

  raise Error::WebDriverError, 'no sessionId in returned payload' unless @session_id

  if oss_status
    WebDriver.logger.info 'Detected OSS dialect.'
    @dialect = :oss
    Capabilities.json_create(value)
  else
    WebDriver.logger.info 'Detected W3C dialect.'
    @dialect = :w3c
    W3C::Capabilities.json_create(value)
  end
end
session_id() click to toggle source

Returns the current session ID.

# File lib/selenium/webdriver/remote/bridge.rb, line 134
def session_id
  @session_id || raise(Error::WebDriverError, 'no current session exists')
end

Private Instance Methods

commands(command) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 173
def commands(command)
  raise NotImplementedError unless command == :new_session

  COMMANDS[command]
end
escaper() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 169
def escaper
  @escaper ||= defined?(URI::Parser) ? URI::DEFAULT_PARSER : URI
end
execute(command, opts = {}, command_hash = nil) click to toggle source

executes a command on the remote server.

@return [WebDriver::Remote::Response]

# File lib/selenium/webdriver/remote/bridge.rb, line 153
def execute(command, opts = {}, command_hash = nil)
  verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
  path = path.dup

  path[':session_id'] = session_id if path.include?(':session_id')

  begin
    opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
  rescue IndexError
    raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
  end

  WebDriver.logger.info("-> #{verb.to_s.upcase} #{path}")
  http.call(verb, path, command_hash)
end
merged_capabilities(oss_capabilities, options = nil) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 179
def merged_capabilities(oss_capabilities, options = nil)
  w3c_capabilities = W3C::Capabilities.from_oss(oss_capabilities)
  w3c_capabilities.merge!(options.as_json) if options

  {
    desiredCapabilities: oss_capabilities,
    capabilities: {
      firstMatch: [w3c_capabilities]
    }
  }
end