appium_lib_core 4.1.0 → 9.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +342 -270
  3. data/README.md +65 -15
  4. data/Rakefile +5 -22
  5. data/appium_lib_core.gemspec +12 -15
  6. data/bin/console +0 -4
  7. data/lib/appium_lib_core/android/device/auth_finger_print.rb +4 -1
  8. data/lib/appium_lib_core/android/device/network.rb +10 -0
  9. data/lib/appium_lib_core/android/device/performance.rb +3 -0
  10. data/lib/appium_lib_core/android/device/screen.rb +2 -0
  11. data/lib/appium_lib_core/android/device.rb +80 -17
  12. data/lib/appium_lib_core/common/base/bridge.rb +238 -95
  13. data/lib/appium_lib_core/common/base/capabilities.rb +21 -8
  14. data/lib/appium_lib_core/common/{command/mjsonwp.rb → base/device_ime.rb} +33 -12
  15. data/lib/appium_lib_core/common/base/driver.rb +263 -334
  16. data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
  17. data/lib/appium_lib_core/common/base/has_location.rb +80 -0
  18. data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
  19. data/lib/appium_lib_core/common/base/http_default.rb +22 -38
  20. data/lib/appium_lib_core/{ios/uiautomation/bridge.rb → common/base/remote_status.rb} +9 -8
  21. data/lib/appium_lib_core/common/base/rotable.rb +62 -0
  22. data/lib/appium_lib_core/common/base/screenshot.rb +8 -8
  23. data/lib/appium_lib_core/common/base/search_context.rb +98 -172
  24. data/lib/appium_lib_core/common/base.rb +1 -5
  25. data/lib/appium_lib_core/common/command.rb +244 -4
  26. data/lib/appium_lib_core/common/device/app_management.rb +2 -26
  27. data/lib/appium_lib_core/common/device/context.rb +1 -5
  28. data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
  29. data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
  30. data/lib/appium_lib_core/common/device/{touch_actions.rb → orientation.rb} +6 -10
  31. data/lib/appium_lib_core/common/error.rb +4 -5
  32. data/lib/appium_lib_core/common/log.rb +5 -4
  33. data/lib/appium_lib_core/common/wait.rb +38 -6
  34. data/lib/appium_lib_core/device.rb +3 -9
  35. data/lib/appium_lib_core/driver.rb +194 -161
  36. data/lib/appium_lib_core/{patch.rb → element.rb} +64 -26
  37. data/lib/appium_lib_core/ios/xcuitest/device.rb +2 -0
  38. data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
  39. data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
  40. data/lib/appium_lib_core/mac2/device.rb +92 -0
  41. data/lib/appium_lib_core/{ios.rb → mac2.rb} +2 -5
  42. data/lib/appium_lib_core/support/event_firing_bridge.rb +57 -0
  43. data/lib/appium_lib_core/version.rb +2 -2
  44. data/lib/appium_lib_core.rb +23 -10
  45. metadata +53 -118
  46. data/.github/ISSUE_TEMPLATE/issue-report.md +0 -29
  47. data/.github/contributing.md +0 -26
  48. data/.github/issue_template.md +0 -20
  49. data/.github/workflows/unittest.yml +0 -68
  50. data/.gitignore +0 -18
  51. data/.rubocop.yml +0 -58
  52. data/azure-pipelines.yml +0 -15
  53. data/ci-jobs/functional/android_setup.yml +0 -3
  54. data/ci-jobs/functional/ios_setup.yml +0 -7
  55. data/ci-jobs/functional/publish_test_result.yml +0 -18
  56. data/ci-jobs/functional/run_appium.yml +0 -25
  57. data/ci-jobs/functional/start-emulator.sh +0 -26
  58. data/ci-jobs/functional_test.yml +0 -298
  59. data/docs/mobile_command.md +0 -34
  60. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
  61. data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
  62. data/lib/appium_lib_core/common/command/common.rb +0 -110
  63. data/lib/appium_lib_core/common/command/w3c.rb +0 -56
  64. data/lib/appium_lib_core/common/device/value.rb +0 -52
  65. data/lib/appium_lib_core/common/touch_action/multi_touch.rb +0 -56
  66. data/lib/appium_lib_core/common/touch_action/touch_actions.rb +0 -203
  67. data/lib/appium_lib_core/ios/uiautomation/device.rb +0 -44
  68. data/lib/appium_lib_core/ios/uiautomation/patch.rb +0 -34
  69. data/release_notes.md +0 -816
  70. data/script/commands.rb +0 -200
@@ -13,8 +13,15 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'base64'
16
+ require_relative 'device_ime'
17
+ require_relative 'driver_settings'
16
18
  require_relative 'search_context'
17
19
  require_relative 'screenshot'
20
+ require_relative 'rotable'
21
+ require_relative 'remote_status'
22
+ require_relative 'has_location'
23
+ require_relative 'has_network_connection'
24
+ require_relative '../wait'
18
25
 
19
26
  module Appium
20
27
  module Core
@@ -22,42 +29,77 @@ module Appium
22
29
  class Driver < ::Selenium::WebDriver::Driver
23
30
  include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
24
31
  include ::Selenium::WebDriver::DriverExtensions::HasSessionId
25
- include ::Selenium::WebDriver::DriverExtensions::Rotatable
26
- include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
27
32
  include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
28
33
 
29
- include ::Appium::Core::Base::SearchContext
30
- include ::Appium::Core::Base::TakeScreenshot
34
+ include ::Appium::Core::Base::Rotatable
35
+ include ::Appium::Core::Base::TakesScreenshot
36
+ include ::Appium::Core::Base::HasRemoteStatus
37
+ include ::Appium::Core::Base::HasLocation
38
+ include ::Appium::Core::Base::HasNetworkConnection
39
+
40
+ include ::Appium::Core::Waitable
41
+
42
+ ::Selenium::WebDriver::SearchContext.extra_finders = APPIUM_EXTRA_FINDERS
31
43
 
