Class: Appium::Core::Base::Driver

Inherits:
Selenium::WebDriver::Driver
  • Object
show all
Includes:
HasLocation, HasRemoteStatus, Rotatable, TakesScreenshot, Waitable, Selenium::WebDriver::DriverExtensions::HasSessionId, Selenium::WebDriver::DriverExtensions::UploadsFiles
Defined in:
lib/appium_lib_core/common/base/driver.rb

Constant Summary collapse

AVAILABLE_METHODS =
[
  :get, :head, :post, :put, :delete,
  :connect, :options, :trace, :patch
].freeze

Constants included from Rotatable

Rotatable::ORIENTATIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Waitable

#wait_until, #wait_until_true

Methods included from HasLocation

#location, #location=, #set_location

Methods included from HasRemoteStatus

#remote_status

Methods included from TakesScreenshot

#element_screenshot_as, #save_element_screenshot, #save_screenshot, #save_viewport_screenshot, #screenshot_as

Methods included from Rotatable

#orientation, #rotation=

Constructor Details

#initialize(bridge: nil, listener: nil, **opts) ⇒ Driver

override



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/appium_lib_core/common/base/driver.rb', line 48

def initialize(bridge: nil, listener: nil, **opts) # rubocop:disable Lint/MissingSuper
  original_opts = opts.dup

  # For ::Appium::Core::Waitable
  @wait_timeout = opts.delete(:wait_timeout)
  @wait_interval = opts.delete(:wait_interval)

  # Selenium WebDriver attributes
  @devtools = nil
  @bidi = nil

  # internal use
  @has_bidi = false

  # steep:ignore:start
  ::Selenium::WebDriver::Remote::Bridge.element_class = ::Appium::Core::Element
  # steep:ignore:end
  bridge ||= create_bridge(**opts)
  add_extensions(bridge.browser)
  @bridge = listener ? ::Appium::Support::EventFiringBridge.new(bridge, listener, **original_opts) : bridge
end

Instance Attribute Details

#bridgeObject (readonly)

Private API. Do not use this for general use. Used by flutter driver to get bridge for creating a new element



45
46
47
# File 'lib/appium_lib_core/common/base/driver.rb', line 45

def bridge
  @bridge
end

Instance Method Details

#activate_app(app_id) ⇒ Hash

Activate(Launch) the specified app.

Examples:


@driver.activate_app("io.appium.bundle") #=> {}


700
701
702
703
# File 'lib/appium_lib_core/common/base/driver.rb', line 700

def activate_app(app_id)
  # TODO: use mobile command in the background?
  @bridge.activate_app(app_id)
end

#add_command(method:, url:, name:, &block) ⇒ Object

Define a new custom method to the driver so that you can define your own method for drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you to define custom commands that are not part of W3C spec.

Uses Selenium’s Bridge.add_command under the hood to register the command and define the method on the bridge.

Examples:

Simple GET command (no block)


@driver.add_command(
  method: :get,
  url: 'session/:session_id/path/to/custom/url',
  name: :test_command
)
# Send a GET request to 'session/<session id>/path/to/custom/url'
@driver.test_command

POST command with arguments (do/end block)


@driver.add_command(
  method: :post,
  url: 'session/:session_id/path/to/custom/url',
  name: :test_command
) do |argument|
  execute(:test_command, {}, { dummy: argument })
end
# Send a POST request to 'session/<session id>/path/to/custom/url'
# with body "{ dummy: 1 }" as JSON object. "1" is the argument.
# ':session_id' in the given 'url' is replaced with current 'session id'.
@driver.test_command(1)

POST command with arguments (inline block)


@driver.add_command(
  method: :post,
  url: 'session/:session_id/path/to/custom/url',
  name: :test_command
) { |argument| execute(:test_command, {}, { dummy: argument }) }
@driver.test_command(1)

POST command with URL placeholders (do/end block)


