Class: Appium::Core::Driver

Inherits:
Object
  • Object
show all
Extended by:
Appium::Core, Device
Includes:
Waitable
Defined in:
lib/appium_lib_core/driver.rb,
sig/lib/appium_lib_core/driver.rbs

Constant Summary collapse

DEFAULT_APPIUM_PORT =

Returns:

  • (Integer)
4723

Constants included from Appium::Core

DATE, VERSION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Device

add_endpoint_method, extend_webdriver_with_forwardable, extended

Methods included from Forwardable

#def_delegator, #def_delegators, #def_instance_delegator, #def_instance_delegators, #def_single_delegator, #def_single_delegators

Methods included from Waitable

#wait_until, #wait_until_true

Constructor Details

#initializeDriver

Returns a new instance of Driver.



394
395
396
397
398
# File 'lib/appium_lib_core/driver.rb', line 394

def initialize
  @bridge_extensions = Module.new
  @delegate_target = self # for testing purpose
  @automation_name = nil # initialise before 'set_automation_name'
end

Instance Attribute Details

#automation_nameSymbol (readonly)

Automation name sent to appium server or received by server.
If automation_name is nil, it is not set both client side and server side.

Returns:

  • (Symbol)


189
190
191
# File 'lib/appium_lib_core/driver.rb', line 189

def automation_name
  @automation_name
end

#bridge_extensionsModule (readonly)

Returns:

  • (Module)


165
166
167
# File 'lib/appium_lib_core/driver.rb', line 165

def bridge_extensions
  @bridge_extensions
end

#capsCore::Base::Capabilities (readonly)

Selenium webdriver capabilities, but the value is provided capabilities basis.



169
170
171
# File 'lib/appium_lib_core/driver.rb', line 169

def caps
  @caps
end

#custom_urlString (readonly)

Custom URL for the selenium server. If set this attribute, ruby_lib_core try to handshake to the custom url.
Defaults to false. Then try to connect to http://127.0.0.1:##port.

Returns:

  • (String)


194
195
196
# File 'lib/appium_lib_core/driver.rb', line 194

def custom_url
  @custom_url
end

#default_waitInteger (readonly)

Default wait time for elements to appear in Appium server side. Provide { appium_lib: { wait: 30 } } to Appium::Core.for

Returns:

  • (Integer)


199
200
201
# File 'lib/appium_lib_core/driver.rb', line 199

def default_wait
  @default_wait
end

#deviceSymbol (readonly)

Device type to request from the appium server

Returns:

  • (Symbol)

    :android and :ios, for example



184
185
186
# File 'lib/appium_lib_core/driver.rb', line 184

def device
  @device
end

#direct_connectBool (readonly)

Enable updating Http client endpoint following below keys by Appium/Selenium server.
This works with Base::Http::Default.

If your Selenium/Appium server decorates the new session capabilities response with the following keys:

  • directConnectProtocol
  • directConnectHost
  • directConnectPort
  • directConnectPath

ignore them if this parameter is false. Defaults to true. These keys can have appium: prefix.

Note that the server should provide the keys with valid values. The host value must not be

  • loopback (for example 127.0.0.1, ::1)
  • link-local (for example 169.254.x.x, fe80::/10)
  • unspecified/wildcard (0.0.0.0, ::)
  • multicast (224.0.0.0/4, ff00::/8)

Returns:

  • (Bool)


246
247
248
# File 'lib/appium_lib_core/driver.rb', line 246

def direct_connect
  @direct_connect
end

#driverAppium::Core::Base::Driver (readonly)



225
226
227
# File 'lib/appium_lib_core/driver.rb', line 225

def driver
  @driver
end

#enable_idempotency_headerBool (readonly)

Return if adding 'x-idempotency-key' header is enabled for each new session request. Following commands should not have the key. The key is unique for each http client instance. Defaults to true https://github.com/appium/appium-base-driver/pull/400

Returns:

  • (Bool)


180
181
182
# File 'lib/appium_lib_core/driver.rb', line 180

def enable_idempotency_header
  @enable_idempotency_header
end

#http_clientAppium::Core::Base::Http::Default (readonly)

Return http client called in start_driver()

Returns:



173
174
175
# File 'lib/appium_lib_core/driver.rb', line 173

def http_client
  @http_client
end