32
44
  # Private API.
33
45
  # Do not use this for general use. Used by flutter driver to get bridge for creating a new element
34
46
  attr_reader :bridge
35
47
 
36
- def initialize(opts = {})
37
- listener = opts.delete(:listener)
38
- @bridge = ::Appium::Core::Base::Bridge.handshake(**opts)
39
- if @bridge.dialect == :oss # MJSONWP
40
- extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
41
- extend ::Selenium::WebDriver::DriverExtensions::HasLocation
42
- extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
43
- elsif @bridge.dialect == :w3c
44
- # TODO: Only for Appium. Ideally, we'd like to remove the below like selenium-webdriver
45
- extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
46
- extend ::Selenium::WebDriver::DriverExtensions::HasLocation
47
- extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
48
- end
49
- super(@bridge, listener: listener)
48
+ # override
49
+ def initialize(bridge: nil, listener: nil, **opts) # rubocop:disable Lint/MissingSuper
50
+ original_opts = opts.dup
51
+
52
+ # For ::Appium::Core::Waitable
53
+ @wait_timeout = opts.delete(:wait_timeout)
54
+ @wait_interval = opts.delete(:wait_interval)
55
+
56
+ # Selenium WebDriver attributes
57
+ @devtools = nil
58
+ @bidi = nil
59
+
60
+ # in the selenium webdriver as well
61
+ ::Selenium::WebDriver::Remote::Bridge.element_class = ::Appium::Core::Element
62
+ bridge ||= create_bridge(**opts)
63
+ add_extensions(bridge.browser)
64
+ @bridge = listener ? ::Appium::Support::EventFiringBridge.new(bridge, listener, **original_opts) : bridge
50
65
  end
51
66
 
52
- # Get the dialect value
53
- # @return [:oss|:w3c]
54
- def dialect
55
- @bridge.dialect
67
+ private
68
+
69
+ # Create a proper bridge instance.
70
+ #
71
+ # @return [::Appium::Core::Base::Bridge]
72
+ #
73
+ def create_bridge(**opts)
74
+ # for a new session request
75
+ capabilities = opts.delete(:capabilities)
76
+ bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
77
+
78
+ # for attaching to an existing session
79
+ session_id = opts.delete(:existing_session_id)
80
+ automation_name = opts.delete(:automation_name)
81
+ platform_name = opts.delete(:platform_name)
82
+
83
+ raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
84
+
85
+ bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
86
+
87
+ if session_id.nil?
88
+ bridge.create_session(capabilities)
89
+ else
90
+ # attach to the existing session id
91
+ bridge.attach_to(session_id, platform_name, automation_name)
92
+ end
93
+
94
+ bridge
56
95
  end
57
96
 
97
+ public
98
+
58
99
  # Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path.
59
100
  # After this method, +@bridge.http+ will be a new instance following them instead of +server_url+ which is
60
101
  # set before creating session.
102
+ # If +@bridge.http+ did not have +update_sending_request_to+ method, this method returns immediately.
61
103
  #
62
104
  # @example
63
105
  #
@@ -66,14 +108,125 @@ module Appium
66
108
  # driver.manage.timeouts.implicit_wait = 10 # @bridge.http is for 'https://example2.com:9000/wd/hub/'
67
109
  #
68
110
  def update_sending_request_to(protocol:, host:, port:, path:)
69
- @bridge.http.update_sending_request_to(scheme: protocol,
70
- host: host,
71
- port: port,
72
- path: path)
111
+ unless @bridge.http&.class&.method_defined? :update_sending_request_to
112
+ ::Appium::Logger.warn "#{@bridge.http&.class} has no 'update_sending_request_to'. " \
113
+ 'It keeps current connection target.'
114
+ return
115
+ end
116
+
117
+ @bridge.http&.update_sending_request_to(scheme: protocol,
118
+ host: host,
119
+ port: port,
120
+ path: path)
121
+ end
122
+
123
+ AVAILABLE_METHODS = [
124
+ :get, :head, :post, :put, :delete,
125
+ :connect, :options, :trace, :patch
126
+ ].freeze
127
+ # Define a new custom method to the driver so that you can define your own method for
128
+ # drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
129
+ # to define custom commands that are not part of W3C spec.
130
+ #
131
+ # @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
132
+ # @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
133
+ # +:session_id+ is the placeholder of 'session id'.
134
+ # Other place holders can be specified with +:+ prefix like +:id+.
135
+ # Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
136
+ # @param [Symbol] name The name of method that is called as the driver instance method.
137
+ # @param [Proc] block The block to involve as the method.
138
+ # Please define a method that has the same +name+ with arguments you want.
139
+ # The method must has +execute+ method. tHe +execute+ is calls the +url+
140
+ # with the given parameters.
141
+ # The first argument should be +name+ as symbol.
142
+ # The second argument should be hash. If keys in the hash matches +:+ prefix
143
+ # string in the given url, the matched string in the given url will be
144
+ # values in the hash.
145
+ # The third argument should be hash. The hash will be the request body.
146
+ # Please read examples below for more details.
147
+ # @raise [ArgumentError] If the given +method+ is invalid value.
148
+ #
149
+ # @example
150
+ #
151
+ # @driver.add_command(
152
+ # method: :get,
153
+ # url: 'session/:session_id/path/to/custom/url',
154
+ # name: :test_command
155
+ # )
156
+ # # Send a GET request to 'session/<session id>/path/to/custom/url'
157
+ # @driver.test_command
158
+ #
159
+ #
160
+ # @driver.add_command(
161
+ # method: :post,
162
+ # url: 'session/:session_id/path/to/custom/url',
163
+ # name: :test_command
164
+ # ) do
165
+ # def test_command(argument)
166
+ # execute(:test_command, {}, { dummy: argument })
167
+ # end
168
+ # end
169
+ # # Send a POST request to 'session/<session id>/path/to/custom/url'
170
+ # # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
171
+ # # ':session_id' in the given 'url' is replaced with current 'session id'.
172
+ # @driver.test_command(1)
173
+ #
174
+ #
175
+ # @driver.add_command(
176
+ # method: :post,
177
+ # url: 'session/:session_id/element/:id/custom/action',
178
+ # name: :test_action_command
179
+ # ) do
180
+ # def test_action_command(element_id, action)
181
+ # execute(:test_action_command, {id: element_id}, { dummy_action: action })
182
+ # end
183
+ # end
184
+ # # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
185
+ # # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
186
+ # # ':session_id' in the given url is replaced with current 'session id'.
187
+ # # ':id' in the given url is replaced with the given 'element_id'.
188
+ # e = @driver.find_element :accessibility_id, 'an element'
189
+ # @driver.test_action_command(e.id, 'action')
190
+ #
191
+ def add_command(method:, url:, name:, &block)
192
+ unless AVAILABLE_METHODS.include? method
193
+ raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}"
194
+ end
195
+
196
+ # TODO: Remove this logger before Appium 2.0 release
197
+ ::Appium::Logger.info '[Experimental] this method is experimental for Appium 2.0. This interface may change.'
198
+
199
+ @bridge.add_command method: method, url: url, name: name, &block
73
200
  end