@driver.add_command(
  method: :post,
  url: 'session/:session_id/element/:id/custom/action',
  name: :test_action_command
) do |element_id, action|
  execute(:test_action_command, {id: element_id}, { dummy_action: action })
end
# Send a POST request to 'session/<session id>/element/<element id>/custom/action'
# with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
# ':session_id' in the given url is replaced with current 'session id'.
# ':id' in the given url is replaced with the given 'element_id'.
e = @driver.find_element :accessibility_id, 'an element'
@driver.test_action_command(e.id, 'action')

POST command with URL placeholders (inline block)


@driver.add_command(
  method: :post,
  url: 'session/:session_id/element/:id/custom/action',
  name: :test_action_command
) { |element_id, action| execute(:test_action_command, {id: element_id}, { dummy_action: action }) }
e = @driver.find_element :accessibility_id, 'an element'
@driver.test_action_command(e.id, 'action')

Raises:

  • (ArgumentError)

    If the given method is invalid value.



211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/appium_lib_core/common/base/driver.rb', line 211

def add_command(method:, url:, name:, &block)
  raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}" unless AVAILABLE_METHODS.include? method

  ::Appium::Logger.info "Overriding the command '#{name}' for '#{url}'" if Bridge.extra_commands&.key?(name)

  # Use Selenium's Bridge.add_command to register the command and define the method.
  # When no block is given, create a default implementation that calls execute.
  block ||= proc { execute(name) }
  Bridge.add_command(name, method, url, &block)

  # Ensure the driver delegates the new method to bridge
  self.class.class_eval { def_delegator :@bridge, name } unless self.class.method_defined?(name)
end

#app_installed?(app_id) ⇒ Boolean

Check whether the specified app is installed on the device

Examples:


@driver.app_installed?("io.appium.bundle")


688
689
690
691
# File 'lib/appium_lib_core/common/base/driver.rb', line 688

def app_installed?(app_id)
  # TODO: use mobile command in the background?
  @bridge.app_installed?(app_id)
end

#app_state(app_id) ⇒ AppState::STATUS Also known as: query_app_state

Get the status of an existing application on the device. State:

:not_installed : The current application state cannot be determined/is unknown
:not_running : The application is not running
:running_in_background_suspended : The application is running in the background and is suspended
:running_in_background : The application is running in the background and is not suspended
:running_in_foreground : The application is running in the foreground

For more details: developer.apple.com/documentation/xctest/xcuiapplicationstate

Examples:


@driver.app_state("io.appium.bundle") #=> :not_running
# Compatibility for other clients
@driver.query_app_state("io.appium.bundle") #=> :not_running


741
742
743
# File 'lib/appium_lib_core/common/base/driver.rb', line 741

def app_state(app_id)
  @bridge.app_state(app_id)
end

#app_strings(language = nil) ⇒ Hash

Return the hash of all localization strings.

Examples:


@driver.app_strings #=> "TransitionsTitle"=>"Transitions", "WebTitle"=>"Web"


610
611
612
# File 'lib/appium_lib_core/common/base/driver.rb', line 610

def app_strings(language = nil)
  @bridge.app_strings(language)
end

#available_contextsArray<String>

Returns All usable contexts, as an array of strings.

Examples:


@driver.available_contexts


466
467
468
# File 'lib/appium_lib_core/common/base/driver.rb', line 466

def available_contexts
  @bridge.available_contexts
end

#backString

Get the device window’s size.

Examples:

@driver.back # back to the previous view


877
878
879
# File 'lib/appium_lib_core/common/base/driver.rb', line 877

def back
  navigate.back
end

#background_app(duration = 0) ⇒ String

Backgrounds the app for a set number of seconds. This is a blocking application

Examples:


@driver.background_app
@driver.background_app(5)
@driver.background_app(-1) #=> the app never come back. https://github.com/appium/appium/issues/7741


625
626
627
# File 'lib/appium_lib_core/common/base/driver.rb', line 625

def background_app(duration = 0)
  @bridge.background_app(duration)
end

