appium_lib_core 5.0.0.beta1 → 5.0.0.rc1
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 +13 -6
- data/README.md +2 -1
- data/Rakefile +4 -0
- data/appium_lib_core.gemspec +3 -3
- data/ci-jobs/functional_test.yml +1 -1
- data/docs/mobile_command.md +3 -2
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +2 -1
- data/lib/appium_lib_core/common/base/bridge.rb +303 -7
- data/lib/appium_lib_core/common/base/device_ime.rb +49 -0
- data/lib/appium_lib_core/common/base/driver.rb +101 -105
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +11 -4
- data/lib/appium_lib_core/common/base/has_network_connection.rb +1 -1
- data/lib/appium_lib_core/common/base/rotable.rb +1 -1
- data/lib/appium_lib_core/common/base/screenshot.rb +4 -3
- data/lib/appium_lib_core/common/base/search_context.rb +9 -4
- data/lib/appium_lib_core/common/base.rb +0 -2
- data/lib/appium_lib_core/common/command.rb +259 -3
- data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
- data/lib/appium_lib_core/common/device/value.rb +4 -4
- data/lib/appium_lib_core/common/error.rb +4 -1
- data/lib/appium_lib_core/common/log.rb +4 -1
- data/lib/appium_lib_core/common/touch_action/touch_actions.rb +4 -1
- data/lib/appium_lib_core/device.rb +1 -1
- data/lib/appium_lib_core/driver.rb +3 -4
- data/lib/appium_lib_core/{patch.rb → element.rb} +9 -14
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +1 -1
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core.rb +2 -5
- data/release_notes.md +23 -0
- data/script/commands.rb +1 -12
- metadata +15 -17
- data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -348
- data/lib/appium_lib_core/common/base/command.rb +0 -145
- data/lib/appium_lib_core/common/command/common.rb +0 -110
- data/lib/appium_lib_core/common/command/w3c.rb +0 -56
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Appium
|
16
|
+
module Core
|
17
|
+
class Base
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
class DeviceIME
|
22
|
+
# @private this class is private
|
23
|
+
def initialize(bridge)
|
24
|
+
@bridge = bridge
|
25
|
+
end
|
26
|
+
|
27
|
+
def activate(ime_name)
|
28
|
+
@bridge.ime_activate(ime_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def available_engines
|
32
|
+
@bridge.ime_available_engines
|
33
|
+
end
|
34
|
+
|
35
|
+
def active_engine
|
36
|
+
@bridge.ime_active_engine
|
37
|
+
end
|
38
|
+
|
39
|
+
def activated?
|
40
|
+
@bridge.ime_activated
|
41
|
+
end
|
42
|
+
|
43
|
+
def deactivate
|
44
|
+
@bridge.ime_deactivate
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -13,6 +13,8 @@
|
|
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'
|
18
20
|
require_relative 'rotable'
|
@@ -36,23 +38,25 @@ module Appium
|
|
36
38
|
include ::Appium::Core::Base::HasLocation
|
37
39
|
include ::Appium::Core::Base::HasNetworkConnection
|
38
40
|
|
41
|
+
private
|
42
|
+
|
39
43
|
# Private API.
|
40
44
|
# Do not use this for general use. Used by flutter driver to get bridge for creating a new element
|
41
45
|
attr_reader :bridge
|
42
46
|
|
43
|
-
|
44
|
-
|
47
|
+
def initialize(bridge: nil, listener: nil, **opts)
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
45
51
|
# Implements protocol handshake which:
|
46
52
|
#
|
47
53
|
# 1. Creates session with driver.
|
48
54
|
# 2. Sniffs response.
|
49
55
|
# 3. Based on the response, understands which dialect we should use.
|
50
56
|
#
|
51
|
-
# @return [Bridge
|
57
|
+
# @return [::Appium::Core::Base::Bridge]
|
52
58
|
#
|
53
|
-
# TODO: Fixme
|
54
59
|
def create_bridge(**opts)
|
55
|
-
opts[:url] ||= service_url(opts)
|
56
60
|
caps = opts.delete(:capabilities)
|
57
61
|
# NOTE: This is deprecated
|
58
62
|
cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
|
@@ -71,19 +75,15 @@ module Appium
|
|
71
75
|
capabilities = generate_capabilities(cap_array)
|
72
76
|
|
73
77
|
bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
|
74
|
-
raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
78
|
+
raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
75
79
|
|
76
|
-
bridge = ::Appium::Core::Base::Bridge
|
80
|
+
bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
|
77
81
|
|
78
82
|
bridge.create_session(capabilities)
|
79
83
|
bridge
|
80
84
|
end
|
81
85
|
|
82
|
-
|
83
|
-
# @return [:oss|:w3c]
|
84
|
-
def dialect
|
85
|
-
@bridge.dialect
|
86
|
-
end
|
86
|
+
public
|
87
87
|
|
88
88
|
# Update +server_url+ and HTTP clients following this arguments, protocol, host, port and path.
|
89
89
|
# After this method, +@bridge.http+ will be a new instance following them instead of +server_url+ which is
|
@@ -109,6 +109,86 @@ module Appium
|
|
109
109
|
path: path)
|
110
110
|
end
|
111
111
|
|
112
|
+
AVAILABLE_METHODS = [
|
113
|
+
:get, :head, :post, :put, :delete,
|
114
|
+
:connect, :options, :trace, :patch
|
115
|
+
].freeze
|
116
|
+
# Define a new custom method to the driver so that you can define your own method for
|
117
|
+
# drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
|
118
|
+
# to define custom commands that are not part of W3C spec.
|
119
|
+
#
|
120
|
+
# @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
|
121
|
+
# @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
|
122
|
+
# +:session_id+ is the placeholder of 'session id'.
|
123
|
+
# Other place holders can be specified with +:+ prefix like +:id+.
|
124
|
+
# Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
|
125
|
+
# @param [Symbol] name The name of method that is called as the driver instance method.
|
126
|
+
# @param [Proc] block The block to involve as the method.
|
127
|
+
# Please define a method that has the same +name+ with arguments you want.
|
128
|
+
# The method must has +execute+ method. tHe +execute+ is calls the +url+
|
129
|
+
# with the given parameters.
|
130
|
+
# The first argument should be +name+ as symbol.
|
131
|
+
# The second argument should be hash. If keys in the hash matches +:+ prefix
|
132
|
+
# string in the given url, the matched string in the given url will be
|
133
|
+
# values in the hash.
|
134
|
+
# The third argument should be hash. The hash will be the request body.
|
135
|
+
# Please read examples below for more details.
|
136
|
+
# @raise [ArgumentError] If the given +method+ is invalid value.
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
#
|
140
|
+
# @driver.add_command(
|
141
|
+
# method: :get,
|
142
|
+
# url: 'session/:session_id/path/to/custom/url',
|
143
|
+
# name: :test_command
|
144
|
+
# )
|
145
|
+
# # Send a GET request to 'session/<session id>/path/to/custom/url'
|
146
|
+
# @driver.test_command
|
147
|
+
#
|
148
|
+
#
|
149
|
+
# @driver.add_command(
|
150
|
+
# method: :post,
|
151
|
+
# url: 'session/:session_id/path/to/custom/url',
|
152
|
+
# name: :test_command
|
153
|
+
# ) do
|
154
|
+
# def test_command(argument)
|
155
|
+
# execute(:test_command, {}, { dummy: argument })
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
# # Send a POST request to 'session/<session id>/path/to/custom/url'
|
159
|
+
# # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
|
160
|
+
# # ':session_id' in the given 'url' is replaced with current 'session id'.
|
161
|
+
# @driver.test_command(1)
|
162
|
+
#
|
163
|
+
#
|
164
|
+
# @driver.add_command(
|
165
|
+
# method: :post,
|
166
|
+
# url: 'session/:session_id/element/:id/custom/action',
|
167
|
+
# name: :test_action_command
|
168
|
+
# ) do
|
169
|
+
# def test_action_command(element_id, action)
|
170
|
+
# execute(:test_action_command, {id: element_id}, { dummy_action: action })
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
# # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
|
174
|
+
# # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
|
175
|
+
# # ':session_id' in the given url is replaced with current 'session id'.
|
176
|
+
# # ':id' in the given url is replaced with the given 'element_id'.
|
177
|
+
# e = @driver.find_element :accessibility_id, 'an element'
|
178
|
+
# _, element_id = e.ref
|
179
|
+
# @driver.test_action_command(element_id, 'action')
|
180
|
+
#
|
181
|
+
def add_command(method:, url:, name:, &block)
|
182
|
+
unless AVAILABLE_METHODS.include? method
|
183
|
+
raise ::Appium::Core::Error::ArgumentError, "Available method is either #{AVAILABLE_METHODS}"
|
184
|
+
end
|
185
|
+
|
186
|
+
# TODO: Remove this logger before Appium 2.0 release
|
187
|
+
::Appium::Logger.info '[Experimental] this method is experimental for Appium 2.0. This interface may change.'
|
188
|
+
|
189
|
+
@bridge.add_command method: method, url: url, name: name, &block
|
190
|
+
end
|
191
|
+
|
112
192
|
### Methods for Appium
|
113
193
|
|
114
194
|
# Lock the device
|
@@ -191,36 +271,6 @@ module Appium
|
|
191
271
|
end
|
192
272
|
alias type send_keys
|
193
273
|
|
194
|
-
class DriverSettings
|
195
|
-
# @private this class is private
|
196
|
-
def initialize(bridge)
|
197
|
-
@bridge = bridge
|
198
|
-
end
|
199
|
-
|
200
|
-
# Get appium Settings for current test session.
|
201
|
-
#
|
202
|
-
# @example
|
203
|
-
#
|
204
|
-
# @driver.settings.get
|
205
|
-
#
|
206
|
-
def get
|
207
|
-
@bridge.get_settings
|
208
|
-
end
|
209
|
-
|
210
|
-
# Update Appium Settings for current test session
|
211
|
-
#
|
212
|
-
# @param [Hash] settings Settings to update, keys are settings, values to value to set each setting to
|
213
|
-
#
|
214
|
-
# @example
|
215
|
-
#
|
216
|
-
# @driver.settings.update({'allowInvisibleElements': true})
|
217
|
-
#
|
218
|
-
def update(settings)
|
219
|
-
@bridge.update_settings(settings)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
private_constant :DriverSettings
|
223
|
-
|
224
274
|
# Returns an instance of DriverSettings to call get/update.
|
225
275
|
#
|
226
276
|
# @example
|
@@ -229,7 +279,7 @@ module Appium
|
|
229
279
|
# @driver.settings.update('allowInvisibleElements': true)
|
230
280
|
#
|
231
281
|
def settings
|
232
|
-
@
|
282
|
+
@settings ||= DriverSettings.new(@bridge)
|
233
283
|
end
|
234
284
|
|
235
285
|
# Get appium Settings for current test session.
|
@@ -260,34 +310,6 @@ module Appium
|
|
260
310
|
end
|
261
311
|
alias update_settings settings=
|
262
312
|
|
263
|
-
class DeviceIME
|
264
|
-
# @private this class is private
|
265
|
-
def initialize(bridge)
|
266
|
-
@bridge = bridge
|
267
|
-
end
|
268
|
-
|
269
|
-
def activate(ime_name)
|
270
|
-
@bridge.ime_activate(ime_name)
|
271
|
-
end
|
272
|
-
|
273
|
-
def available_engines
|
274
|
-
@bridge.ime_available_engines
|
275
|
-
end
|
276
|
-
|
277
|
-
def active_engine
|
278
|
-
@bridge.ime_active_engine
|
279
|
-
end
|
280
|
-
|
281
|
-
def activated?
|
282
|
-
@bridge.ime_activated
|
283
|
-
end
|
284
|
-
|
285
|
-
def deactivate
|
286
|
-
@bridge.ime_deactivate
|
287
|
-
end
|
288
|
-
end
|
289
|
-
private_constant :DeviceIME
|
290
|
-
|
291
313
|
# Returns an instance of DeviceIME
|
292
314
|
#
|
293
315
|
# @return [Appium::Core::Base::Driver::DeviceIME]
|
@@ -301,7 +323,7 @@ module Appium
|
|
301
323
|
# @driver.ime.deactivate #=> Deactivate current IME engine
|
302
324
|
#
|
303
325
|
def ime
|
304
|
-
@
|
326
|
+
@ime ||= DeviceIME.new(@bridge)
|
305
327
|
end
|
306
328
|
|
307
329
|
# Android only. Make an engine that is available active.
|
@@ -421,30 +443,6 @@ module Appium
|
|
421
443
|
end
|
422
444
|
alias set_context context=
|
423
445
|
|
424
|
-
# Set the value to element directly
|
425
|
-
#
|
426
|
-
# @example
|
427
|
-
#
|
428
|
-
# @driver.set_immediate_value element, 'hello'
|
429
|
-
#
|
430
|
-
def set_immediate_value(element, *value)
|
431
|
-
::Appium::Logger.warn '[DEPRECATION] driver#set_immediate_value(element, *value) is deprecated. ' \
|
432
|
-
'Use Element#immediate_value(*value) instead'
|
433
|
-
@bridge.set_immediate_value(element, *value)
|
434
|
-
end
|
435
|
-
|
436
|
-
# Replace the value to element directly
|
437
|
-
#
|
438
|
-
# @example
|
439
|
-
#
|
440
|
-
# @driver.replace_value element, 'hello'
|
441
|
-
#
|
442
|
-
def replace_value(element, *value)
|
443
|
-
::Appium::Logger.warn '[DEPRECATION] driver#replace_value(element, *value) is deprecated. ' \
|
444
|
-
'Use Element#replace_value(*value) instead'
|
445
|
-
@bridge.replace_value(element, *value)
|
446
|
-
end
|
447
|
-
|
448
446
|
# Place a file in a specific location on the device.
|
449
447
|
# On iOS, the server should have ifuse libraries installed and configured properly for this feature to work on
|
450
448
|
# real devices.
|
@@ -864,7 +862,7 @@ module Appium
|
|
864
862
|
# @driver.perform_actions [f1, f2] #=> 'nil' if the action succeed
|
865
863
|
#
|
866
864
|
def perform_actions(data)
|
867
|
-
raise ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
865
|
+
raise ::Appium::Core::Error::ArgumentError, "'#{data}' must be Array" unless data.is_a? Array
|
868
866
|
|
869
867
|
@bridge.send_actions data.map(&:encode).compact
|
870
868
|
data.each(&:clear_actions)
|
@@ -942,8 +940,7 @@ module Appium
|
|
942
940
|
# #=> uiautomator2
|
943
941
|
# # <Selenium::WebDriver::Remote::Capabilities:0x007fa38dae1360
|
944
942
|
# # @capabilities=
|
945
|
-
# # {:
|
946
|
-
# # :browser_name=>nil,
|
943
|
+
# # {:browser_name=>nil,
|
947
944
|
# # :browser_version=>nil,
|
948
945
|
# # :platform_name=>"android",
|
949
946
|
# # :page_load_strategy=>nil,
|
@@ -992,8 +989,7 @@ module Appium
|
|
992
989
|
# #=> XCUITest
|
993
990
|
# # <Selenium::WebDriver::Remote::Capabilities:0x007fb15dc01370
|
994
991
|
# # @capabilities=
|
995
|
-
# # {:
|
996
|
-
# # :browser_name=>"UICatalog",
|
992
|
+
# # {:browser_name=>"UICatalog",
|
997
993
|
# # :browser_version=>nil,
|
998
994
|
# # :platform_name=>"ios",
|
999
995
|
# # :page_load_strategy=>nil,
|
@@ -1074,7 +1070,7 @@ module Appium
|
|
1074
1070
|
#
|
1075
1071
|
# @param [String] img_path A path to a partial image you'd like to find
|
1076
1072
|
#
|
1077
|
-
# @return [::
|
1073
|
+
# @return [::Appium::Core::Element]
|
1078
1074
|
#
|
1079
1075
|
# @example
|
1080
1076
|
#
|
@@ -1144,14 +1140,14 @@ module Appium
|
|
1144
1140
|
@bridge.execute_driver(script: script, type: type, timeout_ms: timeout_ms)
|
1145
1141
|
end
|
1146
1142
|
|
1147
|
-
# Convert vanilla element response to ::
|
1143
|
+
# Convert vanilla element response to ::Appium::Core::Element
|
1148
1144
|
#
|
1149
1145
|
# @param [Hash] id The id which can get as a response from server
|
1150
|
-
# @return [::
|
1146
|
+
# @return [::Appium::Core::Element]
|
1151
1147
|
#
|
1152
1148
|
# @example
|
1153
1149
|
# response = {"element-6066-11e4-a52e-4f735466cecf"=>"xxxx", "ELEMENT"=>"xxxx"}
|
1154
|
-
# ele = @driver.convert_to_element(response) #=> ::
|
1150
|
+
# ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
|
1155
1151
|
# ele.rect #=> Can get the rect of the element
|
1156
1152
|
#
|
1157
1153
|
def convert_to_element(id)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Appium
|
16
|
+
module Core
|
17
|
+
class Base
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
class DriverSettings
|
22
|
+
# @private this class is private
|
23
|
+
def initialize(bridge)
|
24
|
+
@bridge = bridge
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get appium Settings for current test session.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
#
|
31
|
+
# @driver.settings.get
|
32
|
+
#
|
33
|
+
def get
|
34
|
+
@bridge.get_settings
|
35
|
+
end
|
36
|
+
|
37
|
+
# Update Appium Settings for current test session
|
38
|
+
#
|
39
|
+
# @param [Hash] settings Settings to update, keys are settings, values to value to set each setting to
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
#
|
43
|
+
# @driver.settings.update({'allowInvisibleElements': true})
|
44
|
+
#
|
45
|
+
def update(settings)
|
46
|
+
@bridge.update_settings(settings)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -52,19 +52,26 @@ module Appium
|
|
52
52
|
# @param [String, Number] latitude Set the latitude.
|
53
53
|
# @param [String, Number] longitude Set the longitude.
|
54
54
|
# @param [String, Number] altitude Set the altitude.
|
55
|
-
# @param [String, Number] speed Set the speed to apply the location on Android real devices
|
55
|
+
# @param [String, Number] speed Set the speed to apply the location on Android real devices
|
56
|
+
# in meters/second @since Appium 1.21.0 and in knots for emulators @since Appium 1.22.0.
|
57
|
+
# @param [String, Number] satellites Sets the count of geo satellites being tracked in range 1..12 @since Appium 1.22.0.
|
58
|
+
# This number is respected on Emulators.
|
56
59
|
# @param [::Selenium::WebDriver::Location]
|
57
60
|
#
|
58
61
|
# @example
|
59
62
|
#
|
60
63
|
# driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
|
61
64
|
#
|
62
|
-
def set_location(latitude, longitude, altitude, speed: nil)
|
63
|
-
if speed.nil?
|
65
|
+
def set_location(latitude, longitude, altitude, speed: nil, satellites: nil)
|
66
|
+
if speed.nil? && satellites.nil?
|
64
67
|
self.location = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
|
65
68
|
else
|
66
69
|
loc = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
|
67
|
-
|
70
|
+
|
71
|
+
speed = Float(speed) unless speed.nil?
|
72
|
+
satellites = Integer(satellites) unless satellites.nil?
|
73
|
+
|
74
|
+
@bridge.set_location loc.latitude, loc.longitude, loc.altitude, speed: speed, satellites: satellites
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|