class Capybara::Apparition::Driver

Constants

DEFAULT_TIMEOUT
VERSION_STRING

Attributes

app[R]
options[R]

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/capybara/apparition/driver.rb, line 29
def initialize(app, options = {})
  @app       = app
  @options   = options
  generate_browser_options
  @browser   = nil
  @inspector = nil
  @client    = nil
  @launcher  = nil
  @started   = false
end

Public Instance Methods

accept_modal(type, options = {}) { || ... } click to toggle source
# File lib/capybara/apparition/driver.rb, line 310
def accept_modal(type, options = {})
  case type
  when :alert
    browser.accept_alert
  when :confirm
    browser.accept_confirm
  when :prompt
    browser.accept_prompt options[:with]
  end

  yield if block_given?

  find_modal(options)
end
add_header(name, value, options = {}) click to toggle source
# File lib/capybara/apparition/driver.rb, line 215
def add_header(name, value, options = {})
  browser.add_header({ name => value }, **{ permanent: true }.merge(options))
end
Also aliased as: header
authenticate(user = nil, password = nil)
Alias for: basic_authorize
basic_authorize(user = nil, password = nil) click to toggle source
# File lib/capybara/apparition/driver.rb, line 244
def basic_authorize(user = nil, password = nil)
  browser.set_http_auth(user, password)
end
Also aliased as: authenticate
browser() click to toggle source

def chrome_url

'ws://localhost:9223'

end

# File lib/capybara/apparition/driver.rb, line 48
def browser
  @browser ||= begin
    Browser.new(client, browser_logger) do |browser|
      browser.js_errors = options.fetch(:js_errors, true)
      browser.ignore_https_errors = options.fetch(:ignore_https_errors, false)
      browser.extensions = options.fetch(:extensions, [])
      browser.debug      = options.fetch(:debug, false)
      browser.url_blacklist = options[:url_blacklist] || []
      browser.url_whitelist = options[:url_whitelist] || []
    end
  end
end
browser_logger() click to toggle source

logger should be an object that behaves like IO or nil

# File lib/capybara/apparition/driver.rb, line 84
def browser_logger
  options.fetch(:browser_logger, $stdout)
end
click(x, y) click to toggle source
# File lib/capybara/apparition/driver.rb, line 113
def click(x, y)
  browser.click_coordinates(x, y)
end
client() click to toggle source
# File lib/capybara/apparition/driver.rb, line 65
def client
  @client ||= begin
    @launcher ||= Browser::Launcher.start(options)
    ws_url = @launcher.ws_url
    ::Capybara::Apparition::ChromeClient.client(ws_url.to_s)
  end
end
current_window_handle() click to toggle source
# File lib/capybara/apparition/driver.rb, line 136
def current_window_handle
  browser.current_window_handle
end
debug() click to toggle source
# File lib/capybara/apparition/driver.rb, line 249
def debug
  if @options[:inspector]
    # Fall back to default scheme
    scheme = begin
               URI.parse(browser.current_url).scheme
             rescue StandardError
               nil
             end
    scheme = 'http' if scheme != 'https'
    inspector.open(scheme)
    pause
  else
    raise Error, 'To use the remote debugging, you have to launch the driver ' \
                 'with `:inspector => true` configuration option'
  end
end
dismiss_modal(type, options = {}) { || ... } click to toggle source
# File lib/capybara/apparition/driver.rb, line 325
def dismiss_modal(type, options = {})
  case type
  when :confirm
    browser.dismiss_confirm
  when :prompt
    browser.dismiss_prompt
  end

  yield if block_given?
  find_modal(options)
end
error_messages() click to toggle source
# File lib/capybara/apparition/driver.rb, line 345
def error_messages
  console_messages('error')
end
evaluate_async_script(script, *args) click to toggle source
# File lib/capybara/apparition/driver.rb, line 123
def evaluate_async_script(script, *args)
  retry_if_wrong_world do
    unwrap_script_result(browser.evaluate_async(script, session_wait_time, *native_args(args)))
  end
end
evaluate_script(script, *args) click to toggle source
# File lib/capybara/apparition/driver.rb, line 117
def evaluate_script(script, *args)
  retry_if_wrong_world do
    unwrap_script_result(browser.evaluate(script, *native_args(args)))
  end
end
execute_script(script, *args) click to toggle source
# File lib/capybara/apparition/driver.rb, line 129
def execute_script(script, *args)
  retry_if_wrong_world do
    browser.execute(script, *native_args(args))
  end
  nil