#bidi::Selenium::WebDriver::BiDi

Return bidi instance

Examples:


log_entries = []
driver.bidi.send_cmd('session.subscribe', 'events': ['log.entryAdded'], 'contexts': ['NATIVE_APP'])
subscribe_id = driver.bidi.add_callback('log.entryAdded') do |params|
  log_entries << params
end
driver.page_source

driver.bidi.remove_callback('log.entryAdded', subscribe_id)
driver.bidi.send_cmd('session.unsubscribe', 'events': ['log.entryAdded'], 'contexts': ['NATIVE_APP'])

Raises:

  • (::Selenium::WebDriver::Error::WebDriverError)


1046
1047
1048
1049
1050
1051
# File 'lib/appium_lib_core/common/base/driver.rb', line 1046

def bidi
  return @bridge.bidi if @has_bidi

  msg = 'BiDi must be enabled by providing webSocketUrl capability to true'
  raise(::Selenium::WebDriver::Error::WebDriverError, msg)
end

#compare_images(mode: :matchFeatures, first_image:, second_image:, options: nil) ⇒ Object



934
935
936
# File 'lib/appium_lib_core/common/base/driver.rb', line 934

def compare_images(mode: :matchFeatures, first_image:, second_image:, options: nil)
  @bridge.compare_images(mode: mode, first_image: first_image, second_image: second_image, options: options)
end

#context=(context = nil) ⇒ Object Also known as: set_context

Change the context to the given context.

Examples:


@driver.set_context "NATIVE_APP"
@driver.context = "NATIVE_APP"


478
479
480
# File 'lib/appium_lib_core/common/base/driver.rb', line 478

def context=(context = nil)
  @bridge.set_context(context)
end

#convert_to_element(response_id) ⇒ ::Appium::Core::Element

Convert vanilla element response to ::Appium::Core::Element

Examples:

response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
ele.rect #=> Can get the rect of the element


1027
1028
1029
# File 'lib/appium_lib_core/common/base/driver.rb', line 1027

def convert_to_element(response_id)
  @bridge.convert_to_element response_id
end

#current_contextString

Returns The context currently being used.

Examples:


@driver.current_context


456
457
458
# File 'lib/appium_lib_core/common/base/driver.rb', line 456

def current_context
  @bridge.current_context
end

#device_time(format = nil) ⇒ String

Get the time on the device

Examples:


@driver.device_time #=> "2018-06-12T11:13:31+02:00"
@driver.device_time "YYYY-MM-DD" #=> "2018-06-12"


803
804
805
# File 'lib/appium_lib_core/common/base/driver.rb', line 803

def device_time(format = nil)
  @bridge.device_time(format)
end

#execute_driver(script: '', type: 'webdriverio', timeout_ms: nil) ⇒ Appium::Core::Base::Device::ExecuteDriver::Result

Run a set of script against the current session, allowing execution of many commands in one Appium request. Supports WebdriverIO API so far. Please read command API for more details about acceptable scripts and the output.

Examples:

script = "const status = await driver.status();\nconsole.warn('warning message');\nreturn [status];\n"
r = @@driver.execute_driver(script: script, type: 'webdriverio', timeout: 10_000)
r        #=> An instance of Appium::Core::Base::Device::ExecuteDriver::Result
r.result #=> The 'result' key part as the result of the script
r.logs   #=> The 'logs' key part as '{'log' => [], 'warn' => [], 'error' => []}'

Raises:

  • (::Selenium::WebDriver::Error::UnknownError)

    If something error happens in the script. It has the original message.

Since:

  • Appium 1.14.0



1013
1014
1015
# File 'lib/appium_lib_core/common/base/driver.rb', line 1013

def execute_driver(script: '', type: 'webdriverio', timeout_ms: nil)
  @bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
end

#find_element_by_image(img_path) ⇒ ::Appium::Core::Element

Return an element if current view has a partial image. The logic depends on template matching by OpenCV. image-comparison

You can handle settings for the comparision following below. device-settings