#listenerSelenium::WebDriver::Support::AbstractEventListener (readonly)

instance of AbstractEventListener for logging support Nil by default



222
223
224
# File 'lib/appium_lib_core/driver.rb', line 222

def listener
  @listener
end

#portInteger (readonly)

Appium's server port. 4723 is by default. Defaults to DEFAULT_APPIUM_PORT.
Provide { appium_lib: { port: 8080 } } to Appium::Core.for. :custom_url is prior than :port if :custom_url is set.

Returns:

  • (Integer)


205
206
207
# File 'lib/appium_lib_core/driver.rb', line 205

def port
  @port
end

#wait_intervalInteger (readonly)

Return a time to wait interval. 0.5 seconds is by default Wait::DEFAULT_INTERVAL.
Wait interval time for Base::Wait, wait and wait_true.
Provide { appium_lib: { wait_interval: 0.1 } } to Appium::Core.for.

Returns:

  • (Integer)


218
219
220
# File 'lib/appium_lib_core/driver.rb', line 218

def wait_interval
  @wait_interval
end

#wait_timeoutInteger (readonly)

Return a time wait timeout. 30 seconds is by default Wait::DEFAULT_TIMEOUT.
Wait time for Base::Wait, wait and wait_true.
Provide { appium_lib: { wait_timeout: 20 } } to Appium::Core.for.

Returns:

  • (Integer)


212
213
214
# File 'lib/appium_lib_core/driver.rb', line 212

def wait_timeout
  @wait_timeout
end

Class Method Details

.attach_to(session_id, url: nil, automation_name: nil, platform_name: nil, http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 }) ⇒ Selenium::WebDriver

Attach to an existing session. The main usage of this method is to attach to an existing session for debugging. The generated driver instance has the capabilities which has the given automationName and platformName only since the W3C WebDriver spec does not provide an endpoint to get running session's capabilities.

Examples:


new_driver = ::Appium::Core::Driver.attach_to(
  driver.session_id,  # The 'driver' has an existing session id
  url: 'http://127.0.0.1:4723', automation_name: 'UiAutomator2', platform_name: 'Android'
)
new_driver.page_source # for example

Parameters:

  • session_id (String)

    The session id to attach to.

  • url (String) (defaults to: nil)

    The WebDriver URL to attach to with the session_id.

  • automation_name (String) (defaults to: nil)

    The platform name to keep in the dummy capabilities

  • platform_name (String) (defaults to: nil)

    The automation name to keep in the dummy capabilities

Returns:



372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/appium_lib_core/driver.rb', line 372

def self.attach_to(
  session_id, url: nil, automation_name: nil, platform_name: nil,
  http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 }
)
  new.attach_to(
    session_id,
    automation_name: automation_name,
    platform_name: platform_name,
    url: url,
    http_client_ops: http_client_ops
  )
end

.for(opts = {}) ⇒ Driver

Creates a new driver and extend particular methods

Examples:


# format 1
@core = Appium::Core.for caps: {...}, appium_lib: {...}
# format 2. 'capabilities:' is also available instead of 'caps:'.
@core = Appium::Core.for url: "http://127.0.0.1:8080", capabilities: {...}, appium_lib: {...}

require 'rubygems'
require 'appium_lib_core'

# Start iOS driver
opts = {
         caps: {
           platformName: :ios,
           platformVersion: '11.0',
           deviceName: 'iPhone Simulator',
           automationName: 'XCUITest',
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           port: 8080,
           wait: 0,
           wait_timeout: 20,
           wait_interval: 0.3,
           listener: nil,
         }
       }
@core = Appium::Core.for(opts) # create a core driver with 'opts' and extend methods into 'self'
@core.start_driver # Connect to 'http://127.0.0.1:8080' because of 'port: 8080'

# Start iOS driver with .zip file over HTTP
# 'capabilities:' is also available instead of 'caps:'. Either is fine.
opts = {
         capabilities: {
           platformName: :ios,
           platformVersion: '11.0',
           deviceName: 'iPhone Simulator',
           automationName: 'XCUITest',
           app: 'http://example.com/path/to/MyiOS.app.zip'
         },
         appium_lib: {
           server_url: 'http://custom-host:8080/wd/hub',
           wait: 0,
           wait_timeout: 20,
           wait_interval: 0.3,
           listener: nil,
         }
       }
