appium_lib 10.6.0 → 12.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/.azure-pipelines.yml +18 -0
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/rubocop.yml +27 -0
- data/.rubocop.yml +106 -8
- data/CHANGELOG.md +16 -0
- data/appium_lib.gemspec +5 -5
- data/docs/android_docs.md +209 -209
- data/docs/ios_docs.md +247 -247
- data/lib/appium_lib/android/common/helper.rb +4 -4
- data/lib/appium_lib/android/element/button.rb +4 -4
- data/lib/appium_lib/android/element/generic.rb +8 -12
- data/lib/appium_lib/android/espresso/element/button.rb +2 -2
- data/lib/appium_lib/android/espresso/element/generic.rb +20 -24
- data/lib/appium_lib/android/uiautomator2/element/button.rb +4 -4
- data/lib/appium_lib/appium.rb +32 -32
- data/lib/appium_lib/common/helper.rb +7 -5
- data/lib/appium_lib/common/wait.rb +3 -4
- data/lib/appium_lib/driver.rb +10 -48
- data/lib/appium_lib/ios/common/helper.rb +3 -2
- data/lib/appium_lib/ios/xcuitest/command/gestures.rb +14 -14
- data/lib/appium_lib/ios/xcuitest/command/multi_app_handler.rb +6 -12
- data/lib/appium_lib/ios/xcuitest/helper.rb +1 -1
- data/lib/appium_lib/ios/xcuitest.rb +0 -1
- data/lib/appium_lib/version.rb +2 -2
- data/readme.md +2 -9
- data/release_notes.md +25 -0
- metadata +30 -22
- data/.travis.yml +0 -19
@@ -27,7 +27,7 @@ module Appium
|
|
27
27
|
@filter = value.to_s.downcase
|
28
28
|
end
|
29
29
|
|
30
|
-
def initialize
|
30
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
31
31
|
reset
|
32
32
|
@filter = false
|
33
33
|
end
|
@@ -217,7 +217,7 @@ module Appium
|
|
217
217
|
# [^\/]+ - type is made up of at least one non-/ characters
|
218
218
|
# \\/ - / ends the type and starts the name
|
219
219
|
# [\S]+$ - the name contains at least one non-space character and then the line is ended
|
220
|
-
resource_id = /^[a-zA-Z_][a-zA-Z0-9
|
220
|
+
resource_id = /^[a-zA-Z_][a-zA-Z0-9._]*:[^\/]+\/\S+$/
|
221
221
|
string.match(resource_id) ? on_match : ''
|
222
222
|
end
|
223
223
|
|
@@ -234,11 +234,11 @@ module Appium
|
|
234
234
|
|
235
235
|
if class_name == '*'
|
236
236
|
return "//*[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
|
237
|
-
|
237
|
+
" or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
|
238
238
|
end
|
239
239
|
|
240
240
|
"//#{class_name}[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
|
241
|
-
|
241
|
+
" or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
|
242
242
|
end
|
243
243
|
|
244
244
|
# Returns a string that matches the first element that contains value
|
@@ -60,9 +60,9 @@ module Appium
|
|
60
60
|
# uiautomator index doesn't support last
|
61
61
|
# and it's 0 indexed
|
62
62
|
button_index = tags(BUTTON).length
|
63
|
-
button_index -= 1 if button_index
|
63
|
+
button_index -= 1 if button_index.positive?
|
64
64
|
image_button_index = tags(IMAGE_BUTTON).length
|
65
|
-
image_button_index -= 1 if image_button_index
|
65
|
+
image_button_index -= 1 if image_button_index.positive?
|
66
66
|
|
67
67
|
find_element :uiautomator,
|
68
68
|
_button_visible_selectors(button_index: button_index,
|
@@ -98,10 +98,10 @@ module Appium
|
|
98
98
|
|
99
99
|
if button_index && image_button_index
|
100
100
|
"new UiSelector().className(#{BUTTON}).instance(#{button_index});" \
|
101
|
-
|
101
|
+
"new UiSelector().className(#{IMAGE_BUTTON}).instance(#{image_button_index});"
|
102
102
|
else
|
103
103
|
"new UiSelector().className(#{BUTTON});" \
|
104
|
-
|
104
|
+
"new UiSelector().className(#{IMAGE_BUTTON});"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -56,12 +56,10 @@ module Appium
|
|
56
56
|
rid = resource_id(text, "new UiSelector().resourceId(#{text})")
|
57
57
|
args = rid.empty? ? ["new UiSelector().textContains(#{text})", "new UiSelector().descriptionContains(#{text})"] : [rid]
|
58
58
|
args.each_with_index do |arg, index|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
raise e if index == args.size - 1
|
64
|
-
end
|
59
|
+
elem = find_element :uiautomator, scroll_uiselector(arg, scrollable_index)
|
60
|
+
return elem
|
61
|
+
rescue StandardError => e
|
62
|
+
raise e if index == args.size - 1
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
@@ -74,12 +72,10 @@ module Appium
|
|
74
72
|
rid = resource_id(text, "new UiSelector().resourceId(#{text})")
|
75
73
|
args = rid.empty? ? ["new UiSelector().text(#{text})", "new UiSelector().description(#{text})"] : [rid]
|
76
74
|
args.each_with_index do |arg, index|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
raise e if index == args.size - 1
|
82
|
-
end
|
75
|
+
elem = find_element :uiautomator, scroll_uiselector(arg, scrollable_index)
|
76
|
+
return elem
|
77
|
+
rescue StandardError => e
|
78
|
+
raise e if index == args.size - 1
|
83
79
|
end
|
84
80
|
end
|
85
81
|
end # module Android
|
@@ -63,9 +63,9 @@ module Appium
|
|
63
63
|
# uiautomator index doesn't support last
|
64
64
|
# and it's 0 indexed
|
65
65
|
button_index = tags(::Appium::Android::BUTTON).length
|
66
|
-
button_index -= 1 if button_index
|
66
|
+
button_index -= 1 if button_index.positive?
|
67
67
|
image_button_index = tags(::Appium::Android::IMAGE_BUTTON).length
|
68
|
-
image_button_index -= 1 if image_button_index
|
68
|
+
image_button_index -= 1 if image_button_index.positive?
|
69
69
|
|
70
70
|
_button_visible_selectors_xpath(button_index: button_index,
|
71
71
|
image_button_index: image_button_index)
|
@@ -25,19 +25,17 @@ module Appium
|
|
25
25
|
w_s = window_rect
|
26
26
|
|
27
27
|
(1..30).each do |_count|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
sleep 1 # we must wait finish scrolling
|
28
|
+
action
|
29
|
+
.move_to_location(w_s.width / 2, (w_s.height * 2) / 5) # pointer based magic number
|
30
|
+
.pointer_down(:left)
|
31
|
+
.move_to_location(0, w_s.height / 5)
|
32
|
+
.release
|
33
|
+
.perform
|
34
|
+
sleep 1 # we must wait finish scrolling
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
36
|
+
return text(text)
|
37
|
+
rescue StandardError => e
|
38
|
+
err = e
|
41
39
|
end
|
42
40
|
|
43
41
|
raise err
|
@@ -52,19 +50,17 @@ module Appium
|
|
52
50
|
w_s = window_rect
|
53
51
|
|
54
52
|
(1..30).each do |_count|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
sleep 1 # we must wait finish scrolling
|
53
|
+
action
|
54
|
+
.move_to_location(w_s.width / 2, (w_s.height * 2) / 5) # pointer based magic number
|
55
|
+
.pointer_down(:left)
|
56
|
+
.move_to_location(0, w_s.height / 5)
|
57
|
+
.release
|
58
|
+
.perform
|
59
|
+
sleep 1 # we must wait finish scrolling
|
63
60
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
61
|
+
return text_exact(text)
|
62
|
+
rescue StandardError => e
|
63
|
+
err = e
|
68
64
|
end
|
69
65
|
|
70
66
|
raise err
|
@@ -60,9 +60,9 @@ module Appium
|
|
60
60
|
# uiautomator index doesn't support last
|
61
61
|
# and it's 0 indexed
|
62
62
|
button_index = tags(::Appium::Android::Button).length
|
63
|
-
button_index -= 1 if button_index
|
63
|
+
button_index -= 1 if button_index.positive?
|
64
64
|
image_button_index = tags(::Appium::Android::ImageButton).length
|
65
|
-
image_button_index -= 1 if image_button_index
|
65
|
+
image_button_index -= 1 if image_button_index.positive?
|
66
66
|
|
67
67
|
elements = find_elements :uiautomator,
|
68
68
|
_button_visible_selectors(button_index: button_index,
|
@@ -101,10 +101,10 @@ module Appium
|
|
101
101
|
|
102
102
|
if button_index && image_button_index
|
103
103
|
"new UiSelector().className(#{::Appium::Android::Button}).instance(#{button_index});" \
|
104
|
-
|
104
|
+
"new UiSelector().className(#{::Appium::Android::ImageButton}).instance(#{image_button_index});"
|
105
105
|
else
|
106
106
|
"new UiSelector().className(#{::Appium::Android::Button});" \
|
107
|
-
|
107
|
+
"new UiSelector().className(#{::Appium::Android::ImageButton});"
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
data/lib/appium_lib/appium.rb
CHANGED
@@ -77,9 +77,8 @@ module Appium
|
|
77
77
|
Appium::Logger.info "Loading #{toml}" if verbose
|
78
78
|
|
79
79
|
data = Tomlrb.load_file(toml, symbolize_keys: true)
|
80
|
-
|
81
|
-
|
82
|
-
end
|
80
|
+
|
81
|
+
Appium::Logger.info data if verbose && !data.empty?
|
83
82
|
|
84
83
|
if data && data[:caps] && data[:caps][:app] && !data[:caps][:app].empty?
|
85
84
|
data[:caps][:app] = Appium::Driver.absolute_app_path data
|
@@ -157,18 +156,16 @@ module Appium
|
|
157
156
|
|
158
157
|
target_modules.each do |const|
|
159
158
|
# noinspection RubyResolve
|
160
|
-
# rubocop:disable Style/MultilineIfModifier
|
161
159
|
driver.public_methods(false).each do |m|
|
160
|
+
# override unless there's an existing method with matching arity
|
161
|
+
next if const.respond_to?(m) && const.method(m).arity == driver.method(m).arity
|
162
|
+
|
162
163
|
const.send(:define_singleton_method, m) do |*args, &block|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end
|
168
|
-
# override unless there's an existing method with matching arity
|
169
|
-
end unless const.respond_to?(m) && const.method(m).arity == driver.method(m).arity
|
164
|
+
super(*args, &block) # promote.rb
|
165
|
+
rescue NoMethodError, ArgumentError
|
166
|
+
driver.send m, *args, &block if driver.respond_to?(m)
|
167
|
+
end
|
170
168
|
end
|
171
|
-
# rubocop:enable Style/MultilineIfModifier
|
172
169
|
end
|
173
170
|
end
|
174
171
|
|
@@ -200,29 +197,32 @@ module Appium
|
|
200
197
|
raise 'Driver is nil' if driver.nil?
|
201
198
|
|
202
199
|
# Wrap single class into an array
|
203
|
-
class_array = [class_array] unless class_array.
|
200
|
+
class_array = [class_array] unless class_array.instance_of? Array
|
204
201
|
# Promote Appium driver methods to class instance methods.
|
205
202
|
class_array.each do |klass|
|
206
|
-
driver.public_methods(false).each do |
|
203
|
+
driver.public_methods(false).each do |method|
|
207
204
|
klass.class_eval do
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
205
|
+
if method_defined? method
|
206
|
+
::Appium::Logger.warn "'#{method}' is already defined. Skipping to override it."
|
207
|
+
next
|
208
|
+
end
|
209
|
+
|
210
|
+
define_method method do |*args, &block|
|
211
|
+
# Prefer existing method.
|
212
|
+
# super will invoke method missing on driver
|
213
|
+
super(*args, &block)
|
214
|
+
|
215
|
+
# minitest also defines a name method,
|
216
|
+
# so rescue argument error
|
217
|
+
# and call the name method on $driver
|
218
|
+
rescue NoMethodError, ArgumentError
|
219
|
+
if args.size == 1 && args.first.is_a?(Hash)
|
220
|
+
# To prevent warnings by keyword arguments (for Ruby 2.7 and 3)
|
221
|
+
driver.send method, **args.first, &block if driver.respond_to?(method)
|
222
|
+
else
|
223
|
+
::Appium::Logger.warn "Should fix this '#{args}' for Ruby 2.7 (and 3)" if args.first.is_a?(Hash)
|
224
|
+
|
225
|
+
driver.send method, *args, &block if driver.respond_to?(method)
|
226
226
|
end
|
227
227
|
end
|
228
228
|
end
|
@@ -29,7 +29,8 @@ module Appium
|
|
29
29
|
# Return yield and ignore any exceptions.
|
30
30
|
def ignore
|
31
31
|
yield
|
32
|
-
rescue Exception # rubocop:disable Lint/
|
32
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
33
|
+
# Ignored
|
33
34
|
end
|
34
35
|
|
35
36
|
# Navigate back.
|
@@ -73,7 +74,7 @@ module Appium
|
|
73
74
|
class CountElements < Nokogiri::XML::SAX::Document
|
74
75
|
attr_reader :result
|
75
76
|
|
76
|
-
def initialize(platform)
|
77
|
+
def initialize(platform) # rubocop:disable Lint/MissingSuper
|
77
78
|
reset
|
78
79
|
@platform = platform
|
79
80
|
end
|
@@ -213,7 +214,7 @@ module Appium
|
|
213
214
|
@filter = value.to_s.downcase
|
214
215
|
end
|
215
216
|
|
216
|
-
def initialize
|
217
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
217
218
|
reset
|
218
219
|
@filter = false
|
219
220
|
end
|
@@ -232,8 +233,9 @@ module Appium
|
|
232
233
|
"#{string} #{attr[0]}: #{attr1}\n"
|
233
234
|
end
|
234
235
|
|
235
|
-
r
|
236
|
-
|
236
|
+
return r if attr_string.nil? || attr_string.empty?
|
237
|
+
|
238
|
+
"#{r}\n#{name}\n#{attr_string}"
|
237
239
|
end
|
238
240
|
end
|
239
241
|
|
@@ -42,10 +42,10 @@ module Appium
|
|
42
42
|
# wait_true(20) { button_exact('Back') }.click
|
43
43
|
#
|
44
44
|
def wait_true(opts = {})
|
45
|
-
opts =
|
45
|
+
opts = { timeout: opts } if opts.is_a? Numeric
|
46
46
|
|
47
47
|
if opts.is_a? Hash
|
48
|
-
opts.empty? ? @core.wait_true { yield } : @core.wait_true(opts) { yield }
|
48
|
+
opts.empty? ? @core.wait_true { yield } : @core.wait_true(**opts) { yield }
|
49
49
|
else
|
50
50
|
::Appium::Logger.warn('Arguments should be Hash like {timeout: 100}')
|
51
51
|
end
|
@@ -71,8 +71,7 @@ module Appium
|
|
71
71
|
# wait(20) { button_exact('Back') }.click
|
72
72
|
#
|
73
73
|
def wait(opts = {})
|
74
|
-
opts =
|
75
|
-
|
74
|
+
opts = { timeout: opts } if opts.is_a? Numeric
|
76
75
|
if opts.is_a? Hash
|
77
76
|
opts.empty? ? @core.wait { yield } : @core.wait(**opts) { yield }
|
78
77
|
else
|
data/lib/appium_lib/driver.rb
CHANGED
@@ -151,21 +151,12 @@ module Appium
|
|
151
151
|
# @param opts [Object] A hash containing various options.
|
152
152
|
# @param global_driver [Bool] A bool require global driver before initialize.
|
153
153
|
# @return [Driver]
|
154
|
-
def initialize(opts = {}, global_driver =
|
155
|
-
# TODO: set `global_driver = false` by default in the future.
|
154
|
+
def initialize(opts = {}, global_driver = false)
|
156
155
|
# Capybara can't put `global_driver` as the 2nd argument.
|
157
156
|
global_driver = opts.delete :global_driver if global_driver.nil?
|
158
157
|
|
159
|
-
if global_driver
|
160
|
-
warn '[DEPRECATION] Appium::Driver.new(opts) will not generate global driver by default.' \
|
161
|
-
'If you would like to generate the global driver dy default, ' \
|
162
|
-
'please initialise driver with Appium::Driver.new(opts, true)'
|
163
|
-
global_driver = true # if global_driver is nil, then global_driver must be default value.
|
164
|
-
end
|
158
|
+
$driver&.driver_quit if global_driver
|
165
159
|
|
166
|
-
if global_driver
|
167
|
-
$driver.driver_quit if $driver
|
168
|
-
end
|
169
160
|
raise 'opts must be a hash' unless opts.is_a? Hash
|
170
161
|
|
171
162
|
@core = ::Appium::Core.for(opts)
|
@@ -277,7 +268,6 @@ module Appium
|
|
277
268
|
|
278
269
|
# Returns a hash of the driver attributes
|
279
270
|
def driver_attributes
|
280
|
-
# rubocop:disable Layout/AlignHash
|
281
271
|
{
|
282
272
|
caps: @core.caps,
|
283
273
|
automation_name: @core.automation_name,
|
@@ -295,7 +285,6 @@ module Appium
|
|
295
285
|
wait_timeout: @core.wait_timeout,
|
296
286
|
wait_interval: @core.wait_interval
|
297
287
|
}
|
298
|
-
# rubocop:enable Layout/AlignHash
|
299
288
|
end
|
300
289
|
|
301
290
|
def device_is_android?
|
@@ -328,27 +317,7 @@ module Appium
|
|
328
317
|
!@core.automation_name.nil? && @core.automation_name == :xcuitest
|
329
318
|
end
|
330
319
|
|
331
|
-
#
|
332
|
-
#
|
333
|
-
# @return [:oss | :w3c]
|
334
|
-
#
|
335
|
-
# @example
|
336
|
-
#
|
337
|
-
# if dialect == :w3c
|
338
|
-
# driver.action
|
339
|
-
# .move_to_location(500, 500).pointer_down(:left)
|
340
|
-
# .move_to_location(0, 700)
|
341
|
-
# .release.perform
|
342
|
-
# else
|
343
|
-
# action = TouchAction.new(driver).press(x: 500, y: 500).move_to(500, 700).release
|
344
|
-
# action.perform
|
345
|
-
# end
|
346
|
-
#
|
347
|
-
def dialect
|
348
|
-
@driver.dialect
|
349
|
-
end
|
350
|
-
|
351
|
-
# An entry point to chain W3C actions. Returns `TouchAction.new` if it works as MJSONWP instead of W3C action.
|
320
|
+
# An entry point to chain W3C actions
|
352
321
|
# Read https://www.rubydoc.info/github/appium/ruby_lib_core/Appium/Core/Base/Bridge/W3C#action-instance_method
|
353
322
|
#
|
354
323
|
# @return [TouchAction|Selenium::WebDriver::PointerActions]
|
@@ -359,12 +328,7 @@ module Appium
|
|
359
328
|
# action.click(element).perform # The `click` is a part of `PointerActions`
|
360
329
|
#
|
361
330
|
def action
|
362
|
-
|
363
|
-
::Appium::Logger.info('Calls TouchAction instead of W3C actions for MJSONWP module')
|
364
|
-
TouchAction.new($driver || @driver)
|
365
|
-
else
|
366
|
-
@driver.action
|
367
|
-
end
|
331
|
+
@driver.action
|
368
332
|
end
|
369
333
|
|
370
334
|
# Returns the server's version info
|
@@ -426,14 +390,12 @@ module Appium
|
|
426
390
|
return app_path if app_path =~ URI::DEFAULT_PARSER.make_regexp # public URL for Sauce
|
427
391
|
|
428
392
|
absolute_app_path = File.expand_path app_path
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
app_path
|
393
|
+
if File.exist? absolute_app_path
|
394
|
+
absolute_app_path
|
395
|
+
else
|
396
|
+
::Appium::Logger.info("Use #{app_path}")
|
397
|
+
app_path
|
398
|
+
end
|
437
399
|
end
|
438
400
|
|
439
401
|
# Get the server url
|
@@ -49,6 +49,7 @@ module Appium
|
|
49
49
|
puts " visible: #{visible}" if visible
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
52
53
|
# iOS only. On Android uiautomator always returns an empty string for EditText password.
|
53
54
|
#
|
54
55
|
# Password character returned from value of UIASecureTextField
|
@@ -76,7 +77,7 @@ module Appium
|
|
76
77
|
source = get_source
|
77
78
|
|
78
79
|
# current_context may be nil which breaks start_with
|
79
|
-
if current_context
|
80
|
+
if current_context&.start_with?('WEBVIEW')
|
80
81
|
parser = @android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Appium::Common::HTMLElements.new)
|
81
82
|
parser.document.reset
|
82
83
|
parser.document.filter = class_name
|
@@ -470,7 +471,7 @@ module Appium
|
|
470
471
|
# will be present.
|
471
472
|
_validate_object opts[:name], opts[:label], opts[:value]
|
472
473
|
|
473
|
-
#
|
474
|
+
# NOTE: that mainWindow is sometimes nil so it's passed as a param
|
474
475
|
# $._elementOrElementsByType will validate that the window isn't nil
|
475
476
|
element_or_elements_by_type = <<-JS
|
476
477
|
(function() {
|
@@ -24,7 +24,7 @@ module Appium
|
|
24
24
|
# ```
|
25
25
|
def swipe(direction:, element: nil)
|
26
26
|
args = { direction: direction }
|
27
|
-
args[:element] = element.
|
27
|
+
args[:element] = element.id if element
|
28
28
|
|
29
29
|
@driver.execute_script 'mobile: swipe', args
|
30
30
|
end
|
@@ -47,7 +47,7 @@ module Appium
|
|
47
47
|
return 'Set "up", "down", "left" or "right" for :direction' unless %w(up down left right).include?(direction)
|
48
48
|
|
49
49
|
args = { direction: direction }
|
50
|
-
args[:element] = element.
|
50
|
+
args[:element] = element.id if element
|
51
51
|
args[:distance] = distance if distance
|
52
52
|
args[:name] = name if name
|
53
53
|
args[:toVisible] = to_visible if to_visible
|
@@ -66,7 +66,7 @@ module Appium
|
|
66
66
|
# ```
|
67
67
|
def pinch(scale:, velocity: 1.0, element: nil)
|
68
68
|
args = { scale: scale, velocity: velocity }
|
69
|
-
args[:element] = element.
|
69
|
+
args[:element] = element.id if element
|
70
70
|
|
71
71
|
@driver.execute_script 'mobile: pinch', args
|
72
72
|
end
|
@@ -79,10 +79,10 @@ module Appium
|
|
79
79
|
# double_tap x: 100, y: 100
|
80
80
|
# double_tap element: find_element(:accessibility_id, "some item")
|
81
81
|
# ```
|
82
|
-
def double_tap(x: nil, y: nil, element: nil)
|
82
|
+
def double_tap(x: nil, y: nil, element: nil)
|
83
83
|
return 'Set x, y or element' if (x.nil? || y.nil?) && element.nil?
|
84
84
|
|
85
|
-
args = element.nil? ? { x: x, y: y } : { element: element.
|
85
|
+
args = element.nil? ? { x: x, y: y } : { element: element.id }
|
86
86
|
@driver.execute_script 'mobile: doubleTap', args
|
87
87
|
end
|
88
88
|
|
@@ -96,10 +96,10 @@ module Appium
|
|
96
96
|
# touch_and_hold x: 100, y: 100, duration: 2.0
|
97
97
|
# touch_and_hold element: find_element(:accessibility_id, "some item")
|
98
98
|
# ```
|
99
|
-
def touch_and_hold(x: nil, y: nil, element: nil, duration: 1.0)
|
99
|
+
def touch_and_hold(x: nil, y: nil, element: nil, duration: 1.0)
|
100
100
|
return 'Set x, y or element' if (x.nil? || y.nil?) && element.nil?
|
101
101
|
|
102
|
-
args = element.nil? ? { x: x, y: y } : { element: element.
|
102
|
+
args = element.nil? ? { x: x, y: y } : { element: element.id }
|
103
103
|
args[:duration] = duration
|
104
104
|
@driver.execute_script 'mobile: touchAndHold', args
|
105
105
|
end
|
@@ -110,7 +110,7 @@ module Appium
|
|
110
110
|
# two_finger_tap element: find_element(:accessibility_id, "some item")
|
111
111
|
# ```
|
112
112
|
def two_finger_tap(element:)
|
113
|
-
args = { element: element.
|
113
|
+
args = { element: element.id }
|
114
114
|
@driver.execute_script 'mobile: twoFingerTap', args
|
115
115
|
end
|
116
116
|
|
@@ -121,12 +121,12 @@ module Appium
|
|
121
121
|
# Otherwise they should be calculated relatively to screen borders.
|
122
122
|
#
|
123
123
|
# ```ruby
|
124
|
-
#
|
125
|
-
#
|
124
|
+
# one_finger_tap x: 100, y: 100
|
125
|
+
# one_finger_tap x: 100, y: 100, element: find_element(:accessibility_id, "some item")
|
126
126
|
# ```
|
127
|
-
def
|
127
|
+
def one_finger_tap(x:, y:, element: nil)
|
128
128
|
args = { x: x, y: y }
|
129
|
-
args[:element] = element.
|
129
|
+
args[:element] = element.id if element
|
130
130
|
@driver.execute_script 'mobile: tap', args
|
131
131
|
end
|
132
132
|
|
@@ -146,7 +146,7 @@ module Appium
|
|
146
146
|
# ```
|
147
147
|
def drag_from_to_for_duration(from_x:, from_y:, to_x:, to_y:, duration: 1.0, element: nil)
|
148
148
|
args = { fromX: from_x, fromY: from_y, toX: to_x, toY: to_y, duration: duration }
|
149
|
-
args[:element] = element.
|
149
|
+
args[:element] = element.id if element
|
150
150
|
@driver.execute_script 'mobile: dragFromToForDuration', args
|
151
151
|
end
|
152
152
|
# rubocop:enable Metrics/ParameterLists
|
@@ -164,7 +164,7 @@ module Appium
|
|
164
164
|
def select_picker_wheel(element:, order:, offset: nil)
|
165
165
|
return 'Set "next" or "previous" for :order' unless %w(next previous).include?(order)
|
166
166
|
|
167
|
-
args = { element: element.
|
167
|
+
args = { element: element.id, order: order }
|
168
168
|
args[:offset] = offset if offset
|
169
169
|
@driver.execute_script 'mobile: selectPickerWheelValue', args
|
170
170
|
end
|
@@ -33,8 +33,7 @@ module Appium
|
|
33
33
|
# xcuitest_install_app(app: "path/to/app.app")
|
34
34
|
#
|
35
35
|
def xcuitest_install_app(app:)
|
36
|
-
|
37
|
-
@driver.execute_script 'mobile: installApp', args
|
36
|
+
@driver.install_app app
|
38
37
|
end
|
39
38
|
|
40
39
|
# Verifies whether the application with given bundle identifier is installed on the device.
|
@@ -47,8 +46,7 @@ module Appium
|
|
47
46
|
# xcuitest_app_installed?(bundle_id: "io.appium.bundle") #=> true or false
|
48
47
|
#
|
49
48
|
def xcuitest_app_installed?(bundle_id:)
|
50
|
-
|
51
|
-
@driver.execute_script 'mobile: isAppInstalled', args
|
49
|
+
@driver.app_installed? bundle_id
|
52
50
|
end
|
53
51
|
|
54
52
|
# Uninstalls an existing application from the device under test. This endpoint does not verify
|
@@ -62,8 +60,7 @@ module Appium
|
|
62
60
|
# xcuitest_remove_app(bundle_id: "io.appium.bundle") #=> 1
|
63
61
|
#
|
64
62
|
def xcuitest_remove_app(bundle_id:)
|
65
|
-
|
66
|
-
@driver.execute_script 'mobile: removeApp', args
|
63
|
+
@driver.remove_app bundle_id
|
67
64
|
end
|
68
65
|
|
69
66
|
# Executes an existing application on the device. If the application is already running then
|
@@ -92,8 +89,7 @@ module Appium
|
|
92
89
|
# xcuitest_terminate_app(bundle_id: "io.appium.bundle") #=> 1
|
93
90
|
#
|
94
91
|
def xcuitest_terminate_app(bundle_id:)
|
95
|
-
|
96
|
-
@driver.execute_script 'mobile: terminateApp', args
|
92
|
+
@driver.terminate_app bundle_id
|
97
93
|
end
|
98
94
|
|
99
95
|
# Get the status of an existing application on the device.
|
@@ -114,8 +110,7 @@ module Appium
|
|
114
110
|
# xcuitest_query_app_status(bundle_id: "io.appium.bundle") #=> 1
|
115
111
|
#
|
116
112
|
def xcuitest_query_app_status(bundle_id:)
|
117
|
-
|
118
|
-
@driver.execute_script 'mobile: queryAppState', args
|
113
|
+
@driver.app_state bundle_id
|
119
114
|
end
|
120
115
|
|
121
116
|
# Activates an existing application on the device under test and moves it to the foreground.
|
@@ -130,8 +125,7 @@ module Appium
|
|
130
125
|
# xcuitest_activate_app(bundle_id: "io.appium.bundle") #=> 1
|
131
126
|
#
|
132
127
|
def xcuitest_activate_app(bundle_id:)
|
133
|
-
|
134
|
-
@driver.execute_script 'mobile: activateApp', args
|
128
|
+
@driver.activate_app bundle_id
|
135
129
|
end
|
136
130
|
end
|
137
131
|
end # module Xcuitest
|
@@ -74,7 +74,7 @@ module Appium
|
|
74
74
|
c_names = class_names.map { |class_name| %(type == "#{class_name}") }.join(' || ')
|
75
75
|
|
76
76
|
predicate = if value
|
77
|
-
%((#{c_names}) && (name contains[c] "#{value}" || label contains[c] "#{value}" || value contains[c] "#{value}")) # rubocop:disable
|
77
|
+
%((#{c_names}) && (name contains[c] "#{value}" || label contains[c] "#{value}" || value contains[c] "#{value}")) # rubocop:disable Layout/LineLength
|
78
78
|
else
|
79
79
|
c_names
|
80
80
|
end
|
data/lib/appium_lib/version.rb
CHANGED
@@ -14,6 +14,6 @@
|
|
14
14
|
|
15
15
|
module Appium
|
16
16
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
17
|
-
VERSION = '
|
18
|
-
DATE = '
|
17
|
+
VERSION = '12.0.0.rc1' unless defined? ::Appium::VERSION
|
18
|
+
DATE = '2021-10-15' unless defined? ::Appium::DATE
|
19
19
|
end
|