Examples:


@@driver.update_settings({ fixImageFindScreenshotDims: false, fixImageTemplateSize: true,
                           autoUpdateImageElementPosition: true })
e = @@driver.find_element_by_image './test/functional/data/test_element_image.png'

Since:

  • Appium 1.8.2



955
956
957
958
# File 'lib/appium_lib_core/common/base/driver.rb', line 955

def find_element_by_image(img_path)
  template = Base64.strict_encode64 File.read img_path
  find_element :image, template
end

#find_elements_by_image(img_path) ⇒ Array<::Appium::Core::Element>

Return elements if current view has a partial image. The logic depends on template matching by OpenCV. image-comparison

You can handle settings for the comparision following below. device-settings

Examples:


@@driver.update_settings({ fixImageFindScreenshotDims: false, fixImageTemplateSize: true,
                           autoUpdateImageElementPosition: true })
e = @@driver.find_elements_by_image ['./test/functional/data/test_element_image.png']
e == [] # if the 'e' is empty

Since:

  • Appium 1.8.2



978
979
980
981
# File 'lib/appium_lib_core/common/base/driver.rb', line 978

def find_elements_by_image(img_path)
  template = Base64.strict_encode64 File.read img_path
  find_elements :image, template
end

#find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil, multiple: nil, match_neighbour_threshold: nil) ⇒ Object



920
921
922
923
924
925
926
927
928
# File 'lib/appium_lib_core/common/base/driver.rb', line 920

def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
                          multiple: nil, match_neighbour_threshold: nil)
  @bridge.find_image_occurrence(full_image: full_image,
                                partial_image: partial_image,
                                visualize: visualize,
                                threshold: threshold,
                                multiple: multiple,
                                match_neighbour_threshold: match_neighbour_threshold)
end

#get_images_similarity(first_image:, second_image:, visualize: false) ⇒ Object



930
931
932
# File 'lib/appium_lib_core/common/base/driver.rb', line 930

def get_images_similarity(first_image:, second_image:, visualize: false)
  @bridge.get_images_similarity(first_image: first_image, second_image: second_image, visualize: visualize)
end

#get_settingsObject

Get appium Settings for current test session. Alias of @driver.settings.get

Examples:


@driver.get_settings
@driver.settings.get


333
334
335
# File 'lib/appium_lib_core/common/base/driver.rb', line 333

def get_settings
  settings.get
end

#get_timeoutsHash

For W3C. Get the timeout related settings on the server side.

Examples:

@driver.get_timeouts


901
902
903
# File 'lib/appium_lib_core/common/base/driver.rb', line 901

def get_timeouts
  @bridge.get_timeouts
end

#hide_keyboard(close_key = nil) ⇒ Object

Hide the onscreen keyboard

Examples:


@driver.hide_keyboard # Close a keyboard with the 'Done' button
@driver.hide_keyboard('Finished') # Close a keyboard with the 'Finished' button


298
299
300
# File 'lib/appium_lib_core/common/base/driver.rb', line 298

def hide_keyboard(close_key = nil)
  @bridge.hide_keyboard close_key
end

#imeAppium::Core::Base::Driver::DeviceIME

Deprecated.

Use ‘mobile: shell’ extension instead.

Returns an instance of DeviceIME

Examples:


@driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'
@driver.ime.available_engines #=> Get the list of IME installed in the target device
@driver.ime.active_engine #=> Get the current active IME such as 'com.android.inputmethod.latin/.LatinIME'
@driver.ime.activated #=> True if IME is activated
@driver.ime.deactivate #=> Deactivate current IME engine


366
367
368
369
# File 'lib/appium_lib_core/common/base/driver.rb', line 366

def ime
  ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: shell' extension instead"
  @ime ||= DeviceIME.new(@bridge)
end

#ime_activate(ime_name) ⇒ Object

Deprecated.

Use ‘mobile: shell’ extension instead.

Android only. Make an engine that is available active.

Examples:


