class Simulacrum::Browserstack::Runner

A Runner Class for Browserstack that handles creating a Browserstack tunnel, closing it when done. Also handles running the suite in parallel.

Attributes

app_ports[R]

Public Class Methods

new() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 25
def initialize
  start_timer

  @username = Simulacrum.runner_options.username
  @apikey = Simulacrum.runner_options.apikey
  @app_ports = app_ports
  @api = Simulacrum::Browserstack::API.new(@username, @apikey)
  @tunnel = Simulacrum::Browserstack::Tunnel.new(@username, @apikey, @app_ports)

  set_global_env
  execute
  summarize_results
  summarize_exit_codes
ensure
  @tunnel.close if @tunnel
end

Public Instance Methods

execute() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 42
def execute
  Simulacrum.logger.info('BrowserStack') { "Using runner with #{processes} remote workers" }
  @process_exit_codes, @process_results = Parallel.map_with_index(browsers, in_processes: processes) do |(name, caps), index|
    begin
      ensure_available_remote_runner
      configure_app_port(index)
      configure_environment(name, caps)
      configure_browser_setting(name)
      exit_code = run
      [exit_code, { results: dump_results }]
    rescue SystemExit
      exit 1
    ensure
      quit_browser
    end
  end.transpose
ensure
  stop_timer
end

Private Instance Methods

browsers() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 177
def browsers
  @browsers ||= begin
    if Simulacrum.config_file?
      browsers = Simulacrum.config_file['browsers']
      browsers = browsers.select do |name, value|
        name == Simulacrum.runner_options.browser
      end if Simulacrum.runner_options.browser
      browsers
    else
      # TODO: Raise a better error...
      fail 'DERP!'
    end
  end
end
configure_app_port(index) click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 130
def configure_app_port(index)
  ENV['APP_SERVER_PORT'] = app_ports[index].to_s
end
configure_browser_setting(name) click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 68
def configure_browser_setting(name)
  RSpec.configuration.around do |example|
    example.metadata[:browser] = name
    begin
      example.run
    end
  end
end
configure_driver() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 82
def configure_driver
  Simulacrum::Browserstack::Driver.use
end
configure_environment(name, caps) click to toggle source

rubocop:disable MethodLength

# File lib/simulacrum/browserstack/runner.rb, line 135
def configure_environment(name, caps)
  ENV['SELENIUM_REMOTE_URL']            = @tunnel.selenium_remote_url
  ENV['BS_DRIVER_NAME']                 = name
  ENV['SELENIUM_BROWSER']               = caps['browser']
  ENV['SELENIUM_VERSION']               = caps['browser_version'].to_s
  ENV['BS_AUTOMATE_OS']                 = caps['os']
  ENV['BS_AUTOMATE_OS_VERSION']         = caps['os_version'].to_s
  ENV['BS_AUTOMATE_RESOLUTION']         = caps['resolution']
  ENV['BS_AUTOMATE_REQUIREWINDOWFOCUS'] = caps['requireWindowFocus'].to_s
  ENV['BS_AUTOMATE_PLATFORM']           = caps['platform']
  ENV['BS_AUTOMATE_DEVICE']             = caps['device']
  ENV['BS_AUTOMATE_DEVICEORIENTATION']  = caps['deviceOrientation']
  ENV['BS_BROWSERNAME']                 = caps['browserName']
  ENV['BS_REALMOBILE']                  = caps['realMobile'].to_s
end
configure_rspec() click to toggle source
Calls superclass method
# File lib/simulacrum/browserstack/runner.rb, line 77
def configure_rspec
  super
  RSpec.configuration.instance_variable_set(:@reporter, reporter)
end
dump_results() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 94
def dump_results
  Marshal.dump(formatter.output_hash)
end
ensure_available_remote_runner() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 98
def ensure_available_remote_runner
  with_retries(max_tries: 20, base_sleep_seconds: 0.5, max_sleep_seconds: 15) do
    remote_worker_available?
  end
end
find_available_port() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 170
def find_available_port
  server = TCPServer.new('127.0.0.1', 0)
  server.addr[1]
ensure
  server.close if server
end
formatter() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 90
def formatter
  @formatter ||= Simulacrum::Formatters::SimulacrumFormatter.new($stdout)
end
processes() click to toggle source

rubocop:enable MethodLength

# File lib/simulacrum/browserstack/runner.rb, line 152
def processes
  Simulacrum.runner_options.max_processes || @api.account_details.sessions_allowed
end
quit_browser() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 64
def quit_browser
  Capybara.current_session.driver.browser.quit
end
remote_worker_available?() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 104
def remote_worker_available?
  account_details = @api.account_details
  unless account_details.sessions_running < account_details.sessions_allowed
    fail NoRemoteSessionsAvailable
  end
end
reporter() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 86
def reporter
  @reporter ||= RSpec::Core::Reporter.new(formatter)
end
set_global_env() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 156
def set_global_env
  ENV['SELENIUM_REMOTE_URL'] = @tunnel.selenium_remote_url
end
start_timer() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 111
def start_timer
  @start_time = Time.now
end
stop_timer() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 115
def stop_timer
  @end_time = Time.now
end
summarize_exit_codes() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 126
def summarize_exit_codes
  @exit_code = (@process_exit_codes.inject(&:+) == 0) ? 0 : 1
end
summarize_results() click to toggle source
# File lib/simulacrum/browserstack/runner.rb, line 119
def summarize_results
  summary = Simulacrum::Browserstack::Summary.new(@process_results, @start_time, @end_time)
  summary.dump_summary
  summary.dump_failures
  summary.dump_pending
end