74
201
 
75
202
  ### Methods for Appium
76
203
 
204
+ # Perform 'key' actions for W3C module.
205
+ # Generate +key+ pointer action here and users can use this via +driver.key_action+
206
+ # - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/ActionBuilder.html
207
+ # - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/KeyActions.html
208
+ #
209
+ # The pointer type is 'key' by default in the Appium Ruby client.
210
+ # +driver.action+ in Appium Ruby client has 'pointer' action by default.
211
+ # This method is a shortcut to set 'key' type.
212
+ # Hense this method is equal to +driver.action(devices: [::Selenium::WebDriver::Interactions.key('keyboard')])+
213
+ # as below example.
214
+ #
215
+ # @example
216
+ #
217
+ # element = @driver.find_element(:id, "some id")
218
+ # @driver.key_action.send_key('hiあ').perform # The 'send_key' is a part of 'KeyActions'
219
+ # # is equal to:
220
+ # # @driver.action(devices: [::Selenium::WebDriver::Interactions.key('keyboard')]).send_keys('hiあ').perform
221
+ #
222
+ def key_action(async: false)
223
+ @bridge.action(
224
+ async: async,
225
+ devices: [::Selenium::WebDriver::Interactions.key('keyboard')]
226
+ )
227
+ end
228
+
229
+ # @deprecated Use 'mobile: lock' extension instead.
77
230
  # Lock the device
78
231
  # @return [String]
79
232
  #
@@ -84,9 +237,11 @@ module Appium
84
237
  # # Block other commands during locking the device.
85
238
  #
86
239
  def lock(duration = nil)
240
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: lock' extension instead"
87
241
  @bridge.lock(duration)
88
242
  end
89
243
 
244
+ # @deprecated Use 'mobile: isLocked' extension instead.
90
245
  # Check current device status is weather locked or not
91
246
  #
92
247
  # @example
@@ -95,10 +250,12 @@ module Appium
95
250
  # @driver.locked?
96
251
  #
97
252
  def locked?
253
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: isLocked' extension instead"
98
254
  @bridge.device_locked?
99
255
  end
100
256
  alias device_locked? locked?
101
257
 
258
+ # @deprecated Use 'mobile: unlock' extension instead.
102
259
  # Unlock the device
103
260
  #
104
261
  # @example
@@ -106,9 +263,11 @@ module Appium
106
263
  # @driver.unlock
107
264
  #
108
265
  def unlock
266
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: unlock' extension instead"
109
267
  @bridge.unlock
110
268
  end
111
269
 
270
+ # @deprecated Use 'mobile: hideKeyboard' extension instead.
112
271
  # Hide the onscreen keyboard
113
272
  # @param [String] close_key The name of the key which closes the keyboard.
114
273
  # Defaults to 'Done' for iOS(except for XCUITest).
@@ -123,9 +282,11 @@ module Appium
123
282
  # @driver.hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
124
283
  #
125
284
  def hide_keyboard(close_key = nil, strategy = nil)
285
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: hideKeyboard' extension instead"
126
286
  @bridge.hide_keyboard close_key, strategy
127
287
  end
128
288
 
289
+ # @deprecated Use 'mobile: isKeyboardShown' extension instead.
129
290
  # Get whether keyboard is displayed or not.
130
291
  # @return [Boolean] Return true if keyboard is shown. Return false if keyboard is hidden.
131
292
  #
@@ -134,42 +295,11 @@ module Appium
134
295
  # @driver.keyboard_shown? # true
135
296
  #
136
297
  def keyboard_shown?
298
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: isKeyboardShown' extension instead"
137
299
  @bridge.is_keyboard_shown
138
300
  end
139
301
  alias is_keyboard_shown keyboard_shown?
140
302
 
141
- # [DEPRECATION]
142
- # Send keys for a current active element
143
- # @param [String] key Input text
144
- #
145
- # @example
146
- #
147
- # @driver.send_keys 'happy testing!'
148
- #
149
- def send_keys(*key)
150
- ::Appium::Logger.warn(
151
- '[DEPRECATION] Driver#send_keys is deprecated in W3C spec. Use driver.action.<command>.perform instead'
152
- )
153
- @bridge.send_keys_to_active_element(key)
154
- end
155
- alias type send_keys
156
-
157
- class DriverSettings
158
- # @private this class is private
159
- def initialize(bridge)
160
- @bridge = bridge
161
- end
162
-
163
- def get
164
- @bridge.get_settings
165
- end
166
-
167
- def update(settings)
168
- @bridge.update_settings(settings)
169
- end
170
- end
171
- private_constant :DriverSettings
172
-
173
303
  # Returns an instance of DriverSettings to call get/update.