@driver.ime_activate engine: 'com.android.inputmethod.latin/.LatinIME'
@driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'


381
382
383
# File 'lib/appium_lib_core/common/base/driver.rb', line 381

def ime_activate(ime_name)
  ime.activate(ime_name)
end

#ime_activatedBoolean

Deprecated.

Use ‘mobile: shell’ extension instead.

Examples:


@driver.ime_activated #=> True if IME is activated
@driver.ime.activated #=> True if IME is activated


420
421
422
# File 'lib/appium_lib_core/common/base/driver.rb', line 420

def ime_activated
  ime.activated?
end

#ime_active_engineObject

Deprecated.

Use ‘mobile: shell’ extension instead.

Android only. Get the name of the active IME engine.

Examples:


@driver.ime_active_engine #=> Get the current active IME such as 'com.android.inputmethod.latin/.LatinIME'
@driver.ime.active_engine #=> Get the current active IME such as 'com.android.inputmethod.latin/.LatinIME'


405
406
407
# File 'lib/appium_lib_core/common/base/driver.rb', line 405

def ime_active_engine
  ime.active_engine
end

#ime_available_enginesObject

Deprecated.

Use ‘mobile: shell’ extension instead.

Android only. List all available input engines on the machine.

Examples:


@driver.ime_available_engines #=> Get the list of IME installed in the target device
@driver.ime.available_engines #=> Get the list of IME installed in the target device


393
394
395
# File 'lib/appium_lib_core/common/base/driver.rb', line 393

def ime_available_engines
  ime.available_engines
end

#ime_deactivateObject

Deprecated.

Use ‘mobile: shell’ extension instead.

Android only. De-activates the currently-active IME engine.

Examples:


@driver.ime_deactivate #=> Deactivate current IME engine
@driver.ime.deactivate #=> Deactivate current IME engine


432
433
434
# File 'lib/appium_lib_core/common/base/driver.rb', line 432

def ime_deactivate
  ime.deactivate
end

#install_app(path, **options) ⇒ Object

Install the given app onto the device. Each options can be snake-case or camel-case. Snake-cases will be converted to camel-case as options value.

Other parameters such as github.com/appium/appium-xcuitest-driver#mobile-installapp also can be set. Then, arguments in snake case will be camel case as its request parameters.

Examples:


@driver.install_app("/path/to/test.apk")
@driver.install_app("/path/to/test.apk", replace: true, timeout: 20000, allow_test_packages: true,
                    use_sdcard: false, grant_permissions: false)
@driver.install_app("/path/to/test.ipa", timeoutMs: 20000)


655
656
657
658
659
# File 'lib/appium_lib_core/common/base/driver.rb', line 655

def install_app(path, **options)
  # TODO: use mobile command in the background?
  options = options.transform_keys { |key| key.to_s.gsub(/_./) { |v| v[1]&.upcase } } unless options.nil?
  @bridge.install_app(path, options)
end

#key_action(async: false) ⇒ Object

Perform ‘key’ actions for W3C module. Generate key pointer action here and users can use this via driver.key_action

The pointer type is ‘key’ by default in the Appium Ruby client. driver.action in Appium Ruby client has ‘pointer’ action by default. This method is a shortcut to set ‘key’ type. Hense this method is equal to driver.action(devices: [::Selenium::WebDriver::Interactions.key(‘keyboard’)]) as below example.

Examples:


element = @driver.find_element(:id, "some id")
@driver.key_action.send_key('hiあ').perform # The 'send_key' is a part of 'KeyActions'
# is equal to:
# @driver.action(devices: [::Selenium::WebDriver::Interactions.key('keyboard')]).send_keys('hiあ').perform


245
246
247
248
249
250
251
252
# File 'lib/appium_lib_core/common/base/driver.rb', line 245

def key_action(async: false)
  @bridge.action(
    async: async,
    # steep:ignore:start
    devices: [::Selenium::WebDriver::Interactions.key('keyboard')]
    # steep:ignore:end
  )
