class Appium::Driver

def absolute_app_path

Returns:
  • (String) - APP_PATH as an absolute path
def absolute_app_path
  raise 'APP_PATH not set!' if @app_path.nil? || @app_path.empty?
  # Sauce storage API. http://saucelabs.com/docs/rest#storage
  return @app_path if @app_path.start_with? 'sauce-storage:'
  return @app_path if @app_path.match(/^http/) # public URL for Sauce
  if @app_path.match(/^\//) # absolute file path
    raise "App doesn't exist. #{@app_path}" unless File.exist? @app_path
    return @app_path
  end
  # if it doesn't contain a slash then it's a bundle id
  return @app_path unless @app_path.match(/[\/\\]/)
  file = File.join(File.dirname(__FILE__), @app_path)
  raise "App doesn't exist #{file}" unless File.exist? file
  file
end

def android_capabilities

Other tags:
    Private: -
def android_capabilities
  {
    compressXml: @compress_xml,
    platform: 'LINUX',
    version: '4.2',
    device: @device == :android ? 'Android' : 'selendroid',
    name: @app_name || 'Ruby Console Android Appium',
    :'app-package' => @app_package,
    :'app-activity' => @app_activity,
    :'app-wait-activity' => @app_wait_activity || @app_activity
  }
end

def capabilities

Other tags:
    Private: -
def capabilities
  caps = @device == :ios ? ios_capabilities : android_capabilities
  caps[:app] = absolute_app_path unless @app_path.nil? || @app_path.empty?
  caps
end

def default_wait

Returns:
  • (Integer) -
def default_wait
  @default_wait
end

def driver

Returns:
  • (Driver) - the driver
def driver
  @driver
end

def driver_quit

Returns:
  • (void) -
def driver_quit
  # rescue NoSuchDriverError
  begin; @driver.quit unless @driver.nil?; rescue; end
end

def dynamic_code_to_string code, value=false

Other tags:
    Private: -
def dynamic_code_to_string code, value=false
  result = @@map[code].first
  return result unless value
  result.split('(').first + "( \"#{value}\" )"
end

def execute_script script, *args

Returns:
  • (Object) -

Parameters:
  • args (*args) -- the args to pass to the script
  • script (String) -- the script to execute
def execute_script script, *args
  @driver.execute_script script, *args
end

def exists pre_check=0, post_check=@default_wait, &search_block

Returns:
  • (Boolean) -

Parameters:
  • search_block (Block) -- the block to call
  • post_check (Integer) -- the amount in seconds to set the
  • pre_check (Integer) -- the amount in seconds to set the
def exists pre_check=0, post_check=@default_wait, &search_block
  set_wait pre_check # set wait to zero
  # the element exists unless an error is raised.
  exists = true
  begin
    search_block.call # search for element
  rescue
    exists = false # error means it's not there
  end
  # restore wait
  set_wait post_check if post_check != pre_check
  exists
end

def find_element *args

Returns:
  • (Element) -

Parameters:
  • args (*args) -- the args to use
def find_element *args
  @driver.find_element *args
end

def find_elements *args

Returns:
  • (Array) - Array is empty when no elements are found.

Parameters:
  • args (*args) -- the args to use
def find_elements *args
  @driver.find_elements *args
end

def initialize opts={}

Returns:
  • (Driver) -

Parameters:
  • opts (Object) -- A hash containing various options.
def initialize opts={}
  # quit last driver
  $driver.driver_quit if $driver
  opts = {} if opts.nil?
  # convert to downcased symbols
  opts.each_pair { |k,v| opts[k.to_s.downcase.strip.intern] = v }
  @custom_url = opts.fetch :server_url, false
  @compress_xml = opts[:compress_xml] ? true : false
  @export_session = opts.fetch :export_session, false
  @default_wait = opts.fetch :wait, 30
  # Path to the .apk, .app or .app.zip.
  # The path can be local or remote for Sauce.
  @app_path = opts.fetch :app_path, ENV['APP_PATH']
  raise 'APP_PATH must be set.' if @app_path.nil?
  # The name to use for the test run on Sauce.
  @app_name = opts.fetch :app_name, ENV['APP_NAME']
  # Android app package
  @app_package = opts.fetch :app_package, ENV['APP_PACKAGE']
  # Android app starting activity.
  @app_activity = opts.fetch :app_activity, ENV['APP_ACTIVITY']
  # Android app waiting activity
  @app_wait_activity = opts.fetch :app_wait_activity, ENV['APP_WAIT_ACTIVITY']
  # Sauce Username
  @sauce_username = opts.fetch :sauce_username, ENV['SAUCE_USERNAME']
  # Sauce Key
  @sauce_access_key = opts.fetch :sauce_access_key, ENV['SAUCE_ACCESS_KEY']
  @port = opts.fetch :port, ENV['PORT'] || 4723
  # device as used in device capabilities.
  # iOS only.
  #
  # Android is always Android or Selendroid so there's no
  # override required.
  @device_cap = opts.fetch :device_cap, false
  # :ios, :android, :selendroid
  @device = opts.fetch :device, ENV['DEVICE'] || :ios
  @device = @device.intern # device must be a symbol
  # load common methods
  extend Appium::Common
  if @device == :android
    raise 'APP_ACTIVITY must be set.' if @app_activity.nil?
    # load Android specific methods
    extend Appium::Android
  else
    # load iOS specific methods
    extend Appium::Ios
  end
  # apply os specific patches
  patch_webdriver_element
  # enable debug patch
  # !!'constant' == true
  @debug = opts.fetch :debug, !!defined?(Pry)
  puts "Debug is: #{@debug}"
  if @debug
    ap opts unless opts.empty?
    puts "Device is: #{@device}"
    patch_webdriver_bridge
  end
  # Save global reference to last created Appium driver for top level methods.
  $driver = self
  # Promote exactly once the first time the driver is created.
  # Subsequent drivers do not trigger promotion.
  unless @@loaded
    @@loaded = true
    # Promote only on Minitest::Spec (minitest 5) by default
    Appium.promote_appium_methods ::Minitest::Spec
  end
  self # return newly created driver
end # def initialize

def ios_capabilities

Other tags:
    Private: -
def ios_capabilities
  {
    platform: 'Mac 10.8',
    version: '6.1',
    device: @device_cap || 'iPhone Simulator',
    name: @app_name || 'Ruby Console iOS Appium'
  }
end

def mobile method, *args

Returns:
  • (Object) -

Parameters:
  • args (*args) -- the args to pass to the method
  • method (String, Symbol) -- the method to execute
def mobile method, *args
  raise 'Method must not be nil' if method.nil?
  raise 'Method must have .to_s' unless method.respond_to? :to_s
  @driver.execute_script "mobile: #{method.to_s}", *args
end

def no_wait

Set implicit wait to zero.
def no_wait
  @driver.manage.timeouts.implicit_wait = 0
end

def restart

Returns:
  • (Driver) - the driver
def restart
  driver_quit
  start_driver
end

def screenshot png_save_path

Returns:
  • (nil) -

Parameters:
  • png_save_path (String) -- the full path to save the png
def screenshot png_save_path
  @driver.save_screenshot png_save_path
  nil
end

def server_url

Returns:
  • (String) - the server url
def server_url
  return @custom_url if @custom_url
  if !@sauce_username.nil? && !@sauce_access_key.nil?
    "http://#{@sauce_username}:#{@sauce_access_key}@ondemand.saucelabs.com:80/wd/hub"
  else
    "http://127.0.0.1:#{@port}/wd/hub"
  end
end

def server_version

Returns:
  • (String) -
def server_version
  status['value']['build']['version']
end

def set_wait timeout=@default_wait

Returns:
  • (void) -

Parameters:
  • timeout (Integer) -- the timeout in seconds
def set_wait timeout=@default_wait
  @driver.manage.timeouts.implicit_wait = timeout
end

def start_driver

Returns:
  • (Selenium::WebDriver) - the new global driver
def start_driver
  @client = @client || Selenium::WebDriver::Remote::Http::Default.new
  @client.timeout = 999999
  begin
    @driver = Selenium::WebDriver.for :remote, http_client: @client, desired_capabilities: capabilities, url: server_url
    # Load touch methods. Required for Selendroid.
    @driver.extend Selenium::WebDriver::DriverExtensions::HasTouchScreen
    # export session
    if @export_session
      begin
        File.open('/tmp/appium_lib_session', 'w') do |f|
          f.puts @driver.session_id
        end
      rescue
      end
    end
  rescue Errno::ECONNREFUSED
    raise 'ERROR: Unable to connect to Appium. Is the server running?'
  end
  # Set timeout to a large number so that Appium doesn't quit
  # when no commands are entered after 60 seconds.
  # broken on selendroid: https://github.com/appium/appium/issues/513
  mobile :setCommandTimeout, timeout: 9999 unless @device == :selendroid
  # Set implicit wait by default unless we're using Pry.
  @driver.manage.timeouts.implicit_wait = @default_wait unless defined? Pry
  @driver
end

def status

Returns:
  • (JSON) -
def status
  driver.status.payload
end

def x

Returns:
  • (void) -
def x
  driver_quit
  exit # exit pry
end