end
find(method, selector) click to toggle source
# File lib/capybara/apparition/driver.rb, line 99
def find(method, selector)
  browser.find(method, selector).map do |page_id, id, attrs|
    Capybara::Apparition::Node.new(self, page_id, id, attrs)
  end
end
find_css(selector) click to toggle source
# File lib/capybara/apparition/driver.rb, line 109
def find_css(selector)
  find :css, selector.to_s
end
find_xpath(selector) click to toggle source
# File lib/capybara/apparition/driver.rb, line 105
def find_xpath(selector)
  find :xpath, selector.to_s
end
fullscreen_window(handle) click to toggle source
# File lib/capybara/apparition/driver.rb, line 187
def fullscreen_window(handle)
  _within_window(handle) do
    browser.fullscreen
  end
end
header(name, value, options = {})
Alias for: add_header
inspector() click to toggle source
# File lib/capybara/apparition/driver.rb, line 61
def inspector
  @inspector ||= options[:inspector] && Inspector.new(options[:inspector])
end
invalid_element_errors() click to toggle source
# File lib/capybara/apparition/driver.rb, line 306
def invalid_element_errors
  [Capybara::Apparition::ObsoleteNode, Capybara::Apparition::MouseEventFailed, Capybara::Apparition::WrongWorld]
end
logger() click to toggle source

logger should be an object that responds to puts, or nil

# File lib/capybara/apparition/driver.rb, line 79
def logger
  options[:logger] || (options[:debug] && STDERR)
end
maximize_window(handle) click to toggle source
# File lib/capybara/apparition/driver.rb, line 181
def maximize_window(handle)
  _within_window(handle) do
    browser.maximize
  end
end
needs_server?() click to toggle source
# File lib/capybara/apparition/driver.rb, line 40
def needs_server?
  true
end
no_such_window_error() click to toggle source
# File lib/capybara/apparition/driver.rb, line 140
def no_such_window_error
  NoSuchWindowError
end
open_new_window() click to toggle source
# File lib/capybara/apparition/driver.rb, line 369
def open_new_window
  # needed because Capybara does arity detection on this method
  browser.open_new_window
end
pause() click to toggle source
# File lib/capybara/apparition/driver.rb, line 266
def pause
  # STDIN is not necessarily connected to a keyboard. It might even be closed.
  # So we need a method other than keypress to continue.

  # In jRuby - STDIN returns immediately from select
  # see https://github.com/jruby/jruby/issues/1783
  # TODO: This limitation is no longer true can we simplify?
  read, write = IO.pipe
  Thread.new do
    IO.copy_stream(STDIN, write)
    write.close
  end

  STDERR.puts "Apparition execution paused. Press enter (or run 'kill -CONT #{Process.pid}') to continue." # rubocop:disable Style/StderrPuts

  signal = false
  old_trap = trap('SIGCONT') do
    signal = true
    STDERR.puts "\nSignal SIGCONT received" # rubocop:disable Style/StderrPuts
  end
  # wait for data on STDIN or signal SIGCONT received
  keyboard = IO.select([read], nil, nil, 1) until keyboard || signal

  unless signal
    begin
      input = read.read_nonblock(80) # clear out the read buffer
      puts unless input&.end_with?("\n")
    rescue EOFError, IO::WaitReadable
      # Ignore problems reading from STDIN.
    end
  end
ensure
  trap('SIGCONT', old_trap) # Restore the previous signal handler, if there was one.
  STDERR.puts 'Continuing' # rubocop:disable Style/StderrPuts
end
proxy_authorize(user = nil, password = nil) click to toggle source
# File lib/capybara/apparition/driver.rb, line 240
def proxy_authorize(user = nil, password = nil)
  browser.set_proxy_auth(user, password)
end
quit() click to toggle source
# File lib/capybara/apparition/driver.rb, line 73
def quit
  @client&.stop
  @launcher&.stop
end
render(path, options = {})
Alias for: save_screenshot
render_base64(format = :png, options = {}) click to toggle source
# File lib/capybara/apparition/driver.rb, line 161
def render_base64(format = :png, options = {})
  browser.render_base64(options.merge(format: format))
end
reset!() click to toggle source
# File lib/capybara/apparition/driver.rb, line 144
def reset!
  begin
    browser.reset
  rescue TimeoutError
    puts 'Reset timed out - retrying'
    browser.reset
  end
  browser.url_blacklist = options[:url_blacklist] || []
  browser.url_whitelist = options[:url_whitelist] || []
  @started = false
end
resize(width, height) click to toggle source
# File lib/capybara/apparition/driver.rb, line 165
def resize(width, height)
  browser.resize(width, height, screen: options[:screen_size])