end

#keyboard_shown?Boolean Also known as: is_keyboard_shown

Get whether keyboard is displayed or not.

Examples:

@driver.is_keyboard_shown # false
@driver.keyboard_shown?   # true


309
310
311
# File 'lib/appium_lib_core/common/base/driver.rb', line 309

def keyboard_shown?
  @bridge.is_keyboard_shown
end

#lock(duration = nil) ⇒ String

Lock the device

Examples:


@driver.lock    #=> Lock the device
@driver.lock(5) #=> Lock the device in 5 sec and unlock the device after 5 sec.
                #   Block other commands during locking the device.


263
264
265
# File 'lib/appium_lib_core/common/base/driver.rb', line 263

def lock(duration = nil)
  @bridge.lock(duration)
end

#locked?Boolean Also known as: device_locked?

Check current device status is weather locked or not

Examples:


@driver.device_locked?
@driver.locked?


274
275
276
# File 'lib/appium_lib_core/common/base/driver.rb', line 274

def locked?
  @bridge.device_locked?
end

#logsAppium::Core::Logs

Get the device window’s logs.

Examples:


@driver.logs.available_types # [:syslog, :crashlog, :performance]
@driver.logs.get :syslog # []


889
890
891
# File 'lib/appium_lib_core/common/base/driver.rb', line 889

def logs
  @logs ||= Logs.new(@bridge)
end

#long_press_keycode(key, metastate: [], flags: []) ⇒ Object

Examples:


@driver.long_press_keycode 66
@driver.long_press_keycode 66, flags: [0x20, 0x2000]
@driver.long_press_keycode 66, metastate: [1], flags: [32, 8192]


599
600
601
# File 'lib/appium_lib_core/common/base/driver.rb', line 599

def long_press_keycode(key, metastate: [], flags: [])
  @bridge.long_press_keycode(key, metastate: metastate, flags: flags)
end

#match_images_features(first_image:, second_image:, detector_name: 'ORB', match_func: 'BruteForce', good_matches_factor: nil, visualize: false) ⇒ Object

Image Comparison



906
907
908
909
910
911
912
913
914
915
916
917
918
# File 'lib/appium_lib_core/common/base/driver.rb', line 906

def match_images_features(first_image:,
                          second_image:,
                          detector_name: 'ORB',
                          match_func: 'BruteForce',
                          good_matches_factor: nil,
                          visualize: false)
  @bridge.match_images_features(first_image: first_image,
                                second_image: second_image,
                                detector_name: detector_name,
                                match_func: match_func,
                                good_matches_factor: good_matches_factor,
                                visualize: visualize)
end

#perform_actions(data) ⇒ Object

Send multiple W3C action chains to server. Use @driver.action for single action chain.

@example: Zoom