174
304
  #
175
305
  # @example
@@ -178,7 +308,7 @@ module Appium
178
308
  # @driver.settings.update('allowInvisibleElements': true)
179
309
  #
180
310
  def settings
181
- @driver_settings ||= DriverSettings.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
311
+ @settings ||= DriverSettings.new(@bridge)
182
312
  end
183
313
 
184
314
  # Get appium Settings for current test session.
@@ -200,8 +330,8 @@ module Appium
200
330
  #
201
331
  # @example
202
332
  #
203
- # @driver.update_settings('allowInvisibleElements': true)
204
- # @driver.settings.update('allowInvisibleElements': true)
333
+ # @driver.update_settings({ 'allowInvisibleElements': true })
334
+ # @driver.settings.update({ 'allowInvisibleElements': true })
205
335
  # @driver.settings = { 'allowInvisibleElements': true }
206
336
  #
207
337
  def settings=(value)
@@ -209,36 +339,11 @@ module Appium
209
339
  end
210
340
  alias update_settings settings=
211
341
 
212
- class DeviceIME
213
- # @private this class is private
214
- def initialize(bridge)
215
- @bridge = bridge
216
- end
217
-
218
- def activate(ime_name)
219
- @bridge.ime_activate(ime_name)
220
- end
221
-
222
- def available_engines
223
- @bridge.ime_available_engines
224
- end
225
-
226
- def active_engine
227
- @bridge.ime_active_engine
228
- end
229
-
230
- def activated?
231
- @bridge.ime_activated
232
- end
233
-
234
- def deactivate
235
- @bridge.ime_deactivate
236
- end
237
- end
238
- private_constant :DeviceIME
239
-
342
+ # @deprecated Use 'mobile: shell' extension instead.
240
343
  # Returns an instance of DeviceIME
241
344
  #
345
+ # @return [Appium::Core::Base::Driver::DeviceIME]
346
+ #
242
347
  # @example
243
348
  #
244
349
  # @driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'
@@ -248,9 +353,11 @@ module Appium
248
353
  # @driver.ime.deactivate #=> Deactivate current IME engine
249
354
  #
250
355
  def ime
251
- @device_ime ||= DeviceIME.new(@bridge) # rubocop:disable Naming/MemoizedInstanceVariableName
356
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: shell' extension instead"
357
+ @ime ||= DeviceIME.new(@bridge)
252
358
  end
253
359
 
360
+ # @deprecated Use 'mobile: shell' extension instead.
254
361
  # Android only. Make an engine that is available active.
255
362
  #
256
363
  # @param [String] ime_name The IME owning the activity [required]
@@ -264,6 +371,7 @@ module Appium
264
371
  ime.activate(ime_name)
265
372
  end
266
373
 
374
+ # @deprecated Use 'mobile: shell' extension instead.
267
375
  # Android only. List all available input engines on the machine.
268
376
  #
269
377
  # @example
@@ -275,6 +383,7 @@ module Appium
275
383
  ime.available_engines
276
384
  end
277
385
 
386
+ # @deprecated Use 'mobile: shell' extension instead.
278
387
  # Android only. Get the name of the active IME engine.
279
388
  #
280
389
  # @example
@@ -286,9 +395,12 @@ module Appium
286
395
  ime.active_engine
287
396
  end
288
397
 
398
+ # @deprecated Use 'mobile: shell' extension instead.
289
399
  # @!method ime_activated
290
400
  # Android only. Indicates whether IME input is active at the moment (not if it is available).
291
401
  #
402
+ # @return [Boolean]
403
+ #
292
404
  # @example
293
405
  #
294
406
  # @driver.ime_activated #=> True if IME is activated
@@ -298,6 +410,7 @@ module Appium
298
410
  ime.activated?
299
411
  end
300
412
 
413
+ # @deprecated Use 'mobile: shell' extension instead.
301
414
  # Android only. De-activates the currently-active IME engine.
302
415
  #
303
416
  # @example
@@ -323,16 +436,6 @@ module Appium
323
436
  block_given? ? @bridge.within_context(context, &block) : @bridge.within_context(context)
324
437
  end
325
438
 
326
- # Change to the default context. This is equivalent to +set_context nil+.
327
- #
328
- # @example
329
- #
330
- # @driver.switch_to_default_context
331
- #
332
- def switch_to_default_context
333
- @bridge.switch_to_default_context
334
- end
335
-
336
439
  # @return [String] The context currently being used.
337
440
  #
338
441
  # @example
@@ -361,47 +464,15 @@ module Appium
361
464
  # @driver.set_context "NATIVE_APP"
362
465
  # @driver.context = "NATIVE_APP"
363
466
  #
364
- def context=(context = null)
467
+ def context=(context = nil)
365
468
  @bridge.set_context(context)
366
469
  end
367
470
  alias set_context context=
368
471
 
369
- # Set the value to element directly
370
- #
371
- # @example
372
- #
373
- # @driver.set_immediate_value element, 'hello'
374
- #
375
- def set_immediate_value(element, *value)
376
- ::Appium::Logger.warn '[DEPRECATION] driver#set_immediate_value(element, *value) is deprecated. ' \
377
- 'Use Element#immediate_value(*value) instead'
378
- @bridge.set_immediate_value(element, *value)
379
- end
380
-
381
- # Replace the value to element directly
382
- #
383
- # @example
384
- #
385
- # @driver.replace_value element, 'hello'
386
- #
387
- def replace_value(element, *value)
388
- ::Appium::Logger.warn '[DEPRECATION] driver#replace_value(element, *value) is deprecated. ' \
389
- 'Use Element#replace_value(*value) instead'
390
- @bridge.replace_value(element, *value)
391
- end
392
-
393
472
  # Place a file in a specific location on the device.