end
resize_window(width, height) click to toggle source
# File lib/capybara/apparition/driver.rb, line 169
def resize_window(width, height)
  warn '[DEPRECATION] Capybara::Apparition::Driver#resize_window ' \
    'is deprecated. Please use Capybara::Window#resize_to instead.'
  resize(width, height)
end
resize_window_to(handle, width, height) click to toggle source
# File lib/capybara/apparition/driver.rb, line 175
def resize_window_to(handle, width, height)
  _within_window(handle) do
    resize(width, height)
  end
end
response_headers() click to toggle source
# File lib/capybara/apparition/driver.rb, line 220
def response_headers
  browser.response_headers.transform_keys { |key| key.split('-').map(&:capitalize).join('-') }
end
save_screenshot(path, options = {}) click to toggle source
# File lib/capybara/apparition/driver.rb, line 156
def save_screenshot(path, options = {})
  browser.render(path, options)
end
Also aliased as: render
set_proxy(host, port, type = nil, user_ = nil, password_ = nil, user: nil, password: nil, bypass: []) click to toggle source
# File lib/capybara/apparition/driver.rb, line 199
def set_proxy(host, port, type = nil, user_ = nil, password_ = nil, user: nil, password: nil, bypass: [])
  if user_ || password_
    warn '#set_proxy: Passing `user` and `password` as positional arguments is deprecated. ' \
         'Please pass as keyword arguments.'
    user ||= user_
    password ||= password_
  end

  # TODO: Look at implementing via the CDP Fetch domain when available
  @options[:browser_options] ||= {}
  @options[:browser_options]['proxy-server'] = "#{type + '=' if type}#{host}:#{port}"
  bypass = Array(bypass).join(';')
  @options[:browser_options]['proxy-bypass-list'] = bypass unless bypass.empty?
  browser.set_proxy_auth(user, password) if user || password
end
source() click to toggle source
# File lib/capybara/apparition/driver.rb, line 95
def source
  browser.source.to_s
end
timeout() click to toggle source
# File lib/capybara/apparition/driver.rb, line 337
def timeout
  client.timeout
end
timeout=(sec) click to toggle source
# File lib/capybara/apparition/driver.rb, line 341
def timeout=(sec)
  client.timeout = sec
end
version() click to toggle source
# File lib/capybara/apparition/driver.rb, line 361
def version
  chrome_version = browser.command('Browser.getVersion')
  format(VERSION_STRING,
         capybara: Capybara::VERSION,
         apparition: Capybara::Apparition::VERSION,
         chrome: chrome_version['product'])
end
visit(url) click to toggle source
# File lib/capybara/apparition/driver.rb, line 88
def visit(url)
  @started = true
  browser.visit(url)
end
wait?() click to toggle source
# File lib/capybara/apparition/driver.rb, line 302
def wait?
  true
end
window_size(handle) click to toggle source
# File lib/capybara/apparition/driver.rb, line 193
def window_size(handle)
  _within_window(handle) do
    evaluate_script('[window.innerWidth, window.innerHeight]')
  end
end
within_window(selector) { || ... } click to toggle source
# File lib/capybara/apparition/driver.rb, line 349
def within_window(selector, &block)
  warn 'Driver#within_window is deprecated, please switch to using Session#within_window instead.'
  _within_window(selector, &block)
  orig_window = current_window_handle
  switch_to_window(selector)
  begin
    yield
  ensure
    switch_to_window(orig_window)
  end
end

Private Instance Methods

_within_window(selector) { || ... } click to toggle source
# File lib/capybara/apparition/driver.rb, line 386
def _within_window(selector)
  orig_window = current_window_handle
  switch_to_window(selector)
  begin
    yield
  ensure
    switch_to_window(orig_window)
  end
end
browser_options() click to toggle source
# File lib/capybara/apparition/driver.rb, line 396
def browser_options
  @options[:browser_options]
end
find_modal(options) click to toggle source
# File lib/capybara/apparition/driver.rb, line 464
def find_modal(options)
  timeout_sec   = options.fetch(:wait) { session_wait_time }
  expect_text   = options[:text]
  expect_regexp = expect_text.is_a?(Regexp) ? expect_text : Regexp.escape(expect_text.to_s)
  timer = Capybara::Helpers.timer(expire_in: timeout_sec)
  begin
    modal_text = browser.modal_message
    found_text ||= modal_text
    raise Capybara::ModalNotFound if modal_text.nil? || (expect_text && !modal_text.match(expect_regexp))
  rescue Capybara::ModalNotFound => e
    if timer.expired?
      raise e, 'Timed out waiting for modal dialog. Unable to find modal dialog.' unless found_text

      raise e, 'Unable to find modal dialog' \
               "#{" with #{expect_text}" if expect_text}" \
               "#{", did find modal with #{found_text}" if found_text}"
    end
    sleep(0.05)
    retry
  end
  modal_text