@core = Appium::Core.for(opts)
@core.start_driver # Connect to 'http://custom-host:8080/wd/hub'

# Start iOS driver as another format. 'url' is available like below
opts = {
         url: "http://custom-host:8080/wd/hub",
         capabilities: {
           platformName: :ios,
           platformVersion: '11.0',
           deviceName: 'iPhone Simulator',
           automationName: 'XCUITest',
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait: 0,
           wait_timeout: 20,
           wait_interval: 0.3,
           listener: nil,
         }
       }
@core = Appium::Core.for(opts) # create a core driver with 'opts' and extend methods into 'self'
@core.start_driver # start driver with 'url'. Connect to 'http://custom-host:8080/wd/hub'

# With a custom listener
class CustomListener < ::Selenium::WebDriver::Support::AbstractEventListener
  // something
end
capabilities: {
  platformName: :ios,
  platformVersion: '11.0',
  deviceName: 'iPhone Simulator',
  automationName: 'XCUITest',
  app: '/path/to/MyiOS.app'
},
appium_lib: {
  listener: CustomListener.new,
}
@core = Appium::Core.for capabilities: capabilities, appium_lib: appium_lib
@core.start_driver

Parameters:

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

    A options include capabilities for the Appium Server and for the client.

Options Hash (opts):

  • :caps (Hash)

    Appium capabilities.

  • :capabilities (Hash)

    The same as :caps. This param is for compatibility with Selenium WebDriver format

  • :appium_lib (Appium::Core::Options)

    Capabilities affect only ruby client

  • :url (String)

    The same as :custom_url in :appium_lib. This param is for compatibility with Selenium WebDriver format

Returns:



348
349
350
# File 'lib/appium_lib_core/driver.rb', line 348

def self.for(opts = {})
  new.setup_for_new_session(opts)
end

Instance Method Details

#appium_server_versionHash

Returns the server's version info. This method calls driver.remote_status internally

Returns blank hash in a case driver.remote_status got an error such as Selenium Grid. It returns 500 error against 'remote_status'.

Examples:


@core.appium_server_version
  {
      "build" => {
          "version" => "1.9.2",
          "git-sha" => "fd7c7fd19d3896719616cd970229d73e63b5271a",
          "built" => "2018-11-08 12:24:02 +0900"
      }
  }

@core.appium_server_version #=> {}

Returns:

  • (Hash)


590
591
592
593
594
595
596
597
598
# File 'lib/appium_lib_core/driver.rb', line 590

def appium_server_version
  return {} if @driver.nil?

  @driver.remote_status
rescue StandardError
  # Ignore error case in a case the target appium server
  # does not support `/status` API.
  {}
end

#attach_to(session_id, url: nil, automation_name: nil, platform_name: nil, http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 }) ⇒ Object

Attach to an existing session

Parameters:

  • session_id (Object)
  • url: (Object, nil) (defaults to: nil)
  • automation_name: (Symbol) (defaults to: nil)
  • platform_name: (Object, nil) (defaults to: nil)
  • http_client_ops: (Hash[untyped, untyped]) (defaults to: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })

Returns:

  • (Object)

Raises:



514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'lib/appium_lib_core/driver.rb', line 514

def attach_to(session_id, url: nil, automation_name: nil, platform_name: nil,
              http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })
  raise ::Appium::Core::Error::ArgumentError, 'The :url must not be nil' if url.nil?
  raise ::Appium::Core::Error::ArgumentError, 'The :automation_name must not be nil' if automation_name.nil?
  raise ::Appium::Core::Error::ArgumentError, 'The :platform_name must not be nil' if platform_name.nil?

  @custom_url = url

  # use lowercase internally
  @automation_name = convert_downcase(automation_name)
  @device = convert_downcase(platform_name)

  extend_for(device: @device, automation_name: @automation_name)

  @http_client = get_http_client http_client: http_client_ops.delete(:http_client),
                                 open_timeout: http_client_ops.delete(:open_timeout),
                                 read_timeout: http_client_ops.delete(:read_timeout)

  # Note that 'enable_idempotency_header' works only a new session reqeust. The attach_to method skips
  # the new session request, this it does not needed.

  begin
    # included https://github.com/SeleniumHQ/selenium/blob/43f8b3f66e7e01124eff6a5805269ee441f65707/rb/lib/selenium/webdriver/remote/driver.rb#L29
    @driver = ::Appium::Core::Base::Driver.new(http_client: @http_client,
                                               url: @custom_url,
                                               listener: @listener,
                                               bridge_extensions: @bridge_extensions,
                                               existing_session_id: session_id,
                                               automation_name: automation_name,
                                               platform_name: platform_name)
  rescue Errno::ECONNREFUSED
    raise ::Appium::Core::Error::SessionNotCreatedError,
          "ERROR: Unable to connect to Appium. Is the server running on #{@custom_url}?"
  end

  @driver