394
- # On iOS, the server should have ifuse libraries installed and configured properly for this feature to work on
395
- # real devices.
396
473
  # On Android, the application under test should be built with debuggable flag enabled in order to get access to
397
474
  # its container on the internal file system.
398
475
  #
399
- # {https://github.com/libimobiledevice/ifuse iFuse GitHub page6}
400
- #
401
- # {https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ}
402
- #
403
- # {https://developer.android.com/studio/debug 'Debug Your App' developer article}
404
- #
405
476
  # @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
406
477
  # If the path starts with application id prefix, then the file will be pushed to the root of
407
478
  # the corresponding application container.
@@ -415,21 +486,14 @@ module Appium
415
486
  # @driver.push_file "/sdcard/Pictures", file # Push a file binary to /sdcard/Pictures path in Android
416
487
  #
417
488
  def push_file(path, filedata)
489
+ # TODO: use 'mobile: pushFile' internally
418
490
  @bridge.push_file(path, filedata)
419
491
  end
420
492
 
421
- # Pull a file from the simulator/device.
422
- # On iOS the server should have ifuse
423
- # libraries installed and configured properly for this feature to work on real devices.
493
+ # Pull a file from the remote device.
424
494
  # On Android the application under test should be built with debuggable flag enabled in order to get access
425
495
  # to its container on the internal file system.
426
496
  #
427
- # {https://github.com/libimobiledevice/ifuse iFuse GitHub page6}
428
- #
429
- # {https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ}
430
- #
431
- # {https://developer.android.com/studio/debug 'Debug Your App' developer article}
432
- #
433
497
  # @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
434
498
  # If the path starts with application id prefix, then the file will be pulled from the root
435
499
  # of the corresponding application container.
@@ -438,7 +502,6 @@ module Appium
438
502
  # Only pulling files from application containers is supported for iOS Simulator.
439
503
  # Provide the remote path in format
440
504
  # <code>@bundle.identifier:container_type/relative_path_in_container</code>
441
- # (Make sure this in ifuse doc)
442
505
  #
443
506
  # @return [Base64-decoded] Base64 decoded data
444
507
  #
@@ -452,21 +515,14 @@ module Appium
452
515
  # File.open('proper_filename', 'wb') { |f| f<< decoded_file }
453
516
  #
454
517
  def pull_file(path)
518
+ # TODO: use 'mobile: pullFile' internally
455
519
  @bridge.pull_file(path)
456
520
  end
457
521
 
458
- # Pull a folder content from the simulator/device.
459
- # On iOS the server should have ifuse libraries installed and configured properly for this feature to work
460
- # on real devices.
522
+ # Pull a folder content from the remote device.
461
523
  # On Android the application under test should be built with debuggable flag enabled in order to get access to
462
524
  # its container on the internal file system.
463
525
  #
464
- # {https://github.com/libimobiledevice/ifuse iFuse GitHub page6}
465
- #
466
- # {https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ}
467
- #
468
- # {https://developer.android.com/studio/debug 'Debug Your App' developer article}
469
- #
470
526
  # @param [String] path Absolute path to the folder.
471
527
  # If the path starts with <em>@applicationId/</em> prefix, then the folder will be pulled
472
528
  # from the root of the corresponding application container.
@@ -475,7 +531,6 @@ module Appium
475
531
  # Only pulling files from application containers is supported for iOS Simulator.
476
532
  # Provide the remote path in format
477
533
  # <code>@bundle.identifier:container_type/relative_path_in_container</code>
478
- # (Make sure this in ifuse doc)
479
534
  #
480
535
  # @return [Base64-decoded] Base64 decoded data which is zip archived
481
536
  #
@@ -486,22 +541,11 @@ module Appium
486
541
  # File.open('proper_filename', 'wb') { |f| f<< decoded_file }
487
542
  #
488
543
  def pull_folder(path)
544
+ # TODO: use 'mobile: pullFolder' internally
489
545
  @bridge.pull_folder(path)
490
546
  end
491
547
 
492
- # Send keyevent on the device.(Only for Selendroid)
493
- # http://developer.android.com/reference/android/view/KeyEvent.html
494
- # @param [integer] key The key to press.
495
- # @param [String] metastate The state the metakeys should be in when pressing the key.
496
- #
497
- # @example
498
- #
499
- # @driver.keyevent 82
500
- #
501
- def keyevent(key, metastate = nil)
502
- @bridge.keyevent(key, metastate)
503
- end
504
-
548
+ # @deprecated Use 'mobile: pressKey' extension instead.
505
549
  # Press keycode on the device.
506
550
  # http://developer.android.com/reference/android/view/KeyEvent.html
507
551
  # @param [Integer] key The key to press. The values which have +KEYCODE_+ prefix in http://developer.android.com/reference/android/view/KeyEvent.html
@@ -521,9 +565,11 @@ module Appium
521
565
  # @driver.press_keycode 66, metastate: [1], flags: [32]
522
566
  #
523
567
  def press_keycode(key, metastate: [], flags: [])
568
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: pressKey' extension instead"
524
569
  @bridge.press_keycode(key, metastate: metastate, flags: flags)
525
570
  end
526
571
 
572
+ # @deprecated Use 'mobile: pressKey' extension instead.
527
573
  # Long press keycode on the device.
528
574
  # http://developer.android.com/reference/android/view/KeyEvent.html
529
575
  # @param [Integer] key The key to long press. The values which have +KEYCODE_+ prefix in http://developer.android.com/reference/android/view/KeyEvent.html