end
generate_browser_options() click to toggle source
# File lib/capybara/apparition/driver.rb, line 400
def generate_browser_options
  # TODO: configure SSL options
  # PhantomJS defaults to only using SSLv3, which since POODLE (Oct 2014)
  # many sites have dropped from their supported protocols (eg PayPal,
  # Braintree).
  # list += ["--ignore-ssl-errors=yes"] unless list.grep(/ignore-ssl-errors/).any?
  # list += ["--ssl-protocol=TLSv1"] unless list.grep(/ssl-protocol/).any?
  # list += ["--remote-debugger-port=#{inspector.port}", "--remote-debugger-autorun=yes"] if inspector
  # Note: Need to verify what Chrome command line options are valid for this
  browser_options = {}
  browser_options['remote-debugging-port'] = @options[:port] || 0
  browser_options['remote-debugging-address'] = @options[:host] if @options[:host]
  browser_options['window-size'] = @options[:window_size].join(',') if @options[:window_size]
  if @options[:browser]
    warn ':browser is deprecated, please pass as :browser_options instead.'
    browser_options.merge! process_browser_options(@options[:browser])
  end
  browser_options.merge! process_browser_options(@options[:browser_options]) if @options[:browser_options]
  if @options[:skip_image_loading]
    browser_options['blink-settings'] = [browser_options['blink-settings'], 'imagesEnabled=false'].compact.join(',')
  end

  @options[:browser_options] = browser_options
  process_cw_options(@options[:cw_options])
end
native_args(args) click to toggle source
# File lib/capybara/apparition/driver.rb, line 507
def native_args(args)
  args.map { |arg| arg.is_a?(Capybara::Apparition::Node) ? arg.native : arg }
end
process_browser_options(options) click to toggle source
# File lib/capybara/apparition/driver.rb, line 433
def process_browser_options(options)
  case options
  when Array
    options.compact.each_with_object({}) do |option, hsh|
      if option.is_a? Hash
        hsh.merge! process_browser_options(option)
      else
        hsh[option.to_s.tr('_', '-')] = nil
      end
    end
  when Hash
    options.transform_keys { |option| option.to_s.tr('_', '-') }
  else
    raise ArgumentError, 'browser_options must be an Array or a Hash'
  end
end
process_cw_options(cw_options) click to toggle source
# File lib/capybara/apparition/driver.rb, line 426
def process_cw_options(cw_options)
  return if cw_options.nil?

  (options[:url_blacklist] ||= []).concat cw_options[:url_blacklist]
  options[:js_errors] ||= cw_options[:js_errors]
end
retry_if_wrong_world() { || ... } click to toggle source
# File lib/capybara/apparition/driver.rb, line 376
def retry_if_wrong_world
  timer = Capybara::Helpers.timer(expire_in: session_wait_time)
  begin
    yield
  rescue WrongWorld
    retry unless timer.expired?
    raise
  end
end
screen_size() click to toggle source
# File lib/capybara/apparition/driver.rb, line 460
def screen_size
  options[:screen_size] || [1366, 768]
end
session_wait_time() click to toggle source
# File lib/capybara/apparition/driver.rb, line 487
def session_wait_time
  if respond_to?(:session_options)
    session_options.default_max_wait_time
  else
    begin begin
            Capybara.default_max_wait_time
          rescue StandardError
            Capybara.default_wait_time
          end end
  end
end
unwrap_script_result(arg, object_cache = {}) click to toggle source
# File lib/capybara/apparition/driver.rb, line 511
def unwrap_script_result(arg, object_cache = {})
  return object_cache[arg] if object_cache.key? arg

  case arg
  when Array
    object_cache[arg] = []
    object_cache[arg].replace(arg.map { |e| unwrap_script_result(e, object_cache) })
    object_cache[arg]
  when Hash
    if (arg['subtype'] == 'node') && arg['objectId']
      tag_name = arg['description'].split(/[.#]/, 2)[0]
      Capybara::Apparition::Node.new(self, browser.current_page, arg['objectId'], tag_name: tag_name)
    else
      object_cache[arg] = {}
      arg.each { |k, v| object_cache[arg][k] = unwrap_script_result(v, object_cache) }
      object_cache[arg]
    end
  else
    arg
  end
end