end

#convert_downcase(value) ⇒ Symbol

Parameters:

  • value (String, Symbol)

Returns:

  • (Symbol)


759
760
761
# File 'lib/appium_lib_core/driver.rb', line 759

def convert_downcase(value)
  value.is_a?(Symbol) ? value.downcase : value.downcase.strip.intern
end

#convert_to_symbol(value) ⇒ Symbol?

Parameters:

  • value (Object, nil)

Returns:

  • (Symbol, nil)


602
603
604
605
606
607
608
# File 'lib/appium_lib_core/driver.rb', line 602

def convert_to_symbol(value)
  if value.nil?
    value
  else
    value.to_sym
  end
end

#delegated_target_for_testself

For testing purpose of delegate_from_appium_driver

Returns:

  • (self)


389
390
391
# File 'lib/appium_lib_core/driver.rb', line 389

def delegated_target_for_test
  @delegate_target
end

#extend_for(device:, automation_name:) ⇒ self

Parameters:

  • device: (Symbol, String)
  • automation_name: (Symbol)

Returns:

  • (self)


611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# File 'lib/appium_lib_core/driver.rb', line 611

def extend_for(device:, automation_name:) # rubocop:disable Metrics/CyclomaticComplexity
  extend Appium::Core
  extend Appium::Core::Device

  sym_automation_name = convert_to_symbol(automation_name)

  case convert_to_symbol(device)
  when :android
    case sym_automation_name
    when :espresso
      ::Appium::Core::Android::Espresso::Bridge.for self
    when :uiautomator2
      ::Appium::Core::Android::Uiautomator2::Bridge.for self
    when :gecko
      ::Appium::Logger.debug('Gecko Driver for Android')
    else # default and UiAutomator
      ::Appium::Core::Android::Uiautomator1::Bridge.for self
    end
  when :ios, :tvos
    case sym_automation_name
    when :safari
      ::Appium::Logger.debug('SafariDriver for iOS')
    else # XCUITest
      ::Appium::Core::Ios::Xcuitest::Bridge.for self
    end
  when :mac
    case sym_automation_name
    when :safari
      ::Appium::Logger.debug('SafariDriver for macOS')
    when :gecko
      ::Appium::Logger.debug('Gecko Driver for macOS')
    when :mac2
      ::Appium::Core::Mac2::Bridge.for self
    else
      # no Mac specific extentions
      ::Appium::Logger.debug('macOS Native')
    end
  when :windows
    case sym_automation_name
    when :gecko
      ::Appium::Logger.debug('Gecko Driver for Windows')
    else
      ::Appium::Core::Windows::Bridge.for self
    end
  when :tizen
    # https://github.com/Samsung/appium-tizen-driver
    ::Appium::Logger.debug('tizen')
  else
    case sym_automation_name
    when :youiengine
      # https://github.com/YOU-i-Labs/appium-youiengine-driver
      ::Appium::Logger.debug('YouiEngine')
    when :mac
      # In this case also can be mac
      ::Appium::Logger.debug('mac')
    when :gecko # other general platform
      ::Appium::Logger.debug('Gecko Driver')
    else
      ::Appium::Logger.warn("No matched driver by platformName: #{device} and automationName: #{automation_name}")
    end
  end

  self
end

#get_appString?

Returns:

  • (String, nil)


694
695
696
# File 'lib/appium_lib_core/driver.rb', line 694

def get_app
  get_cap 'app'
end

#get_appium_lib_opts(opts) ⇒ Hash[Symbol, untyped]

Parameters:

  • opts (Hash[Symbol, untyped], nil)

Returns:

  • (Hash[Symbol, untyped])