@@ -543,39 +589,11 @@ module Appium
543
589
  # @driver.long_press_keycode 66, metastate: [1], flags: [32, 8192]
544
590
  #
545
591
  def long_press_keycode(key, metastate: [], flags: [])
592
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: pressKey' extension instead"
546
593
  @bridge.long_press_keycode(key, metastate: metastate, flags: flags)
547
594
  end
548
595
 
549
- # Start the simulator and application configured with desired capabilities
550
- #
551
- # @example
552
- #
553
- # @driver.launch_app
554
- #
555
- def launch_app
556
- @bridge.launch_app
557
- end
558
-
559
- # Close an app on device
560
- #
561
- # @example
562
- #
563
- # @driver.close_app
564
- #
565
- def close_app
566
- @bridge.close_app
567
- end
568
-
569
- # Reset the device, relaunching the application.
570
- #
571
- # @example
572
- #
573
- # @driver.reset
574
- #
575
- def reset
576
- @bridge.reset
577
- end
578
-
596
+ # @deprecated Use 'mobile: getAppStrings' extension instead.
579
597
  # Return the hash of all localization strings.
580
598
  # @return [Hash]
581
599
  #
@@ -584,9 +602,11 @@ module Appium
584
602
  # @driver.app_strings #=> "TransitionsTitle"=>"Transitions", "WebTitle"=>"Web"
585
603
  #
586
604
  def app_strings(language = nil)
605
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: getAppStrings' extension instead"
587
606
  @bridge.app_strings(language)
588
607
  end
589
608
 
609
+ # @deprecated Use 'mobile: backgroundApp' extension instead.
590
610
  # Backgrounds the app for a set number of seconds.
591
611
  # This is a blocking application
592
612
  # @param [Integer] duration How many seconds to background the app for.
@@ -602,7 +622,9 @@ module Appium
602
622
  @bridge.background_app(duration)
603
623
  end
604
624
 
605
- # Install the given app onto the device
625
+ # Install the given app onto the device.
626
+ # Each options can be snake-case or camel-case. Snake-cases will be converted to camel-case
627
+ # as options value.
606
628
  #
607
629
  # @param [String] path The absolute local path or remote http URL to an .ipa or .apk file,
608
630
  # or a .zip containing one of these.
@@ -616,26 +638,27 @@ module Appium
616
638
  # @param [Boolean] grant_permissions Only for Android. whether to automatically grant application permissions
617
639
  # on Android 6+ after the installation completes. +false+ by default
618
640
  #
641
+ # Other parameters such as https://github.com/appium/appium-xcuitest-driver#mobile-installapp also can be set.
642
+ # Then, arguments in snake case will be camel case as its request parameters.
643
+ #
619
644
  # @example
620
645
  #
621
646
  # @driver.install_app("/path/to/test.apk")
622
647
  # @driver.install_app("/path/to/test.apk", replace: true, timeout: 20000, allow_test_packages: true,
623
648
  # use_sdcard: false, grant_permissions: false)
649
+ # @driver.install_app("/path/to/test.ipa", timeoutMs: 20000)
624
650
  #
625
- def install_app(path,
626
- replace: nil,
627
- timeout: nil,
628
- allow_test_packages: nil,
629
- use_sdcard: nil,
630
- grant_permissions: nil)
631
- @bridge.install_app(path,
632
- replace: replace,
633
- timeout: timeout,
634
- allow_test_packages: allow_test_packages,
635
- use_sdcard: use_sdcard,
636
- grant_permissions: grant_permissions)
651
+ def install_app(path, **options)
652
+ # TODO: use mobile command in the background?
653
+ options = options.transform_keys { |key| key.to_s.gsub(/_./) { |v| v[1].upcase } } unless options.nil?
654
+ @bridge.install_app(path, options)
637
655
  end
638
656
 
657
+ # def capitalize(s)
658
+ # chars =
659
+ # chars[1:].map(&:capitalize).join
660
+ # end
661
+
639
662
  # @param [Strong] app_id BundleId for iOS or package name for Android
640
663
  # @param [Boolean] keep_data Only for Android. Whether to keep application data and caches after it is uninstalled.
641
664
  # +false+ by default
@@ -647,6 +670,7 @@ module Appium
647
670
  # @driver.remove_app("io.appium.bundle", keep_data: false, timeout, 10000)
648
671
  #
649
672
  def remove_app(app_id, keep_data: nil, timeout: nil)
673
+ # TODO: use mobile command in the background?
650
674
  @bridge.remove_app(app_id, keep_data: keep_data, timeout: timeout)
651
675
  end
652
676
 
@@ -658,6 +682,7 @@ module Appium
658
682
  # @driver.app_installed?("io.appium.bundle")
659
683
  #
660
684
  def app_installed?(app_id)
685
+ # TODO: use mobile command in the background?
661
686
  @bridge.app_installed?(app_id)
662
687
  end
663
688
 
@@ -669,6 +694,7 @@ module Appium
669
694
  # @driver.activate_app("io.appium.bundle") #=> {}
670
695
  #
671
696
  def activate_app(app_id)
697
+ # TODO: use mobile command in the background?
672
698
  @bridge.activate_app(app_id)
673
699
  end
674
700
 
@@ -685,6 +711,7 @@ module Appium
685
711
  # @driver.terminate_app("io.appium.bundle", timeout: 500)
686
712
  #
687
713
  def terminate_app(app_id, timeout: nil)
714
+ # TODO: use mobile command in the background?
688
715
  @bridge.terminate_app(app_id, timeout: timeout)
689
716
  end
690
717
 
@@ -708,6 +735,7 @@ module Appium
708
735
  # @driver.query_app_state("io.appium.bundle") #=> :not_running
709
736
  #