f1 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger1')
f1.create_pointer_move(duration: 1, x: 200, y: 500,
                       origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
f1.create_pointer_down(:left)
f1.create_pointer_move(duration: 1, x: 200, y: 200,
                       origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
f1.create_pointer_up(:left)

f2 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger2')
f2.create_pointer_move(duration: 1, x: 200, y: 500,
                       origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
f2.create_pointer_down(:left)
f2.create_pointer_move(duration: 1, x: 200, y: 800,
                       origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
f2.create_pointer_up(:left)

@driver.perform_actions [f1, f2] #=> 'nil' if the action succeed


833
834
835
836
837
838
839
840
841
842
843
# File 'lib/appium_lib_core/common/base/driver.rb', line 833

def perform_actions(data)
  raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array

  # NOTE: 'add_input' in Selenium Ruby implementation has additional 'pause'.
  # This implementation is to avoid the additional pause.
  # https://github.com/SeleniumHQ/selenium/blob/64447d4b03f6986337d1ca8d8b6476653570bcc1/rb/lib/selenium/webdriver/common/action_builder.rb#L207

  @bridge.send_actions data.map(&:encode).compact
  data.each(&:clear_actions)
  nil
end

#press_keycode(key, metastate: [], flags: []) ⇒ Object

Examples:


@driver.press_keycode 66
@driver.press_keycode 66, flags: [0x02]
@driver.press_keycode 66, metastate: [1], flags: [32]


577
578
579
# File 'lib/appium_lib_core/common/base/driver.rb', line 577

def press_keycode(key, metastate: [], flags: [])
  @bridge.press_keycode(key, metastate: metastate, flags: flags)
end

#pull_file(path) ⇒ Base64-decoded

Pull a file from the remote device. On Android the application under test should be built with debuggable flag enabled in order to get access to its container on the internal file system.

Examples:


decoded_file = @driver.pull_file '/local/data/some/path'     #=> Get the file at that path
decoded_file = @driver.pull_file 'Shenanigans.app/some/file'
               #=> Get 'some/file' from the install location of Shenanigans.app
decoded_file = @driver.pull_file '@com.appium.example/Documents/file.txt'
               #=> Get 'file.txt' in @com.appium.example/Documents
File.open('proper_filename', 'wb') { |f| f<< decoded_file }


528
529
530
531
# File 'lib/appium_lib_core/common/base/driver.rb', line 528

def pull_file(path)
  # TODO: use 'mobile: pullFile' internally
  @bridge.pull_file(path)
end

#pull_folder(path) ⇒ Base64-decoded

Pull a folder content from the remote device. On Android the application under test should be built with debuggable flag enabled in order to get access to its container on the internal file system.

Examples:


decoded_file = @driver.pull_folder '/data/local/tmp' #=> Get the folder at that path
decoded_file = @driver.pull_file '@com.appium.example/Documents' #=> Get 'Documents' in @com.appium.example
File.open('proper_filename', 'wb') { |f| f<< decoded_file }


554
555
556
557
# File 'lib/appium_lib_core/common/base/driver.rb', line 554

def pull_folder(path)
  # TODO: use 'mobile: pullFolder' internally
  @bridge.pull_folder(path)
end

#push_file(path, filedata) ⇒ Object

Place a file in a specific location on the device. On Android, the application under test should be built with debuggable flag enabled in order to get access to its container on the internal file system.

Examples:


@driver.push_file "/file/to/path", "data"

file = File.read "your/path/to/test_image.png"
@driver.push_file "/sdcard/Pictures", file # Push a file binary to /sdcard/Pictures path in Android


499
500
501
502
# File 'lib/appium_lib_core/common/base/driver.rb', line 499

def push_file(path, filedata)
  # TODO: use 'mobile: pushFile' internally
  @bridge.push_file(path, filedata)
end

#remove_app(app_id, keep_data: nil, timeout: nil) ⇒ Object

Examples:


@driver.remove_app("io.appium.bundle")
@driver.remove_app("io.appium.bundle", keep_data: false, timeout, 10000)


676
677
678
679
# File 'lib/appium_lib_core/common/base/driver.rb', line 676

def remove_app(app_id, keep_data: nil, timeout: nil)
  # TODO: use mobile command in the background?
  @bridge.remove_app(app_id, keep_data: keep_data, timeout: timeout)
end

#settingsObject

Returns an instance of DriverSettings to call get/update.

Examples:


@driver.settings.get
@driver.settings.update('allowInvisibleElements': true)


321
322
323
# File 'lib/appium_lib_core/common/base/driver.rb', line 321

def settings
  @settings ||= DriverSettings.new(@bridge)
end

#settings=(value) ⇒ Object Also known as: update_settings

Update Appium Settings for current test session Alias of @driver.settings#update

Examples:


@driver.update_settings({ 'allowInvisibleElements': true })
@driver.settings.update({ 'allowInvisibleElements': true })
@driver.settings = { 'allowInvisibleElements': true }


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

def settings=(value)
  settings.update(value)
end

#shakeObject

Cause the device to shake

Examples:


@driver.shake


787
788
789
# File 'lib/appium_lib_core/common/base/driver.rb', line 787

def shake
  @bridge.shake
end

#stop_and_save_recording_screen(file_path) ⇒ Object

Examples:


# iOS
@driver.start_recording_screen video_type: 'libx264'
@driver.stop_and_save_recording_screen 'example.mp4' # Video type 'libx264' can be play as '.mp4' video

# Android
@driver.start_recording_screen
@driver.stop_and_save_recording_screen 'example.mp4'


777
778
779
# File 'lib/appium_lib_core/common/base/driver.rb', line 777

def stop_and_save_recording_screen(file_path)
  @bridge.stop_and_save_recording_screen(file_path)
end

#stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT') ⇒ Object

Examples:


@driver.stop_recording_screen
@driver.stop_recording_screen remote_path: 'https://example.com', user: 'example', pass: 'pass', method: 'POST'


761
762
763
# File 'lib/appium_lib_core/common/base/driver.rb', line 761

def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT')
  @bridge.stop_recording_screen(remote_path: remote_path, user: user, pass: pass, method: method)
end

#terminate_app(app_id, timeout: nil) ⇒ Boolean

Terminate the specified app.

Examples:


@driver.terminate_app("io.appium.bundle") # true
@driver.terminate_app("io.appium.bundle", timeout: 500)


717
718
719
720
# File 'lib/appium_lib_core/common/base/driver.rb', line 717

def terminate_app(app_id, timeout: nil)
  # TODO: use mobile command in the background?
  @bridge.terminate_app(app_id, timeout: timeout)
end

#unlockObject

Unlock the device

Examples:


@driver.unlock


285
286
287
# File 'lib/appium_lib_core/common/base/driver.rb', line 285

def unlock
  @bridge.unlock
end

#update_sending_request_to(protocol:, host:, port:, path:) ⇒ Object

Update server_url and HTTP clients following this arguments, protocol, host, port and path. After this method, @bridge.http will be a new instance following them instead of server_url which is set before creating session. If @bridge.http did not have update_sending_request_to method, this method returns immediately.

Examples:


driver = core.start_driver server_url: 'http://example1.com:8000/wd/hub # @bridge.http is for 'http://example1.com:8000/wd/hub/'
driver.update_sending_request_to protocol: 'https', host: 'example2.com', port: 9000, path: '/wd/hub'
driver.manage.timeouts.implicit_wait = 10 # @bridge.http is for 'https://example2.com:9000/wd/hub/'


117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/appium_lib_core/common/base/driver.rb', line 117

def update_sending_request_to(protocol:, host:, port:, path:)
  unless @bridge.http&.class&.method_defined? :update_sending_request_to
    ::Appium::Logger.warn "#{@bridge.http&.class} has no 'update_sending_request_to'. " \
                          'It keeps current connection target.'
    return
  end

  @bridge.http&.update_sending_request_to(scheme: protocol,
                                          host: host,
                                          port: port,
                                          path: path)
end

#window_rectSelenium::WebDriver::Rectangle

Get the device window’s rect.

Examples:

size = @driver.window_rect
size.width #=> Integer
size.height #=> Integer
size.x #=> 0
size.y #=> 0


867
868
869
# File 'lib/appium_lib_core/common/base/driver.rb', line 867

def window_rect
  manage.window.rect
end

#window_sizeSelenium::WebDriver::Dimension

Get the device window’s size.

Examples:

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


853
854
855
# File 'lib/appium_lib_core/common/base/driver.rb', line 853

def window_size
  manage.window.size
end

#within_context(context, &block) ⇒ Object

Perform a block within the given context, then switch back to the starting context.

Examples:


result = @driver.within_context('NATIVE_APP') do
  @driver.find_element :tag, "button"
end # The result of 'find_element :tag, "button"'


446
447
448
# File 'lib/appium_lib_core/common/base/driver.rb', line 446

def within_context(context, &block)
  block_given? ? @bridge.within_context(context, &block) : @bridge.within_context(context)
end