Class: Appium::Driver

Inherits:
Object
  • Object
show all
Defined in:
lib/appium_lib/driver.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}, global_driver = nil) ⇒ Driver

Creates a new driver. The driver is defined as global scope by default. We can avoid defining global driver.

Examples:


require 'rubygems'
require 'appium_lib'

# platformName takes a string or a symbol.
# Start iOS driver with global scope
opts = {
         caps: {
           platformName: :ios,
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait_timeout: 30
         }
       }
Appium::Driver.new(opts, true).start_driver

# Start Android driver with global scope
opts = {
         caps: {
           platformName: :android,
           app: '/path/to/my.apk'
         },
         appium_lib: {
           wait_timeout: 30,
           wait_interval: 1
         }
       }
Appium::Driver.new(opts, true).start_driver

# Start iOS driver without global scope
opts = {
         caps: {
           platformName: :ios,
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait_timeout: 30
         }
       }
Appium::Driver.new(opts, false).start_driver

Parameters:

  • opts (Object) (defaults to: {})

    A hash containing various options.

  • global_driver (Bool) (defaults to: nil)

    A bool require global driver before initialize.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/appium_lib/driver.rb', line 111

def initialize(opts = {}, global_driver = nil)
  # TODO: set `global_driver = false` by default in the future.
  if global_driver.nil?
    warn '[DEPRECATION] Appium::Driver.new(opts) will not generate global driver by default.' \
             'If you would like to generate the global driver dy default, ' \
             'please initialise driver with Appium::Driver.new(opts, true)'
    global_driver = true # if global_driver is nil, then global_driver must be default value.
  end

  if global_driver
    $driver.driver_quit if $driver
  end
  raise 'opts must be a hash' unless opts.is_a? Hash

  @core = Appium::Core.for(self, opts)

  opts = Appium.symbolize_keys opts
  appium_lib_opts = opts[:appium_lib] || {}

  @caps = @core.caps
  @custom_url = @core.custom_url
  @export_session = @core.export_session
  @export_session_path = @core.export_session_path
  @default_wait = @core.default_wait
  @appium_port = @core.port
  @appium_wait_timeout = @core.wait_timeout
  @appium_wait_interval = @core.wait_interval
  @listener = @core.listener
  @appium_device = @core.device
  @automation_name = @core.automation_name

  # override opts[:app] if sauce labs
  set_app_path(opts)

  # enable debug patch
  @appium_debug = appium_lib_opts.fetch :debug, !!defined?(Pry)
  set_sauce_related_values(appium_lib_opts)

  # Extend Common methods
  extend Appium::Common

  # Extend each driver's methods
  extend_for(device: @core.device, automation_name: @core.automation_name)

  # for command

  if @appium_debug
    Appium::Logger.ap_debug opts unless opts.empty?
    Appium::Logger.debug "Debug is: #{@appium_debug}"
    Appium::Logger.debug "Device is: #{@core.device}"
  end

  # Save global reference to last created Appium driver for top level methods.
  $driver = self if global_driver

  self # return newly created driver
end

Instance Attribute Details

#appium_debugObject (readonly)

Boolean debug mode for the Appium Ruby bindings



55
56
57
# File 'lib/appium_lib/driver.rb', line 55

def appium_debug
  @appium_debug
end

#appium_deviceObject (readonly)

Returns the value of attribute appium_device



45
46
47
# File 'lib/appium_lib/driver.rb', line 45

def appium_device
  @appium_device
end

#appium_portObject (readonly)

Returns the value of attribute appium_port



44
45
46
# File 'lib/appium_lib/driver.rb', line 44

def appium_port
  @appium_port
end

#appium_server_statusObject (readonly)

Appium's server version



53
54
55
# File 'lib/appium_lib/driver.rb', line 53

def appium_server_status
  @appium_server_status
end

#appium_wait_intervalObject (readonly)

Returns the value of attribute appium_wait_interval



50
51
52
# File 'lib/appium_lib/driver.rb', line 50

def appium_wait_interval
  @appium_wait_interval
end

#appium_wait_timeoutObject (readonly)

Returns the value of attribute appium_wait_timeout



49
50
51
# File 'lib/appium_lib/driver.rb', line 49