710
737
  def app_state(app_id)
738
+ # TODO: use mobile command in the background?
711
739
  @bridge.app_state(app_id)
712
740
  end
713
741
  alias query_app_state app_state
@@ -747,6 +775,7 @@ module Appium
747
775
  @bridge.stop_and_save_recording_screen(file_path)
748
776
  end
749
777
 
778
+ # @deprecated Use 'mobile: shake' extension instead.
750
779
  # Cause the device to shake
751
780
  #
752
781
  # @example
@@ -754,9 +783,11 @@ module Appium
754
783
  # @driver.shake
755
784
  #
756
785
  def shake
786
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: shake' extension instead"
757
787
  @bridge.shake
758
788
  end
759
789
 
790
+ # @deprecated Use 'mobile: getDeviceTime' extension instead.
760
791
  # Get the time on the device
761
792
  #
762
793
  # @param [String] format The set of format specifiers. Read https://momentjs.com/docs/ to get
@@ -770,18 +801,10 @@ module Appium
770
801
  # @driver.device_time "YYYY-MM-DD" #=> "2018-06-12"
771
802
  #
772
803
  def device_time(format = nil)
804
+ ::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: getDeviceTime' extension instead"
773
805
  @bridge.device_time(format)
774
806
  end
775
807
 
776
- # touch actions
777
- def touch_actions(actions)
778
- @bridge.touch_actions(actions)
779
- end
780
-
781
- def multi_touch(actions)
782
- @bridge.multi_touch(actions)
783
- end
784
-
785
808
  #
786
809
  # Send multiple W3C action chains to server. Use +@driver.action+ for single action chain.
787
810
  #
@@ -790,7 +813,7 @@ module Appium
790
813
  #
791
814
  # @example: Zoom
792
815
  #
793
- # f1 = @driver.action.add_pointer_input(:touch, 'finger1')
816
+ # f1 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger1')
794
817
  # f1.create_pointer_move(duration: 1, x: 200, y: 500,
795
818
  # origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
796
819
  # f1.create_pointer_down(:left)
@@ -798,7 +821,7 @@ module Appium
798
821
  # origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
799
822
  # f1.create_pointer_up(:left)
800
823
  #
801
- # f2 = @driver.action.add_pointer_input(:touch, 'finger2')
824
+ # f2 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger2')
802
825
  # f2.create_pointer_move(duration: 1, x: 200, y: 500,
803
826
  # origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
804
827
  # f2.create_pointer_down(:left)
@@ -809,7 +832,11 @@ module Appium
809
832
  # @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
810
833
  #
811
834
  def perform_actions(data)
812
- raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
835
+ raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
836
+
837
+ # NOTE: 'add_input' in Selenium Ruby implementation has additional 'pause'.
838
+ # This implementation is to avoid the additional pause.
839
+ # https://github.com/SeleniumHQ/selenium/blob/64447d4b03f6986337d1ca8d8b6476653570bcc1/rb/lib/selenium/webdriver/common/action_builder.rb#L207
813
840
 
814
841
  @bridge.send_actions data.map(&:encode).compact
815
842
  data.each(&:clear_actions)
@@ -853,7 +880,7 @@ module Appium
853
880
  end
854
881
 
855
882
  # Get the device window's logs.
856
- # @return [String]
883
+ # @return [Appium::Core::Logs]
857
884
  #
858
885
  # @example
859
886
  #
@@ -876,107 +903,6 @@ module Appium
876
903
  @bridge.get_timeouts
877
904
  end
878
905
 