686
687
688
689
690
691
# File 'lib/appium_lib_core/driver.rb', line 686

def get_appium_lib_opts(opts)
  o = opts || {}

  val = o[:appium_lib]
  val.is_a?(Hash) ? val : {}
end

#get_cap(name) ⇒ Object

Parameters:

  • name (String, Symbol)

Returns:

  • (Object)


763
764
765
766
767
768
769
# File 'lib/appium_lib_core/driver.rb', line 763

def get_cap(name)
  name_with_prefix = "#{::Appium::Core::Base::Bridge::APPIUM_PREFIX}#{name}"
  @caps[convert_to_symbol name] ||
    @caps[name] ||
    @caps[convert_to_symbol name_with_prefix] ||
    @caps[name_with_prefix]
end

#get_caps(opts) ⇒ Core::Base::Capabilities

Parameters:

  • opts (Hash[Symbol, untyped], nil)

Returns:



677
678
679
680
681
682
683
684
# File 'lib/appium_lib_core/driver.rb', line 677

def get_caps(opts)
  o = opts || {}

  raw_caps = o[:caps] || o[:capabilities]
  caps_hash = raw_caps.is_a?(Hash) ? raw_caps : {} # steep:ignore

  Core::Base::Capabilities.new(caps_hash)
end

#get_http_client(http_client: nil, open_timeout: nil, read_timeout: nil) ⇒ Object

Parameters:

  • http_client: (Object, nil) (defaults to: nil)
  • open_timeout: (Object, nil) (defaults to: nil)
  • read_timeout: (Object, nil) (defaults to: nil)

Returns:

  • (Object)


552
553
554
# File 'lib/appium_lib_core/driver.rb', line 552

def get_http_client(http_client: nil, open_timeout: nil, read_timeout: nil)
  http_client || Appium::Core::Base::Http::Default.new(open_timeout: open_timeout, read_timeout: read_timeout)
end

#set_app_pathString?

Path to the .apk, .app or .app.zip. The path can be local, HTTP/S, Windows Share and other path like 'sauce-storage:'. Use @caps without modifications if the path isn't HTTP/S or local path.

Returns:

  • (String, nil)


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
# File 'lib/appium_lib_core/driver.rb', line 702

def set_app_path
  return unless @caps

  app = get_app # for steep reason
  return if app.nil? || app.empty?

  uri_regex = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER # steep:ignore
  return if app =~ uri_regex.make_regexp

  # steep:ignore
  app_path = File.expand_path(app)
  app_key = [:app, 'app', :'appium:app', 'appium:app'].find { |key| @caps[key] }
  @caps[app_key] = if File.exist? app_path
                     app_path
                   else
                     ::Appium::Logger.warn("Use #{app} directly since #{app_path} does not exist.")
                     app
                   end
end

#set_appium_deviceSymbol?

Returns:

  • (Symbol, nil)


743
744
745
746
747
748
749
# File 'lib/appium_lib_core/driver.rb', line 743

def set_appium_device
  # https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile
  @device = get_cap 'platformName'
  return unless @device

  @device = convert_to_symbol(convert_downcase(@device))
end

#set_appium_lib_specific_values(appium_lib_opts) ⇒ Object

Below capabilities are set only for client side.



724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'lib/appium_lib_core/driver.rb', line 724

def set_appium_lib_specific_values(appium_lib_opts)
  opts = Options.new appium_lib_opts

  @custom_url ||= opts.custom_url # Keep existence capability if it's already provided
  @enable_idempotency_header = opts.enable_idempotency_header

  @default_wait = opts.default_wait

  @port = opts.port

  @wait_timeout  = opts.wait_timeout
  @wait_interval = opts.wait_interval

  @listener = opts.listener

  @direct_connect = opts.direct_connect
end

#set_automation_nameSymbol?

Returns:

  • (Symbol, nil)


752
753
754
755
756
# File 'lib/appium_lib_core/driver.rb', line 752

def set_automation_name
  candidate = get_cap 'automationName'
  @automation_name = candidate if candidate
  @automation_name = convert_to_symbol(convert_downcase(@automation_name)) if @automation_name
end

#set_implicit_wait_by_default(wait) ⇒ Object

Ignore setting default wait if the target driver has no implementation

Parameters:

  • wait (Object)