def appium_wait_timeout
  @appium_wait_timeout
end

#automation_nameObject (readonly)

Returns the value of attribute automation_name



46
47
48
# File 'lib/appium_lib/driver.rb', line 46

def automation_name
  @automation_name
end

#capsObject (readonly)

from Core



39
40
41
# File 'lib/appium_lib/driver.rb', line 39

def caps
  @caps
end

#coreObject (readonly)

Instance of Appium::Core::Driver



60
61
62
# File 'lib/appium_lib/driver.rb', line 60

def core
  @core
end

#custom_urlObject (readonly)

Returns the value of attribute custom_url



40
41
42
# File 'lib/appium_lib/driver.rb', line 40

def custom_url
  @custom_url
end

#default_waitObject (readonly)

Returns the value of attribute default_wait



43
44
45
# File 'lib/appium_lib/driver.rb', line 43

def default_wait
  @default_wait
end

#driverDriver (readonly)

Returns the driver

Returns:



58
59
60
# File 'lib/appium_lib/driver.rb', line 58

def driver
  @driver
end

#export_sessionObject (readonly)

Returns the value of attribute export_session



41
42
43
# File 'lib/appium_lib/driver.rb', line 41

def export_session
  @export_session
end

#export_session_pathObject (readonly)

Returns the value of attribute export_session_path



42
43
44
# File 'lib/appium_lib/driver.rb', line 42

def export_session_path
  @export_session_path
end

#global_webdriver_http_sleepObject

The amount to sleep in seconds before every webdriver http call.



24
25
26
# File 'lib/appium_lib/driver.rb', line 24

def global_webdriver_http_sleep
  @global_webdriver_http_sleep
end

#http_clientObject (readonly)

Returns the value of attribute http_client



48
49
50
# File 'lib/appium_lib/driver.rb', line 48

def http_client
  @http_client
end

#listenerObject (readonly)

Returns the value of attribute listener



47
48
49
# File 'lib/appium_lib/driver.rb', line 47

def listener
  @listener
end

#sauceObject (readonly)

SauceLab's settings



27
28
29
# File 'lib/appium_lib/driver.rb', line 27

def sauce
  @sauce
end

#sauce_access_keyObject (readonly)

Access Key for use on Sauce Labs. Set `false` to disable Sauce, even when SAUCE_ACCESS_KEY is in ENV. same as @sauce.access_key



33
34
35
# File 'lib/appium_lib/driver.rb', line 33

def sauce_access_key
  @sauce_access_key
end

#sauce_endpointObject (readonly)

Override the Sauce Appium endpoint to allow e.g. TestObject tests same as @sauce.endpoint



36
37
38
# File 'lib/appium_lib/driver.rb', line 36

def sauce_endpoint
  @sauce_endpoint
end

#sauce_usernameObject (readonly)

Username for use on Sauce Labs. Set `false` to disable Sauce, even when SAUCE_USERNAME is in ENV. same as @sauce.username



30
31
32
# File 'lib/appium_lib/driver.rb', line 30

def sauce_username
  @sauce_username
end

Class Method Details

.absolute_app_path(opts) ⇒ String

Converts app_path to an absolute path.

opts is the full options hash (caps and appium_lib). If server_url is set then the app path is used as is.

if app isn't set then an error is raised.

Returns:

  • (String)

    APP_PATH as an absolute path



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/appium_lib/driver.rb', line 332

def self.absolute_app_path(opts)
  raise 'opts must be a hash' unless opts.is_a? Hash
  caps            = opts[:caps] || {}
  appium_lib_opts = opts[:appium_lib] || {}
  server_url      = appium_lib_opts.fetch :server_url, false

  app_path        = caps[:app]
  raise 'absolute_app_path invoked and app is not set!' if app_path.nil? || app_path.empty?
  # may be absolute path to file on remote server.
  # if the file is on the remote server then we can't check if it exists
  return app_path if server_url
  # 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 =~ /^http/ # public URL for Sauce
  if app_path =~ /^(\/|[a-zA-Z]:)/ # absolute file path
    app_path = File.expand_path app_path unless File.exist? app_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 =~ /[\/\\]/

  # relative path that must be expanded.
  # absolute_app_path is called from load_settings
  # and the txt file path is the base of the app path in that case.
  app_path = File.expand_path app_path
  raise "App doesn't exist #{app_path}" unless File.exist? app_path
  app_path