879
- # Retrieve the capabilities of the specified session.
880
- # It's almost same as +@driver.capabilities+ but you can get more details.
881
- #
882
- # @return [Selenium::WebDriver::Remote::Capabilities]
883
- #
884
- # @example
885
- # @driver.session_capabilities
886
- #
887
- # #=> uiautomator2
888
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fa38dae1360
889
- # # @capabilities=
890
- # # {:proxy=>nil,
891
- # # :browser_name=>nil,
892
- # # :browser_version=>nil,
893
- # # :platform_name=>"android",
894
- # # :page_load_strategy=>nil,
895
- # # :remote_session_id=>nil,
896
- # # :accessibility_checks=>nil,
897
- # # :profile=>nil,
898
- # # :rotatable=>nil,
899
- # # :device=>nil,
900
- # # "platform"=>"LINUX",
901
- # # "webStorageEnabled"=>false,
902
- # # "takesScreenshot"=>true,
903
- # # "javascriptEnabled"=>true,
904
- # # "databaseEnabled"=>false,
905
- # # "networkConnectionEnabled"=>true,
906
- # # "locationContextEnabled"=>false,
907
- # # "warnings"=>{},
908
- # # "desired"=>
909
- # # {"platformName"=>"android",
910
- # # "automationName"=>"uiautomator2",
911
- # # "app"=>"/path/to/app/api.apk.zip",
912
- # # "platformVersion"=>"8.1.0",
913
- # # "deviceName"=>"Android Emulator",
914
- # # "appPackage"=>"io.appium.android.apis",
915
- # # "appActivity"=>"io.appium.android.apis.ApiDemos",
916
- # # "someCapability"=>"some_capability",
917
- # # "unicodeKeyboard"=>true,
918
- # # "resetKeyboard"=>true},
919
- # # "automationName"=>"uiautomator2",
920
- # # "app"=>"/path/to/app/api.apk.zip",
921
- # # "platformVersion"=>"8.1.0",
922
- # # "deviceName"=>"emulator-5554",
923
- # # "appPackage"=>"io.appium.android.apis",
924
- # # "appActivity"=>"io.appium.android.apis.ApiDemos",
925
- # # "someCapability"=>"some_capability",
926
- # # "unicodeKeyboard"=>true,
927
- # # "resetKeyboard"=>true,
928
- # # "deviceUDID"=>"emulator-5554",
929
- # # "deviceScreenSize"=>"1080x1920",
930
- # # "deviceScreenDensity"=>420,
931
- # # "deviceModel"=>"Android SDK built for x86",
932
- # # "deviceManufacturer"=>"Google",
933
- # # "pixelRatio"=>2.625,
934
- # # "statBarHeight"=>63,
935
- # # "viewportRect"=>{"left"=>0, "top"=>63, "width"=>1080, "height"=>1731}}>
936
- # #
937
- # #=> XCUITest
938
- # # <Selenium::WebDriver::Remote::W3C::Capabilities:0x007fb15dc01370
939
- # # @capabilities=
940
- # # {:proxy=>nil,
941
- # # :browser_name=>"UICatalog",
942
- # # :browser_version=>nil,
943
- # # :platform_name=>"ios",
944
- # # :page_load_strategy=>nil,
945
- # # :remote_session_id=>nil,
946
- # # :accessibility_checks=>nil,
947
- # # :profile=>nil,
948
- # # :rotatable=>nil,
949
- # # :device=>"iphone",
950
- # # "udid"=>"DED4DBAD-8E5E-4AD6-BDC4-E75CF9AD84D8",
951
- # # "automationName"=>"XCUITest",
952
- # # "app"=>"/path/to/app/UICatalog.app",
953
- # # "platformVersion"=>"11.4",
954
- # # "deviceName"=>"iPhone Simulator",
955
- # # "useNewWDA"=>true,
956
- # # "useJSONSource"=>true,
957
- # # "someCapability"=>"some_capability",
958
- # # "sdkVersion"=>"11.4",
959
- # # "CFBundleIdentifier"=>"com.example.apple-samplecode.UICatalog",
960
- # # "pixelRatio"=>2,
961
- # # "statBarHeight"=>23.4375,
962
- # # "viewportRect"=>{"left"=>0, "top"=>47, "width"=>750, "height"=>1287}}>
963
- #
964
- def session_capabilities
965
- @bridge.session_capabilities
966
- end
967
-
968
- # Returns available sessions on the Appium server
969
- #
970
- # @return [[Hash]]
971
- #
972
- # @example
973
- #
974
- # @driver.sessions #=> [{'id' => 'c363add8-a7ca-4455-b9e3-9ac4d69e95b3', 'capabilities' => { capabilities as Hash }}]
975
- #
976
- def sessions
977
- @bridge.sessions
978
- end
979
-
980
906
  # Image Comparison
981
907
  def match_images_features(first_image:,
982
908
  second_image:,
@@ -992,11 +918,14 @@ module Appium
992
918
  visualize: visualize)
993
919
  end
994
920
 
995
- def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil)
921
+ def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
922
+ multiple: nil, match_neighbour_threshold: nil)
996
923
  @bridge.find_image_occurrence(full_image: full_image,
997
924
  partial_image: partial_image,
998
925
  visualize: visualize,
999
- threshold: threshold)
926
+ threshold: threshold,
927
+ multiple: multiple,
928
+ match_neighbour_threshold: match_neighbour_threshold)
1000
929
  end
1001
930
 
1002
931
  def get_images_similarity(first_image:, second_image:, visualize: false)
@@ -1009,14 +938,14 @@ module Appium
1009
938
 
1010
939
  # @since Appium 1.8.2
1011
940
  # Return an element if current view has a partial image. The logic depends on template matching by OpenCV.
1012
- # {https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/image-comparison.md image-comparison}
941
+ # {https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/image-comparison.md image-comparison}
1013
942
  #
1014
943
  # You can handle settings for the comparision following below.
1015
944
  # {https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/device-settings.js#L6 device-settings}
1016
945
  #
1017
946
  # @param [String] img_path A path to a partial image you'd like to find
1018
947
  #
1019
- # @return [::Selenium::WebDriver::Element]
948
+ # @return [::Appium::Core::Element]
1020
949
  #
1021
950
  # @example
1022
951
  #
@@ -1031,14 +960,14 @@ module Appium
1031
960
 
1032
961
  # @since Appium 1.8.2
1033
962
  # Return elements if current view has a partial image. The logic depends on template matching by OpenCV.
1034
- # {https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/image-comparison.md image-comparison}
963
+ # {https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/image-comparison.md image-comparison}
1035
964
  #
1036
965
  # You can handle settings for the comparision following below.
1037
966
  # {https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/device-settings.js#L6 device-settings}
1038
967
  #
1039
968
  # @param [String] img_path A path to a partial image you'd like to find
1040
969
  #
1041
- # @return [::Selenium::WebDriver::Element]
970
+ # @return [Array<::Appium::Core::Element>]
1042
971
  #
1043
972
  # @example
1044
973
  #
@@ -1086,18 +1015,18 @@ module Appium
1086
1015
  @bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
1087
1016
  end
1088
1017
 
1089
- # Convert vanilla element response to ::Selenium::WebDriver::Element
1018
+ # Convert vanilla element response to ::Appium::Core::Element
1090
1019
  #
1091
1020
  # @param [Hash] id The id which can get as a response from server
1092
- # @return [::Selenium::WebDriver::Element]
1021
+ # @return [::Appium::Core::Element]
1093
1022
  #
1094
1023
  # @example
1095
1024
  # response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
1096
- # ele = @driver.convert_to_element(response) #=> ::Selenium::WebDriver::Element
1025
+ # ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
1097
1026
  # ele.rect #=> Can get the rect of the element
1098
1027
  #
1099
- def convert_to_element(id)
1100
- @bridge.convert_to_element id
1028
+ def convert_to_element(response_id)
1029
+ @bridge.convert_to_element response_id
1101
1030
  end
1102
1031
  end # class Driver
1103
1032
  end # class Base