appium_lib_core 4.1.0 → 9.3.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +357 -270
- data/README.md +68 -16
- data/Rakefile +8 -20
- data/Steepfile +11 -0
- data/appium_lib_core.gemspec +13 -15
- data/bin/console +0 -4
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +4 -1
- data/lib/appium_lib_core/android/device/clipboard.rb +4 -2
- data/lib/appium_lib_core/android/device/emulator.rb +11 -5
- data/lib/appium_lib_core/android/device/network.rb +10 -0
- data/lib/appium_lib_core/android/device/performance.rb +3 -0
- data/lib/appium_lib_core/android/device/screen.rb +5 -1
- data/lib/appium_lib_core/android/device.rb +83 -20
- data/lib/appium_lib_core/common/base/bridge.rb +238 -95
- data/lib/appium_lib_core/common/base/capabilities.rb +21 -8
- data/lib/appium_lib_core/common/{command/mjsonwp.rb → base/device_ime.rb} +33 -12
- data/lib/appium_lib_core/common/base/driver.rb +260 -334
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +80 -0
- data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
- data/lib/appium_lib_core/common/base/http_default.rb +22 -38
- data/lib/appium_lib_core/{ios/uiautomation/bridge.rb → common/base/remote_status.rb} +9 -8
- data/lib/appium_lib_core/common/base/rotable.rb +62 -0
- data/lib/appium_lib_core/common/base/screenshot.rb +10 -10
- data/lib/appium_lib_core/common/base/search_context.rb +98 -172
- data/lib/appium_lib_core/common/base.rb +1 -5
- data/lib/appium_lib_core/common/command.rb +244 -4
- data/lib/appium_lib_core/common/device/app_management.rb +2 -26
- data/lib/appium_lib_core/common/device/context.rb +1 -5
- data/lib/appium_lib_core/common/device/image_comparison.rb +27 -10
- data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
- data/lib/appium_lib_core/common/device/{touch_actions.rb → orientation.rb} +6 -10
- data/lib/appium_lib_core/common/device/screen_record.rb +8 -2
- data/lib/appium_lib_core/common/error.rb +5 -5
- data/lib/appium_lib_core/common/log.rb +5 -4
- data/lib/appium_lib_core/common/wait.rb +38 -6
- data/lib/appium_lib_core/device.rb +3 -9
- data/lib/appium_lib_core/driver.rb +193 -182
- data/lib/appium_lib_core/{patch.rb → element.rb} +64 -26
- data/lib/appium_lib_core/ios/device/clipboard.rb +4 -2
- data/lib/appium_lib_core/ios/xcuitest/device.rb +2 -0
- data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
- data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
- data/lib/appium_lib_core/mac2/device.rb +92 -0
- data/lib/appium_lib_core/{ios.rb → mac2.rb} +2 -5
- data/lib/appium_lib_core/support/event_firing_bridge.rb +57 -0
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core.rb +23 -10
- data/rbs_collection.lock.yaml +252 -0
- data/rbs_collection.yaml +15 -0
- data/sig/gems/selenium/abstract_event_listener.rbs +8 -0
- data/sig/gems/selenium/capabilities.rbs +8 -0
- data/sig/gems/selenium/common.rbs +10 -0
- data/sig/gems/selenium/default.rbs +10 -0
- data/sig/gems/selenium/driver.rbs +7 -0
- data/sig/gems/selenium/has_session_id.rbs +8 -0
- data/sig/gems/selenium/has_web_storage.rbs +8 -0
- data/sig/gems/selenium/uploads_files.rbs +8 -0
- data/sig/lib/appium_lib_core/common/base/capabilities.rbs +9 -0
- data/sig/lib/appium_lib_core/common/base/driver.rbs +167 -0
- data/sig/lib/appium_lib_core/common/base/driver_settings.rbs +15 -0
- data/sig/lib/appium_lib_core/common/base/has_location.rbs +13 -0
- data/sig/lib/appium_lib_core/common/base/has_network_connection.rbs +19 -0
- data/sig/lib/appium_lib_core/common/base/http_default.rbs +38 -0
- data/sig/lib/appium_lib_core/common/base/platform.rbs +7 -0
- data/sig/lib/appium_lib_core/common/base/remote_status.rbs +9 -0
- data/sig/lib/appium_lib_core/common/base/rotable.rbs +17 -0
- data/sig/lib/appium_lib_core/common/base/screenshot.rbs +19 -0
- data/sig/lib/appium_lib_core/common/device/battery_status.rbs +13 -0
- data/sig/lib/appium_lib_core/common/wait.rbs +31 -0
- data/sig/lib/appium_lib_core/device.rbs +21 -0
- data/sig/lib/appium_lib_core/driver.rbs +196 -0
- data/sig/lib/appium_lib_core/ios/xcuitest/device/battery.rbs +15 -0
- data/sig/lib/appium_lib_core/version.rbs +7 -0
- data/sig/lib/appium_lib_core.rbs +8 -0
- metadata +88 -111
- data/.github/ISSUE_TEMPLATE/issue-report.md +0 -29
- data/.github/contributing.md +0 -26
- data/.github/issue_template.md +0 -20
- data/.github/workflows/unittest.yml +0 -68
- data/.gitignore +0 -18
- data/.rubocop.yml +0 -58
- data/azure-pipelines.yml +0 -15
- data/ci-jobs/functional/android_setup.yml +0 -3
- data/ci-jobs/functional/ios_setup.yml +0 -7
- data/ci-jobs/functional/publish_test_result.yml +0 -18
- data/ci-jobs/functional/run_appium.yml +0 -25
- data/ci-jobs/functional/start-emulator.sh +0 -26
- data/ci-jobs/functional_test.yml +0 -298
- data/docs/mobile_command.md +0 -34
- data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
- data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
- data/lib/appium_lib_core/common/command/common.rb +0 -110
- data/lib/appium_lib_core/common/command/w3c.rb +0 -56
- data/lib/appium_lib_core/common/device/value.rb +0 -52
- data/lib/appium_lib_core/common/touch_action/multi_touch.rb +0 -56
- data/lib/appium_lib_core/common/touch_action/touch_actions.rb +0 -203
- data/lib/appium_lib_core/ios/uiautomation/device.rb +0 -44
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +0 -34
- data/release_notes.md +0 -816
- 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::
|
|
30
|
-
include ::Appium::Core::Base::
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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,122 @@ 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
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
@bridge.add_command method: method, url: url, name: name, &block
|
|
73
197
|
end
|
|
74
198
|
|
|
75
199
|
### Methods for Appium
|
|
76
200
|
|
|
201
|
+
# Perform 'key' actions for W3C module.
|
|
202
|
+
# Generate +key+ pointer action here and users can use this via +driver.key_action+
|
|
203
|
+
# - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/ActionBuilder.html
|
|
204
|
+
# - https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/KeyActions.html
|
|
205
|
+
#
|
|
206
|
+
# The pointer type is 'key' by default in the Appium Ruby client.
|
|
207
|
+
# +driver.action+ in Appium Ruby client has 'pointer' action by default.
|
|
208
|
+
# This method is a shortcut to set 'key' type.
|
|
209
|
+
# Hense this method is equal to +driver.action(devices: [::Selenium::WebDriver::Interactions.key('keyboard')])+
|
|
210
|
+
# as below example.
|
|
211
|
+
#
|
|
212
|
+
# @example
|
|
213
|
+
#
|
|
214
|
+
# element = @driver.find_element(:id, "some id")
|
|
215
|
+
# @driver.key_action.send_key('hiあ').perform # The 'send_key' is a part of 'KeyActions'
|
|
216
|
+
# # is equal to:
|
|
217
|
+
# # @driver.action(devices: [::Selenium::WebDriver::Interactions.key('keyboard')]).send_keys('hiあ').perform
|
|
218
|
+
#
|
|
219
|
+
def key_action(async: false)
|
|
220
|
+
@bridge.action(
|
|
221
|
+
async: async,
|
|
222
|
+
devices: [::Selenium::WebDriver::Interactions.key('keyboard')]
|
|
223
|
+
)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# @deprecated Use 'mobile: lock' extension instead.
|
|
77
227
|
# Lock the device
|
|
78
228
|
# @return [String]
|
|
79
229
|
#
|
|
@@ -84,9 +234,11 @@ module Appium
|
|
|
84
234
|
# # Block other commands during locking the device.
|
|
85
235
|
#
|
|
86
236
|
def lock(duration = nil)
|
|
237
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: lock' extension instead"
|
|
87
238
|
@bridge.lock(duration)
|
|
88
239
|
end
|
|
89
240
|
|
|
241
|
+
# @deprecated Use 'mobile: isLocked' extension instead.
|
|
90
242
|
# Check current device status is weather locked or not
|
|
91
243
|
#
|
|
92
244
|
# @example
|
|
@@ -95,10 +247,12 @@ module Appium
|
|
|
95
247
|
# @driver.locked?
|
|
96
248
|
#
|
|
97
249
|
def locked?
|
|
250
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: isLocked' extension instead"
|
|
98
251
|
@bridge.device_locked?
|
|
99
252
|
end
|
|
100
253
|
alias device_locked? locked?
|
|
101
254
|
|
|
255
|
+
# @deprecated Use 'mobile: unlock' extension instead.
|
|
102
256
|
# Unlock the device
|
|
103
257
|
#
|
|
104
258
|
# @example
|
|
@@ -106,9 +260,11 @@ module Appium
|
|
|
106
260
|
# @driver.unlock
|
|
107
261
|
#
|
|
108
262
|
def unlock
|
|
263
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: unlock' extension instead"
|
|
109
264
|
@bridge.unlock
|
|
110
265
|
end
|
|
111
266
|
|
|
267
|
+
# @deprecated Use 'mobile: hideKeyboard' extension instead.
|
|
112
268
|
# Hide the onscreen keyboard
|
|
113
269
|
# @param [String] close_key The name of the key which closes the keyboard.
|
|
114
270
|
# Defaults to 'Done' for iOS(except for XCUITest).
|
|
@@ -123,9 +279,11 @@ module Appium
|
|
|
123
279
|
# @driver.hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
|
|
124
280
|
#
|
|
125
281
|
def hide_keyboard(close_key = nil, strategy = nil)
|
|
282
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: hideKeyboard' extension instead"
|
|
126
283
|
@bridge.hide_keyboard close_key, strategy
|
|
127
284
|
end
|
|
128
285
|
|
|
286
|
+
# @deprecated Use 'mobile: isKeyboardShown' extension instead.
|
|
129
287
|
# Get whether keyboard is displayed or not.
|
|
130
288
|
# @return [Boolean] Return true if keyboard is shown. Return false if keyboard is hidden.
|
|
131
289
|
#
|
|
@@ -134,42 +292,11 @@ module Appium
|
|
|
134
292
|
# @driver.keyboard_shown? # true
|
|
135
293
|
#
|
|
136
294
|
def keyboard_shown?
|
|
295
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: isKeyboardShown' extension instead"
|
|
137
296
|
@bridge.is_keyboard_shown
|
|
138
297
|
end
|
|
139
298
|
alias is_keyboard_shown keyboard_shown?
|
|
140
299
|
|
|
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
300
|
# Returns an instance of DriverSettings to call get/update.
|
|
174
301
|
#
|
|
175
302
|
# @example
|
|
@@ -178,7 +305,7 @@ module Appium
|
|
|
178
305
|
# @driver.settings.update('allowInvisibleElements': true)
|
|
179
306
|
#
|
|
180
307
|
def settings
|
|
181
|
-
@
|
|
308
|
+
@settings ||= DriverSettings.new(@bridge)
|
|
182
309
|
end
|
|
183
310
|
|
|
184
311
|
# Get appium Settings for current test session.
|
|
@@ -200,8 +327,8 @@ module Appium
|
|
|
200
327
|
#
|
|
201
328
|
# @example
|
|
202
329
|
#
|
|
203
|
-
# @driver.update_settings('allowInvisibleElements': true)
|
|
204
|
-
# @driver.settings.update('allowInvisibleElements': true)
|
|
330
|
+
# @driver.update_settings({ 'allowInvisibleElements': true })
|
|
331
|
+
# @driver.settings.update({ 'allowInvisibleElements': true })
|
|
205
332
|
# @driver.settings = { 'allowInvisibleElements': true }
|
|
206
333
|
#
|
|
207
334
|
def settings=(value)
|
|
@@ -209,36 +336,11 @@ module Appium
|
|
|
209
336
|
end
|
|
210
337
|
alias update_settings settings=
|
|
211
338
|
|
|
212
|
-
|
|
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
|
-
|
|
339
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
240
340
|
# Returns an instance of DeviceIME
|
|
241
341
|
#
|
|
342
|
+
# @return [Appium::Core::Base::Driver::DeviceIME]
|
|
343
|
+
#
|
|
242
344
|
# @example
|
|
243
345
|
#
|
|
244
346
|
# @driver.ime.activate engine: 'com.android.inputmethod.latin/.LatinIME'
|
|
@@ -248,9 +350,11 @@ module Appium
|
|
|
248
350
|
# @driver.ime.deactivate #=> Deactivate current IME engine
|
|
249
351
|
#
|
|
250
352
|
def ime
|
|
251
|
-
|
|
353
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: shell' extension instead"
|
|
354
|
+
@ime ||= DeviceIME.new(@bridge)
|
|
252
355
|
end
|
|
253
356
|
|
|
357
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
254
358
|
# Android only. Make an engine that is available active.
|
|
255
359
|
#
|
|
256
360
|
# @param [String] ime_name The IME owning the activity [required]
|
|
@@ -264,6 +368,7 @@ module Appium
|
|
|
264
368
|
ime.activate(ime_name)
|
|
265
369
|
end
|
|
266
370
|
|
|
371
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
267
372
|
# Android only. List all available input engines on the machine.
|
|
268
373
|
#
|
|
269
374
|
# @example
|
|
@@ -275,6 +380,7 @@ module Appium
|
|
|
275
380
|
ime.available_engines
|
|
276
381
|
end
|
|
277
382
|
|
|
383
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
278
384
|
# Android only. Get the name of the active IME engine.
|
|
279
385
|
#
|
|
280
386
|
# @example
|
|
@@ -286,9 +392,12 @@ module Appium
|
|
|
286
392
|
ime.active_engine
|
|
287
393
|
end
|
|
288
394
|
|
|
395
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
289
396
|
# @!method ime_activated
|
|
290
397
|
# Android only. Indicates whether IME input is active at the moment (not if it is available).
|
|
291
398
|
#
|
|
399
|
+
# @return [Boolean]
|
|
400
|
+
#
|
|
292
401
|
# @example
|
|
293
402
|
#
|
|
294
403
|
# @driver.ime_activated #=> True if IME is activated
|
|
@@ -298,6 +407,7 @@ module Appium
|
|
|
298
407
|
ime.activated?
|
|
299
408
|
end
|
|
300
409
|
|
|
410
|
+
# @deprecated Use 'mobile: shell' extension instead.
|
|
301
411
|
# Android only. De-activates the currently-active IME engine.
|
|
302
412
|
#
|
|
303
413
|
# @example
|
|
@@ -323,16 +433,6 @@ module Appium
|
|
|
323
433
|
block_given? ? @bridge.within_context(context, &block) : @bridge.within_context(context)
|
|
324
434
|
end
|
|
325
435
|
|
|
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
436
|
# @return [String] The context currently being used.
|
|
337
437
|
#
|
|
338
438
|
# @example
|
|
@@ -361,47 +461,15 @@ module Appium
|
|
|
361
461
|
# @driver.set_context "NATIVE_APP"
|
|
362
462
|
# @driver.context = "NATIVE_APP"
|
|
363
463
|
#
|
|
364
|
-
def context=(context =
|
|
464
|
+
def context=(context = nil)
|
|
365
465
|
@bridge.set_context(context)
|
|
366
466
|
end
|
|
367
467
|
alias set_context context=
|
|
368
468
|
|
|
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
469
|
# 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
470
|
# On Android, the application under test should be built with debuggable flag enabled in order to get access to
|
|
397
471
|
# its container on the internal file system.
|
|
398
472
|
#
|
|
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
473
|
# @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
|
|
406
474
|
# If the path starts with application id prefix, then the file will be pushed to the root of
|
|
407
475
|
# the corresponding application container.
|
|
@@ -415,21 +483,14 @@ module Appium
|
|
|
415
483
|
# @driver.push_file "/sdcard/Pictures", file # Push a file binary to /sdcard/Pictures path in Android
|
|
416
484
|
#
|
|
417
485
|
def push_file(path, filedata)
|
|
486
|
+
# TODO: use 'mobile: pushFile' internally
|
|
418
487
|
@bridge.push_file(path, filedata)
|
|
419
488
|
end
|
|
420
489
|
|
|
421
|
-
# Pull a file from the
|
|
422
|
-
# On iOS the server should have ifuse
|
|
423
|
-
# libraries installed and configured properly for this feature to work on real devices.
|
|
490
|
+
# Pull a file from the remote device.
|
|
424
491
|
# On Android the application under test should be built with debuggable flag enabled in order to get access
|
|
425
492
|
# to its container on the internal file system.
|
|
426
493
|
#
|
|
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
494
|
# @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
|
|
434
495
|
# If the path starts with application id prefix, then the file will be pulled from the root
|
|
435
496
|
# of the corresponding application container.
|
|
@@ -438,7 +499,6 @@ module Appium
|
|
|
438
499
|
# Only pulling files from application containers is supported for iOS Simulator.
|
|
439
500
|
# Provide the remote path in format
|
|
440
501
|
# <code>@bundle.identifier:container_type/relative_path_in_container</code>
|
|
441
|
-
# (Make sure this in ifuse doc)
|
|
442
502
|
#
|
|
443
503
|
# @return [Base64-decoded] Base64 decoded data
|
|
444
504
|
#
|
|
@@ -452,21 +512,14 @@ module Appium
|
|
|
452
512
|
# File.open('proper_filename', 'wb') { |f| f<< decoded_file }
|
|
453
513
|
#
|
|
454
514
|
def pull_file(path)
|
|
515
|
+
# TODO: use 'mobile: pullFile' internally
|
|
455
516
|
@bridge.pull_file(path)
|
|
456
517
|
end
|
|
457
518
|
|
|
458
|
-
# Pull a folder content from the
|
|
459
|
-
# On iOS the server should have ifuse libraries installed and configured properly for this feature to work
|
|
460
|
-
# on real devices.
|
|
519
|
+
# Pull a folder content from the remote device.
|
|
461
520
|
# On Android the application under test should be built with debuggable flag enabled in order to get access to
|
|
462
521
|
# its container on the internal file system.
|
|
463
522
|
#
|
|
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
523
|
# @param [String] path Absolute path to the folder.
|
|
471
524
|
# If the path starts with <em>@applicationId/</em> prefix, then the folder will be pulled
|
|
472
525
|
# from the root of the corresponding application container.
|
|
@@ -475,7 +528,6 @@ module Appium
|
|
|
475
528
|
# Only pulling files from application containers is supported for iOS Simulator.
|
|
476
529
|
# Provide the remote path in format
|
|
477
530
|
# <code>@bundle.identifier:container_type/relative_path_in_container</code>
|
|
478
|
-
# (Make sure this in ifuse doc)
|
|
479
531
|
#
|
|
480
532
|
# @return [Base64-decoded] Base64 decoded data which is zip archived
|
|
481
533
|
#
|
|
@@ -486,22 +538,11 @@ module Appium
|
|
|
486
538
|
# File.open('proper_filename', 'wb') { |f| f<< decoded_file }
|
|
487
539
|
#
|
|
488
540
|
def pull_folder(path)
|
|
541
|
+
# TODO: use 'mobile: pullFolder' internally
|
|
489
542
|
@bridge.pull_folder(path)
|
|
490
543
|
end
|
|
491
544
|
|
|
492
|
-
#
|
|
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
|
-
|
|
545
|
+
# @deprecated Use 'mobile: pressKey' extension instead.
|
|
505
546
|
# Press keycode on the device.
|
|
506
547
|
# http://developer.android.com/reference/android/view/KeyEvent.html
|
|
507
548
|
# @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 +562,11 @@ module Appium
|
|
|
521
562
|
# @driver.press_keycode 66, metastate: [1], flags: [32]
|
|
522
563
|
#
|
|
523
564
|
def press_keycode(key, metastate: [], flags: [])
|
|
565
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: pressKey' extension instead"
|
|
524
566
|
@bridge.press_keycode(key, metastate: metastate, flags: flags)
|
|
525
567
|
end
|
|
526
568
|
|
|
569
|
+
# @deprecated Use 'mobile: pressKey' extension instead.
|
|
527
570
|
# Long press keycode on the device.
|
|
528
571
|
# http://developer.android.com/reference/android/view/KeyEvent.html
|
|
529
572
|
# @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 +586,11 @@ module Appium
|
|
|
543
586
|
# @driver.long_press_keycode 66, metastate: [1], flags: [32, 8192]
|
|
544
587
|
#
|
|
545
588
|
def long_press_keycode(key, metastate: [], flags: [])
|
|
589
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: pressKey' extension instead"
|
|
546
590
|
@bridge.long_press_keycode(key, metastate: metastate, flags: flags)
|
|
547
591
|
end
|
|
548
592
|
|
|
549
|
-
#
|
|
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
|
-
|
|
593
|
+
# @deprecated Use 'mobile: getAppStrings' extension instead.
|
|
579
594
|
# Return the hash of all localization strings.
|
|
580
595
|
# @return [Hash]
|
|
581
596
|
#
|
|
@@ -584,9 +599,11 @@ module Appium
|
|
|
584
599
|
# @driver.app_strings #=> "TransitionsTitle"=>"Transitions", "WebTitle"=>"Web"
|
|
585
600
|
#
|
|
586
601
|
def app_strings(language = nil)
|
|
602
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: getAppStrings' extension instead"
|
|
587
603
|
@bridge.app_strings(language)
|
|
588
604
|
end
|
|
589
605
|
|
|
606
|
+
# @deprecated Use 'mobile: backgroundApp' extension instead.
|
|
590
607
|
# Backgrounds the app for a set number of seconds.
|
|
591
608
|
# This is a blocking application
|
|
592
609
|
# @param [Integer] duration How many seconds to background the app for.
|
|
@@ -602,7 +619,9 @@ module Appium
|
|
|
602
619
|
@bridge.background_app(duration)
|
|
603
620
|
end
|
|
604
621
|
|
|
605
|
-
# Install the given app onto the device
|
|
622
|
+
# Install the given app onto the device.
|
|
623
|
+
# Each options can be snake-case or camel-case. Snake-cases will be converted to camel-case
|
|
624
|
+
# as options value.
|
|
606
625
|
#
|
|
607
626
|
# @param [String] path The absolute local path or remote http URL to an .ipa or .apk file,
|
|
608
627
|
# or a .zip containing one of these.
|
|
@@ -616,26 +635,27 @@ module Appium
|
|
|
616
635
|
# @param [Boolean] grant_permissions Only for Android. whether to automatically grant application permissions
|
|
617
636
|
# on Android 6+ after the installation completes. +false+ by default
|
|
618
637
|
#
|
|
638
|
+
# Other parameters such as https://github.com/appium/appium-xcuitest-driver#mobile-installapp also can be set.
|
|
639
|
+
# Then, arguments in snake case will be camel case as its request parameters.
|
|
640
|
+
#
|
|
619
641
|
# @example
|
|
620
642
|
#
|
|
621
643
|
# @driver.install_app("/path/to/test.apk")
|
|
622
644
|
# @driver.install_app("/path/to/test.apk", replace: true, timeout: 20000, allow_test_packages: true,
|
|
623
645
|
# use_sdcard: false, grant_permissions: false)
|
|
646
|
+
# @driver.install_app("/path/to/test.ipa", timeoutMs: 20000)
|
|
624
647
|
#
|
|
625
|
-
def install_app(path,
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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)
|
|
648
|
+
def install_app(path, **options)
|
|
649
|
+
# TODO: use mobile command in the background?
|
|
650
|
+
options = options.transform_keys { |key| key.to_s.gsub(/_./) { |v| v[1].upcase } } unless options.nil?
|
|
651
|
+
@bridge.install_app(path, options)
|
|
637
652
|
end
|
|
638
653
|
|
|
654
|
+
# def capitalize(s)
|
|
655
|
+
# chars =
|
|
656
|
+
# chars[1:].map(&:capitalize).join
|
|
657
|
+
# end
|
|
658
|
+
|
|
639
659
|
# @param [Strong] app_id BundleId for iOS or package name for Android
|
|
640
660
|
# @param [Boolean] keep_data Only for Android. Whether to keep application data and caches after it is uninstalled.
|
|
641
661
|
# +false+ by default
|
|
@@ -647,6 +667,7 @@ module Appium
|
|
|
647
667
|
# @driver.remove_app("io.appium.bundle", keep_data: false, timeout, 10000)
|
|
648
668
|
#
|
|
649
669
|
def remove_app(app_id, keep_data: nil, timeout: nil)
|
|
670
|
+
# TODO: use mobile command in the background?
|
|
650
671
|
@bridge.remove_app(app_id, keep_data: keep_data, timeout: timeout)
|
|
651
672
|
end
|
|
652
673
|
|
|
@@ -658,6 +679,7 @@ module Appium
|
|
|
658
679
|
# @driver.app_installed?("io.appium.bundle")
|
|
659
680
|
#
|
|
660
681
|
def app_installed?(app_id)
|
|
682
|
+
# TODO: use mobile command in the background?
|
|
661
683
|
@bridge.app_installed?(app_id)
|
|
662
684
|
end
|
|
663
685
|
|
|
@@ -669,6 +691,7 @@ module Appium
|
|
|
669
691
|
# @driver.activate_app("io.appium.bundle") #=> {}
|
|
670
692
|
#
|
|
671
693
|
def activate_app(app_id)
|
|
694
|
+
# TODO: use mobile command in the background?
|
|
672
695
|
@bridge.activate_app(app_id)
|
|
673
696
|
end
|
|
674
697
|
|
|
@@ -685,6 +708,7 @@ module Appium
|
|
|
685
708
|
# @driver.terminate_app("io.appium.bundle", timeout: 500)
|
|
686
709
|
#
|
|
687
710
|
def terminate_app(app_id, timeout: nil)
|
|
711
|
+
# TODO: use mobile command in the background?
|
|
688
712
|
@bridge.terminate_app(app_id, timeout: timeout)
|
|
689
713
|
end
|
|
690
714
|
|
|
@@ -708,6 +732,7 @@ module Appium
|
|
|
708
732
|
# @driver.query_app_state("io.appium.bundle") #=> :not_running
|
|
709
733
|
#
|
|
710
734
|
def app_state(app_id)
|
|
735
|
+
# TODO: use mobile command in the background?
|
|
711
736
|
@bridge.app_state(app_id)
|
|
712
737
|
end
|
|
713
738
|
alias query_app_state app_state
|
|
@@ -747,6 +772,7 @@ module Appium
|
|
|
747
772
|
@bridge.stop_and_save_recording_screen(file_path)
|
|
748
773
|
end
|
|
749
774
|
|
|
775
|
+
# @deprecated Use 'mobile: shake' extension instead.
|
|
750
776
|
# Cause the device to shake
|
|
751
777
|
#
|
|
752
778
|
# @example
|
|
@@ -754,9 +780,11 @@ module Appium
|
|
|
754
780
|
# @driver.shake
|
|
755
781
|
#
|
|
756
782
|
def shake
|
|
783
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: shake' extension instead"
|
|
757
784
|
@bridge.shake
|
|
758
785
|
end
|
|
759
786
|
|
|
787
|
+
# @deprecated Use 'mobile: getDeviceTime' extension instead.
|
|
760
788
|
# Get the time on the device
|
|
761
789
|
#
|
|
762
790
|
# @param [String] format The set of format specifiers. Read https://momentjs.com/docs/ to get
|
|
@@ -770,18 +798,10 @@ module Appium
|
|
|
770
798
|
# @driver.device_time "YYYY-MM-DD" #=> "2018-06-12"
|
|
771
799
|
#
|
|
772
800
|
def device_time(format = nil)
|
|
801
|
+
::Appium::Logger.warn "[DEPRECATION] Please use 'mobile: getDeviceTime' extension instead"
|
|
773
802
|
@bridge.device_time(format)
|
|
774
803
|
end
|
|
775
804
|
|
|
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
805
|
#
|
|
786
806
|
# Send multiple W3C action chains to server. Use +@driver.action+ for single action chain.
|
|
787
807
|
#
|
|
@@ -790,7 +810,7 @@ module Appium
|
|
|
790
810
|
#
|
|
791
811
|
# @example: Zoom
|
|
792
812
|
#
|
|
793
|
-
# f1 =
|
|
813
|
+
# f1 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger1')
|
|
794
814
|
# f1.create_pointer_move(duration: 1, x: 200, y: 500,
|
|
795
815
|
# origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
|
796
816
|
# f1.create_pointer_down(:left)
|
|
@@ -798,7 +818,7 @@ module Appium
|
|
|
798
818
|
# origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
|
799
819
|
# f1.create_pointer_up(:left)
|
|
800
820
|
#
|
|
801
|
-
# f2 =
|
|
821
|
+
# f2 = ::Selenium::WebDriver::Interactions.pointer(:touch, name: 'finger2')
|
|
802
822
|
# f2.create_pointer_move(duration: 1, x: 200, y: 500,
|
|
803
823
|
# origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
|
804
824
|
# f2.create_pointer_down(:left)
|
|
@@ -809,7 +829,11 @@ module Appium
|
|
|
809
829
|
# @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
|
|
810
830
|
#
|
|
811
831
|
def perform_actions(data)
|
|
812
|
-
raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
|
832
|
+
raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
|
833
|
+
|
|
834
|
+
# NOTE: 'add_input' in Selenium Ruby implementation has additional 'pause'.
|
|
835
|
+
# This implementation is to avoid the additional pause.
|
|
836
|
+
# https://github.com/SeleniumHQ/selenium/blob/64447d4b03f6986337d1ca8d8b6476653570bcc1/rb/lib/selenium/webdriver/common/action_builder.rb#L207
|
|
813
837
|
|
|
814
838
|
@bridge.send_actions data.map(&:encode).compact
|
|
815
839
|
data.each(&:clear_actions)
|
|
@@ -853,7 +877,7 @@ module Appium
|
|
|
853
877
|
end
|
|
854
878
|
|
|
855
879
|
# Get the device window's logs.
|
|
856
|
-
# @return [
|
|
880
|
+
# @return [Appium::Core::Logs]
|
|
857
881
|
#
|
|
858
882
|
# @example
|
|
859
883
|
#
|
|
@@ -876,107 +900,6 @@ module Appium
|
|
|
876
900
|
@bridge.get_timeouts
|
|
877
901
|
end
|
|
878
902
|
|
|
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
903
|
# Image Comparison
|
|
981
904
|
def match_images_features(first_image:,
|
|
982
905
|
second_image:,
|
|
@@ -992,11 +915,14 @@ module Appium
|
|
|
992
915
|
visualize: visualize)
|
|
993
916
|
end
|
|
994
917
|
|
|
995
|
-
def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil
|
|
918
|
+
def find_image_occurrence(full_image:, partial_image:, visualize: false, threshold: nil,
|
|
919
|
+
multiple: nil, match_neighbour_threshold: nil)
|
|
996
920
|
@bridge.find_image_occurrence(full_image: full_image,
|
|
997
921
|
partial_image: partial_image,
|
|
998
922
|
visualize: visualize,
|
|
999
|
-
threshold: threshold
|
|
923
|
+
threshold: threshold,
|
|
924
|
+
multiple: multiple,
|
|
925
|
+
match_neighbour_threshold: match_neighbour_threshold)
|
|
1000
926
|
end
|
|
1001
927
|
|
|
1002
928
|
def get_images_similarity(first_image:, second_image:, visualize: false)
|
|
@@ -1009,14 +935,14 @@ module Appium
|
|
|
1009
935
|
|
|
1010
936
|
# @since Appium 1.8.2
|
|
1011
937
|
# 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/
|
|
938
|
+
# {https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/image-comparison.md image-comparison}
|
|
1013
939
|
#
|
|
1014
940
|
# You can handle settings for the comparision following below.
|
|
1015
941
|
# {https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/device-settings.js#L6 device-settings}
|
|
1016
942
|
#
|
|
1017
943
|
# @param [String] img_path A path to a partial image you'd like to find
|
|
1018
944
|
#
|
|
1019
|
-
# @return [::
|
|
945
|
+
# @return [::Appium::Core::Element]
|
|
1020
946
|
#
|
|
1021
947
|
# @example
|
|
1022
948
|
#
|
|
@@ -1031,14 +957,14 @@ module Appium
|
|
|
1031
957
|
|
|
1032
958
|
# @since Appium 1.8.2
|
|
1033
959
|
# Return elements if current view has a partial image. The logic depends on template matching by OpenCV.
|
|
1034
|
-
# {https://github.com/appium/appium/blob/
|
|
960
|
+
# {https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/image-comparison.md image-comparison}
|
|
1035
961
|
#
|
|
1036
962
|
# You can handle settings for the comparision following below.
|
|
1037
963
|
# {https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/device-settings.js#L6 device-settings}
|
|
1038
964
|
#
|
|
1039
965
|
# @param [String] img_path A path to a partial image you'd like to find
|
|
1040
966
|
#
|
|
1041
|
-
# @return [::
|
|
967
|
+
# @return [Array<::Appium::Core::Element>]
|
|
1042
968
|
#
|
|
1043
969
|
# @example
|
|
1044
970
|
#
|
|
@@ -1086,18 +1012,18 @@ module Appium
|
|
|
1086
1012
|
@bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
|
|
1087
1013
|
end
|
|
1088
1014
|
|
|
1089
|
-
# Convert vanilla element response to ::
|
|
1015
|
+
# Convert vanilla element response to ::Appium::Core::Element
|
|
1090
1016
|
#
|
|
1091
1017
|
# @param [Hash] id The id which can get as a response from server
|
|
1092
|
-
# @return [::
|
|
1018
|
+
# @return [::Appium::Core::Element]
|
|
1093
1019
|
#
|
|
1094
1020
|
# @example
|
|
1095
1021
|
# response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
|
|
1096
|
-
# ele = @driver.convert_to_element(response) #=> ::
|
|
1022
|
+
# ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
|
|
1097
1023
|
# ele.rect #=> Can get the rect of the element
|
|
1098
1024
|
#
|
|
1099
|
-
def convert_to_element(
|
|
1100
|
-
@bridge.convert_to_element
|
|
1025
|
+
def convert_to_element(response_id)
|
|
1026
|
+
@bridge.convert_to_element response_id
|
|
1101
1027
|
end
|
|
1102
1028
|
end # class Driver
|
|
1103
1029
|
end # class Base
|