end

Instance Method Details

#appium_client_versionHash

Returns the client's version info

Examples:


{
    "version" => "9.1.1"
}

Returns:

  • (Hash)


320
321
322
# File 'lib/appium_lib/driver.rb', line 320

def appium_client_version
  { version: ::Appium::VERSION }
end

#appium_server_versionHash

Returns the server's version info

Examples:

{
  "build" => {
      "version" => "0.18.1",
      "revision" => "d242ebcfd92046a974347ccc3a28f0e898595198"
  }
}

Returns:

  • (Hash)


291
292
293
294
295
296
297
# File 'lib/appium_lib/driver.rb', line 291

def appium_server_version
  @core.appium_server_version
rescue Selenium::WebDriver::Error::WebDriverError => ex
  raise ::Appium::Core::Error::ServerError unless ex.message.include?('content-type=""')
  # server (TestObject for instance) does not respond to status call
  {}
end

#automation_name_is_espresso?Boolean

Return true if automationName is 'Espresso'

Returns:

  • (Boolean)


257
258
259
# File 'lib/appium_lib/driver.rb', line 257

def automation_name_is_espresso?
  !@core.automation_name.nil? && @core.automation_name == :espresso
end

#automation_name_is_uiautomator2?Boolean

Return true if automationName is 'uiautomator2'

Returns:

  • (Boolean)


251
252
253
# File 'lib/appium_lib/driver.rb', line 251

def automation_name_is_uiautomator2?
  !@core.automation_name.nil? && @core.automation_name == :uiautomator2
end

#automation_name_is_xcuitest?Boolean

Return true if automationName is 'XCUITest'

Returns:

  • (Boolean)


263
264
265
# File 'lib/appium_lib/driver.rb', line 263

def automation_name_is_xcuitest?
  !@core.automation_name.nil? && @core.automation_name == :xcuitest
end

#check_server_version_xcuitestBoolean

Return true if the target Appium server is over REQUIRED_VERSION_XCUITEST. If the Appium server is under REQUIRED_VERSION_XCUITEST, then error is raised.

Returns:

  • (Boolean)


270
271
272
273
274
275
276
277
278
# File 'lib/appium_lib/driver.rb', line 270

def check_server_version_xcuitest
  if automation_name_is_xcuitest? &&
      !@appium_server_status.empty? &&
      (@appium_server_status['build']['version'] < REQUIRED_VERSION_XCUITEST)
    raise(Appium::Core::Error::NotSupportedAppiumServer,
          "XCUITest requires Appium version >= #{REQUIRED_VERSION_XCUITEST}")
  end
  true
end

#device_is_android?Boolean

Returns:

  • (Boolean)


237
238
239
# File 'lib/appium_lib/driver.rb', line 237

def device_is_android?
  @core.device == :android
end

#device_is_ios?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/appium_lib/driver.rb', line 241

def device_is_ios?
  @core.device == :ios
end

#device_is_windows?Boolean

Returns:

  • (Boolean)


245
246
247
# File 'lib/appium_lib/driver.rb', line 245

def device_is_windows?
  @core.device == :windows
end

#driver_attributesObject

Returns a hash of the driver attributes



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/appium_lib/driver.rb', line 217

def driver_attributes
  {
      caps:                @core.caps,
      automation_name:     @core.automation_name,
      custom_url:          @core.custom_url,
      export_session:      @core.export_session,
      export_session_path: @core.export_session_path,
      default_wait:        @core.default_wait,
      sauce_username:      @sauce.username,
      sauce_access_key:    @sauce.access_key,
      sauce_endpoint:      @sauce.endpoint,
      port:                @core.port,
      device:              @core.device,
      debug:               @appium_debug,
      listener:            @listener,
      wait_timeout:        @core.wait_timeout,
      wait_interval:       @core.wait_interval
  }
end

#driver_quitvoid Also known as: quit_driver

This method returns an undefined value.

Quits the driver



392
393
394
# File 'lib/appium_lib/driver.rb', line 392

def driver_quit
  @core.quit_driver