Returns:

  • (Object)


557
558
559
560
561
562
563
564
565
566
# File 'lib/appium_lib_core/driver.rb', line 557

def set_implicit_wait_by_default(wait)
  return if @default_wait.nil?

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

  ::Appium::Logger.debug(e.message)
  {}
end

#setup_for_new_session(opts = {}) ⇒ self

Set up for a new session

Parameters:

  • opts (Hash[Symbol, Symbol | String | Hash[Symbol, String | Numeric] | Numeric]) (defaults to: {})

Returns:

  • (self)


404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/appium_lib_core/driver.rb', line 404

def setup_for_new_session(opts = {})
  @custom_url = opts.delete :url # to set the custom url as :url

  @caps = get_caps(opts)

  set_appium_lib_specific_values(get_appium_lib_opts(opts))
  set_app_path
  set_appium_device
  set_automation_name

  extend_for(device: @device, automation_name: @automation_name)
  self
end

#start_driver(server_url: nil, http_client_ops: { http_client: nil, 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_core'

# platformName takes a string or a symbol.

# Start iOS driver
opts = {
         capabilities: {
           platformName: :ios,
           platformVersion: '11.0',
           deviceName: 'iPhone Simulator',
           automationName: 'XCUITest',
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait: 20,
           wait_timeout: 20,
           wait_interval: 0.3,
         }
       }

@core = Appium::Core.for(opts) # create a core driver with 'opts' and extend methods into 'self'
@driver = @core.start_driver server_url: "http://127.0.0.1:8000"

# Attach custom HTTP client
@driver = @core.start_driver server_url: "http://127.0.0.1:8000",
                             http_client_ops: { http_client: Your:Http:Client.new,
                                                open_timeout: 1_000,
                                                read_timeout: 1_000 }

Parameters:

  • server_url (String) (defaults to: nil)

    Custom server url to send to requests. Default is "http://127.0.0.1:4723&quot;.

  • http_client_ops (Hash) (defaults to: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })

    Options for http client

  • server_url: (Object, nil) (defaults to: nil)
  • http_client_ops: (::Hash[untyped, untyped]) (defaults to: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })

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:



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/appium_lib_core/driver.rb', line 461

def start_driver(server_url: nil,
                 http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })
  @custom_url ||= "http://127.0.0.1:#{@port}"
  @custom_url = server_url unless server_url.nil?

  @http_client = get_http_client http_client: http_client_ops.delete(:http_client),
                                 open_timeout: http_client_ops.delete(:open_timeout),
                                 read_timeout: http_client_ops.delete(:read_timeout)

  if @enable_idempotency_header
    if @http_client.instance_variable_defined? :@additional_headers
      @http_client.set_additional_header Appium::Core::Base::Http::RequestHeaders::KEYS[:idempotency], SecureRandom.uuid
    else
      ::Appium::Logger.warn 'No additional_headers attribute in this http client instance'
    end
  end

  begin
    @driver = ::Appium::Core::Base::Driver.new(listener: @listener,
                                               http_client: @http_client,
                                               bridge_extensions: @bridge_extensions,
                                               capabilities: @caps, # ::Appium::Core::Base::Capabilities
                                               url: @custom_url,
                                               wait_timeout: @wait_timeout,
                                               wait_interval: @wait_interval)

    if @direct_connect
      d_c = DirectConnections.new(@driver.capabilities)
      if d_c.valid?
        @driver.update_sending_request_to(protocol: d_c.protocol, host: d_c.host, port: d_c.port, path: d_c.path)
      else
        ::Appium::Logger.warn(
          "Direct connect is enabled but the server did not provide valid direct connect information (#{d_c.protocol}, #{d_c.host}, #{d_c.port}, #{d_c.path}). " \
          "Continue with the original URL (#{@custom_url})"
        )
      end
    end
  rescue Errno::ECONNREFUSED => e
    raise "ERROR: Unable to connect to Appium. Is the server running on #{@custom_url}? Error: #{e}"
  end

  if @http_client.instance_variable_defined? :@additional_headers
    # We only need the key for a new session request. Should remove it for other following commands.
    @http_client.delete_additional_header Appium::Core::Base::Http::RequestHeaders::KEYS[:idempotency]
  end

  set_implicit_wait_by_default(@default_wait)

  @driver
end