end

#execute_script(script, *args) ⇒ Object

The same as @driver.execute_script

Parameters:

  • script (String)

    The script to execute

  • args (*args)

    The args to pass to the script

Returns:

  • (Object)


524
525
526
# File 'lib/appium_lib/driver.rb', line 524

def execute_script(script, *args)
  @driver.execute_script script, *args
end

#exists(pre_check = 0, post_check = @core.default_wait) { ... } ⇒ Boolean

Returns existence of element.

Example:

exists { button('sign in') } ? puts('true') : puts('false')

Parameters:

  • pre_check (Integer) (defaults to: 0)

    The amount in seconds to set the wait to before checking existence

  • post_check (Integer) (defaults to: @core.default_wait)

    The amount in seconds to set the wait to after checking existence

Yields:

  • The block to call

Returns:

  • (Boolean)


500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'lib/appium_lib/driver.rb', line 500

def exists(pre_check = 0, post_check = @core.default_wait)
  # do not uset set_wait here.
  # it will cause problems with other methods reading the default_wait of 0
  # which then gets converted to a 1 second wait.
  @driver.manage.timeouts.implicit_wait = pre_check
  # the element exists unless an error is raised.
  exists                                = true

  begin
    yield # search for element
  rescue
    exists = false # error means it's not there
  end

  # restore wait
  @driver.manage.timeouts.implicit_wait = post_check if post_check != pre_check

  exists
end

#find_element(*args) ⇒ Element

Calls @driver.find_element

If you call `Appium.promote_appium_methods`, you can call `find_element` directly.

Examples:


@driver = Appium::Driver.new(opts, false)
@driver.find_element :accessibility_id, zzz

Parameters:

  • args (*args)

    The args to use

Returns:

  • (Element)


561
562
563
# File 'lib/appium_lib/driver.rb', line 561

def find_element(*args)
  @driver.find_element(*args)
end

#find_elements(*args) ⇒ Array<Element>

Calls @driver.find_elements_with_appium

If you call `Appium.promote_appium_methods`, you can call `find_elements` directly.

If you call `Appium.promote_appium_methods`, you can call `find_elements` directly.

Examples:


@driver = Appium::Driver.new(opts, false)
@driver.find_elements :predicate, yyy

@driver = Appium::Driver.new(opts, false)
@driver.find_elements :predicate, yyy

Parameters:

  • args (*args)

    The args to use

Returns:

  • (Array<Element>)

    Array is empty when no elements are found.



546
547
548
# File 'lib/appium_lib/driver.rb', line 546

def find_elements(*args)
  @driver.find_elements(*args)
end

#ios_versionObject



306
307
308
309
# File 'lib/appium_lib/driver.rb', line 306

def ios_version
  warn '[DEPRECATION] ios_version will be removed. Please use platform_version instead.'
  platform_version
end

#no_waitObject

Set implicit wait to zero.



469
470
471
# File 'lib/appium_lib/driver.rb', line 469

def no_wait
  @driver.manage.timeouts.implicit_wait = 0
end

#platform_versionArray<Integer>

Return the platform version as an array of integers

Returns:

  • (Array<Integer>)


301
302
303
# File 'lib/appium_lib/driver.rb', line 301

def platform_version
  @core.platform_version
end

#restartDriver

Restarts the driver

Returns:



373
374
375
376
# File 'lib/appium_lib/driver.rb', line 373

def restart
  driver_quit
  start_driver
end

#screenshot(png_save_path) ⇒ nil

Takes a png screenshot and saves to the target path.

Examples:


screenshot '/tmp/hi.png'

Parameters:

  • png_save_path (String)

    the full path to save the png

Returns:

  • (nil)


386
387
388
# File 'lib/appium_lib/driver.rb', line 386

def screenshot(png_save_path)
  @core.screenshot png_save_path
end

#server_urlString

Get the server url

Returns:

  • (String)

    the server url



365
366
367
368
369
# File 'lib/appium_lib/driver.rb', line 365

def server_url
  return @core.custom_url if @core.custom_url
  return @sauce.server_url if @sauce.sauce_server_url?
  "http://127.0.0.1:#{@core.port}/wd/hub"
end

#set_implicit_wait(wait) ⇒ Object

To ignore error for Espresso Driver



459
460
461
462
463
464
465
466
# File 'lib/appium_lib/driver.rb', line 459

def set_implicit_wait(wait)
  @driver.manage.timeouts.implicit_wait = wait
rescue Selenium::WebDriver::Error::UnknownError => e
  unless e.message.include?('The operation requested is not yet implemented by Espresso driver')
    raise ::Appium::Core::Error::ServerError
  end
  {}
end

#set_location(opts = {}) ⇒ Selenium::WebDriver::Location

Note:

This method does not work on real devices.

Calls @driver.set_location

Parameters:

  • opts (Hash) (defaults to: {})

    consisting of:

Options Hash (opts):

  • :latitude (Float)

    the latitude in degrees (required)

  • :longitude (Float)

    the longitude in degees (required)

  • :altitude (Float)

    the altitude, defaulting to 75

Returns:

  • (Selenium::WebDriver::Location)

    the location constructed by the selenium webdriver



574
575
576
577
578
579
# File 'lib/appium_lib/driver.rb', line 574

def set_location(opts = {})
  latitude = opts.fetch(:latitude)
  longitude = opts.fetch(:longitude)
  altitude = opts.fetch(:altitude, 75)
  @driver.set_location(latitude, longitude, altitude)
end

#set_wait(timeout = nil) ⇒ void

This method returns an undefined value.

Set implicit wait. Default to @core.default_wait.

Examples:


set_wait 2
set_wait # @core.default_wait

Parameters:

  • timeout (Integer) (defaults to: nil)

    the timeout in seconds



483
484
485
486
# File 'lib/appium_lib/driver.rb', line 483

def set_wait(timeout = nil)
  timeout = @core.default_wait if timeout.nil?
  @driver.manage.timeouts.implicit_wait = timeout
end

#start_driver(http_client_ops = { http_client: ::Appium::Http::Default.new, open_timeout: 999_999, read_timeout: 999_999 }) ⇒ Selenium::WebDriver

Creates a new global driver and quits the old one if it exists. You can customise http_client as the following

Examples:


require 'rubygems'
require 'appium_lib'

# platformName takes a string or a symbol.
# Start iOS driver
opts = {
         caps: {
           platformName: :ios,
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait_timeout: 30
         }
       }
Appium::Driver.new(opts).start_driver

Parameters:

  • http_client_ops (Hash) (defaults to: { http_client: ::Appium::Http::Default.new, open_timeout: 999_999, read_timeout: 999_999 })

    a customizable set of options

Options Hash (http_client_ops):

  • :http_client (Hash)

    Custom HTTP Client

  • :open_timeout (Hash)

    Custom open timeout for http client.

  • :read_timeout (Hash)

    Custom read timeout for http client.

Returns:

  • (Selenium::WebDriver)

    the new global driver



435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/appium_lib/driver.rb', line 435

def start_driver(http_client_ops =
                     { http_client: ::Appium::Http::Default.new, open_timeout: 999_999, read_timeout: 999_999 })
  @core.quit_driver

  # If automationName is set only in server side, then the following automation_name should be nil before
  # starting driver.
  automation_name = @core.automation_name

  @driver = @core.start_driver(server_url: server_url, http_client_ops: http_client_ops)
  @http_client = @core.http_client

  # if automation_name was nil before start_driver, then re-extend driver specific methods
  # to be able to extend correctly.
  extend_for(device: @core.device, automation_name: @core.automation_name) if automation_name.nil?

  @appium_server_status = appium_server_version
  check_server_version_xcuitest

  set_implicit_wait(@core.default_wait)

  @driver
end

#window_sizeSelenium::WebDriver::Dimension

Get the device window's size.

Examples:


size = @driver.window_size
size.width #=> Integer
size.height #=> Integer

Returns:

  • (Selenium::WebDriver::Dimension)


406
407
408
# File 'lib/appium_lib/driver.rb', line 406

def window_size
  @driver.window_size
end

#xvoid

This method returns an undefined value.

Quit the driver and Pry. quit and exit are reserved by Pry.



584
585
586
587
# File 'lib/appium_lib/driver.rb', line 584

def x
  driver_quit
  exit # exit pry
end