appium_lib 9.0.0 → 9.1.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -0
  3. data/android_tests/lib/android/specs/android/helper.rb +3 -5
  4. data/android_tests/lib/android/specs/common/command.rb +47 -0
  5. data/android_tests/lib/android/specs/common/helper.rb +8 -8
  6. data/android_tests/lib/android/specs/common/web_context.rb +1 -1
  7. data/android_tests/lib/android/specs/driver.rb +19 -11
  8. data/android_tests/lib/format.rb +3 -3
  9. data/android_tests/lib/run.rb +7 -5
  10. data/android_tests/readme.md +1 -1
  11. data/appium_lib.gemspec +6 -7
  12. data/contributing.md +10 -0
  13. data/docs/android_docs.md +252 -217
  14. data/docs/ios_docs.md +257 -222
  15. data/docs/ios_xcuitest.md +32 -4
  16. data/ios_tests/lib/common.rb +11 -55
  17. data/ios_tests/lib/ios/specs/common/command.rb +44 -0
  18. data/ios_tests/lib/ios/specs/common/helper.rb +8 -8
  19. data/ios_tests/lib/ios/specs/device/device.rb +5 -5
  20. data/ios_tests/lib/ios/specs/driver.rb +34 -15
  21. data/ios_tests/lib/ios/specs/ios/element/textfield.rb +1 -1
  22. data/ios_tests/readme.md +1 -1
  23. data/ios_tests/upload/sauce_storage.rb +10 -8
  24. data/lib/appium_lib/android/element/button.rb +3 -3
  25. data/lib/appium_lib/android/element/text.rb +1 -1
  26. data/lib/appium_lib/android/element/textfield.rb +1 -1
  27. data/lib/appium_lib/android/helper.rb +12 -12
  28. data/lib/appium_lib/android/mobile_methods.rb +1 -3
  29. data/lib/appium_lib/common/command.rb +55 -0
  30. data/lib/appium_lib/common/helper.rb +7 -7
  31. data/lib/appium_lib/common/patch.rb +21 -8
  32. data/lib/appium_lib/common/search_context.rb +10 -0
  33. data/lib/appium_lib/common/version.rb +2 -2
  34. data/lib/appium_lib/common/wait.rb +8 -14
  35. data/lib/appium_lib/device/device.rb +65 -83
  36. data/lib/appium_lib/device/multi_touch.rb +2 -2
  37. data/lib/appium_lib/device/touch_actions.rb +4 -7
  38. data/lib/appium_lib/driver.rb +66 -38
  39. data/lib/appium_lib/ios/element/alert.rb +4 -4
  40. data/lib/appium_lib/ios/element/textfield.rb +3 -3
  41. data/lib/appium_lib/ios/errors.rb +6 -0
  42. data/lib/appium_lib/ios/helper.rb +25 -25
  43. data/lib/appium_lib/ios/mobile_methods.rb +2 -4
  44. data/readme.md +3 -1
  45. data/release_notes.md +13 -0
  46. metadata +23 -12
@@ -26,7 +26,7 @@ module Appium
26
26
  # action.perform #=> to 25% of its size.
27
27
  # ```
28
28
  def pinch(percentage = 25, auto_perform = true)
29
- fail ArgumentError("Can't pinch to greater than screen size.") if percentage > 100
29
+ raise ArgumentError("Can't pinch to greater than screen size.") if percentage > 100
30
30
 
31
31
  p = Float(percentage) / 100
32
32
 
@@ -62,7 +62,7 @@ module Appium
62
62
  # action.perform
63
63
  # ```
64
64
  def zoom(percentage = 200, auto_perform = true)
65
- fail ArgumentError("Can't zoom to smaller then screen size.") if percentage < 100
65
+ raise ArgumentError("Can't zoom to smaller then screen size.") if percentage < 100
66
66
 
67
67
  p = 100 / Float(percentage)
68
68
  i = 1 - p
@@ -8,8 +8,8 @@ module Appium
8
8
  # action = TouchAction.new.press(x: 45, y: 100).wait(5).release
9
9
  # action.perform
10
10
  class TouchAction
11
- ACTIONS = [:move_to, :long_press, :double_tap, :two_finger_tap, :press, :release, :tap, :wait, :perform]
12
- COMPLEX_ACTIONS = [:swipe]
11
+ ACTIONS = [:move_to, :long_press, :double_tap, :two_finger_tap, :press, :release, :tap, :wait, :perform].freeze
12
+ COMPLEX_ACTIONS = [:swipe].freeze
13
13
 
14
14
  class << self
15
15
  COMPLEX_ACTIONS.each do |action|
@@ -174,11 +174,8 @@ module Appium
174
174
  private
175
175
 
176
176
  def chain_method(method, args = nil)
177
- if args
178
- @actions << { action: method, options: args }
179
- else
180
- @actions << { action: method }
181
- end
177
+ action = args ? { action: method, options: args } : { action: method }
178
+ @actions << action
182
179
  self
183
180
  end
184
181
 
@@ -1,7 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'ap'
3
3
  require 'selenium-webdriver'
4
- require 'selenium/client/errors' # used in helper.rb for CommandError
5
4
  require 'nokogiri'
6
5
 
7
6
  # common
@@ -10,11 +9,14 @@ require_relative 'common/wait'
10
9
  require_relative 'common/patch'
11
10
  require_relative 'common/version'
12
11
  require_relative 'common/error'
12
+ require_relative 'common/search_context'
13
+ require_relative 'common/command'
13
14
  require_relative 'common/element/window'
14
15
 
15
16
  # ios
16
17
  require_relative 'ios/helper'
17
18
  require_relative 'ios/patch'
19
+ require_relative 'ios/errors'
18
20
 
19
21
  require_relative 'ios/element/alert'
20
22
  require_relative 'ios/element/button'
@@ -70,11 +72,11 @@ module Appium
70
72
  # @param opts [Hash] file: '/path/to/appium.txt', verbose: true
71
73
  # @return [hash] the symbolized hash with updated :app and :require keys
72
74
  def self.load_settings(opts = {})
73
- fail 'opts must be a hash' unless opts.is_a? Hash
74
- fail 'opts must not be empty' if opts.empty?
75
+ raise 'opts must be a hash' unless opts.is_a? Hash
76
+ raise 'opts must not be empty' if opts.empty?
75
77
 
76
78
  toml = opts[:file]
77
- fail 'Must pass file' unless toml
79
+ raise 'Must pass file' unless toml
78
80
  verbose = opts.fetch :verbose, false
79
81
 
80
82
  Appium::Logger.info "appium settings path: #{toml}" if verbose
@@ -82,12 +84,14 @@ module Appium
82
84
  toml_exists = File.exist? toml
83
85
  Appium::Logger.info "Exists? #{toml_exists}" if verbose
84
86
 
85
- fail "toml doesn't exist #{toml}" unless toml_exists
87
+ raise "toml doesn't exist #{toml}" unless toml_exists
86
88
  require 'tomlrb'
87
89
  Appium::Logger.info "Loading #{toml}" if verbose
88
90
 
89
91
  data = Tomlrb.load_file(toml, symbolize_keys: true)
90
- Appium::Logger.ap_info data unless data.empty? if verbose
92
+ if verbose
93
+ Appium::Logger.ap_info data unless data.empty?
94
+ end
91
95
 
92
96
  if data && data[:caps] && data[:caps][:app] && !data[:caps][:app].empty?
93
97
  data[:caps][:app] = Appium::Driver.absolute_app_path data
@@ -102,6 +106,7 @@ module Appium
102
106
  end
103
107
 
104
108
  class << self
109
+ # rubocop:disable Style/Alias
105
110
  alias_method :load_appium_txt, :load_settings
106
111
  end
107
112
 
@@ -141,7 +146,7 @@ module Appium
141
146
  # based on deep_symbolize_keys & deep_transform_keys from rails
142
147
  # https://github.com/rails/docrails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/activesupport/lib/active_support/core_ext/hash/keys.rb#L84
143
148
  def self.symbolize_keys(hash)
144
- fail 'symbolize_keys requires a hash' unless hash.is_a? Hash
149
+ raise 'symbolize_keys requires a hash' unless hash.is_a? Hash
145
150
  result = {}
146
151
  hash.each do |key, value|
147
152
  key = key.to_sym rescue key # rubocop:disable Style/RescueModifier
@@ -162,7 +167,7 @@ module Appium
162
167
  # that module are promoted on.
163
168
  # otherwise, the array of modules will be used as the promotion target.
164
169
  def self.promote_singleton_appium_methods(modules)
165
- fail 'Driver is nil' if $driver.nil?
170
+ raise 'Driver is nil' if $driver.nil?
166
171
 
167
172
  target_modules = []
168
173
 
@@ -171,12 +176,13 @@ module Appium
171
176
  target_modules << modules.const_get(sub_module)
172
177
  end
173
178
  else
174
- fail 'modules must be a module or an array' unless modules.is_a? Array
179
+ raise 'modules must be a module or an array' unless modules.is_a? Array
175
180
  target_modules = modules
176
181
  end
177
182
 
178
183
  target_modules.each do |const|
179
184
  # noinspection RubyResolve
185
+ # rubocop:disable Style/MultilineIfModifier
180
186
  $driver.public_methods(false).each do |m|
181
187
  const.send(:define_singleton_method, m) do |*args, &block|
182
188
  begin
@@ -187,6 +193,7 @@ module Appium
187
193
  # override unless there's an existing method with matching arity
188
194
  end unless const.respond_to?(m) && const.method(m).arity == $driver.method(m).arity
189
195
  end
196
+ # rubocop:enable Style/MultilineIfModifier
190
197
  end
191
198
  end
192
199
 
@@ -213,7 +220,7 @@ module Appium
213
220
  # Appium.promote_appium_methods Minitest::Spec
214
221
  # ```
215
222
  def self.promote_appium_methods(class_array)
216
- fail 'Driver is nil' if $driver.nil?
223
+ raise 'Driver is nil' if $driver.nil?
217
224
  # Wrap single class into an array
218
225
  class_array = [class_array] unless class_array.class == Array
219
226
  # Promote Appium driver methods to class instance methods.
@@ -239,6 +246,22 @@ module Appium
239
246
  nil # return nil
240
247
  end
241
248
 
249
+ class Driver
250
+ module Capabilities
251
+ # except for browser_name, default capability is equal to ::Selenium::WebDriver::Remote::Capabilities.firefox
252
+ # Because Selenium::WebDriver::Remote::Bridge uses Capabilities.firefox by default
253
+ # https://github.com/SeleniumHQ/selenium/blob/selenium-3.0.1/rb/lib/selenium/webdriver/remote/bridge.rb#L67
254
+ def self.init_caps_for_appium(opts_caps = {})
255
+ default_caps_opts_firefox = {
256
+ javascript_enabled: true,
257
+ takes_screenshot: true,
258
+ css_selectors_enabled: true
259
+ }.merge(opts_caps)
260
+ ::Selenium::WebDriver::Remote::Capabilities.new(default_caps_opts_firefox)
261
+ end
262
+ end
263
+ end
264
+
242
265
  class Driver
243
266
  # attr readers are promoted to global scope. To avoid clobbering, they're
244
267
  # made available via the driver_attributes method
@@ -302,12 +325,12 @@ module Appium
302
325
  def initialize(opts = {})
303
326
  # quit last driver
304
327
  $driver.driver_quit if $driver
305
- fail 'opts must be a hash' unless opts.is_a? Hash
328
+ raise 'opts must be a hash' unless opts.is_a? Hash
306
329
 
307
330
  opts = Appium.symbolize_keys opts
308
331
 
309
- # default to {} to prevent nil.fetch and other nil errors
310
- @caps = opts[:caps] || {}
332
+ @caps = Capabilities.init_caps_for_appium(opts[:caps] || {})
333
+
311
334
  appium_lib_opts = opts[:appium_lib] || {}
312
335
 
313
336
  # appium_lib specific values
@@ -327,7 +350,7 @@ module Appium
327
350
 
328
351
  # Path to the .apk, .app or .app.zip.
329
352
  # The path can be local or remote for Sauce.
330
- if @caps && @caps[:app] && ! @caps[:app].empty?
353
+ if @caps && @caps[:app] && !@caps[:app].empty?
331
354
  @caps[:app] = self.class.absolute_app_path opts
332
355
  end
333
356
 
@@ -351,6 +374,9 @@ module Appium
351
374
  # apply os specific patches
352
375
  patch_webdriver_element
353
376
 
377
+ # for command
378
+ patch_remote_driver_commands
379
+
354
380
  # enable debug patch
355
381
  # !!'constant' == true
356
382
  @appium_debug = appium_lib_opts.fetch :debug, !!defined?(Pry)
@@ -370,17 +396,18 @@ module Appium
370
396
 
371
397
  # Returns a hash of the driver attributes
372
398
  def driver_attributes
373
- attributes = { caps: @caps,
374
- custom_url: @custom_url,
375
- export_session: @export_session,
376
- default_wait: @default_wait,
377
- last_waits: @last_waits,
378
- sauce_username: @sauce_username,
379
- sauce_access_key: @sauce_access_key,
380
- port: @appium_port,
381
- device: @appium_device,
382
- debug: @appium_debug,
383
- listener: @listener
399
+ attributes = {
400
+ caps: @caps,
401
+ custom_url: @custom_url,
402
+ export_session: @export_session,
403
+ default_wait: @default_wait,
404
+ last_waits: @last_waits,
405
+ sauce_username: @sauce_username,
406
+ sauce_access_key: @sauce_access_key,
407
+ port: @appium_port,
408
+ device: @appium_device,
409
+ debug: @appium_debug,
410
+ listener: @listener
384
411
  }
385
412
 
386
413
  # Return duplicates so attributes are immutable
@@ -397,7 +424,7 @@ module Appium
397
424
  # Return true if automationName is 'XCUITest'
398
425
  # @return [Boolean]
399
426
  def automation_name_is_xcuitest?
400
- !@automation_name.nil? && @automation_name.downcase == 'xcuitest'
427
+ !@automation_name.nil? && 'xcuitest'.casecmp(@automation_name).zero?
401
428
  end
402
429
 
403
430
  # Return true if the target Appium server is over REQUIRED_VERSION_XCUITEST.
@@ -405,7 +432,7 @@ module Appium
405
432
  # @return [Boolean]
406
433
  def check_server_version_xcuitest
407
434
  if automation_name_is_xcuitest? && (@appium_server_version['build']['version'] <= REQUIRED_VERSION_XCUITEST)
408
- fail Appium::Error::NotSupportedAppiumServer, "XCUITest requires over Appium #{REQUIRED_VERSION_XCUITEST}"
435
+ raise Appium::Error::NotSupportedAppiumServer, "XCUITest requires over Appium #{REQUIRED_VERSION_XCUITEST}"
409
436
  end
410
437
  true
411
438
  end
@@ -435,33 +462,33 @@ module Appium
435
462
  #
436
463
  # @return [String] APP_PATH as an absolute path
437
464
  def self.absolute_app_path(opts)
438
- fail 'opts must be a hash' unless opts.is_a? Hash
465
+ raise 'opts must be a hash' unless opts.is_a? Hash
439
466
  caps = opts[:caps] || {}
440
467
  appium_lib_opts = opts[:appium_lib] || {}
441
468
  server_url = appium_lib_opts.fetch :server_url, false
442
469
 
443
470
  app_path = caps[:app]
444
- fail 'absolute_app_path invoked and app is not set!' if app_path.nil? || app_path.empty?
471
+ raise 'absolute_app_path invoked and app is not set!' if app_path.nil? || app_path.empty?
445
472
  # may be absolute path to file on remote server.
446
473
  # if the file is on the remote server then we can't check if it exists
447
474
  return app_path if server_url
448
475
  # Sauce storage API. http://saucelabs.com/docs/rest#storage
449
476
  return app_path if app_path.start_with? 'sauce-storage:'
450
- return app_path if app_path.match(/^http/) # public URL for Sauce
451
- if app_path.match(/^(\/|[a-zA-Z]:)/) # absolute file path
477
+ return app_path if app_path =~ /^http/ # public URL for Sauce
478
+ if app_path =~ /^(\/|[a-zA-Z]:)/ # absolute file path
452
479
  app_path = File.expand_path app_path unless File.exist? app_path
453
- fail "App doesn't exist. #{app_path}" unless File.exist? app_path
480
+ raise "App doesn't exist. #{app_path}" unless File.exist? app_path
454
481
  return app_path
455
482
  end
456
483
 
457
484
  # if it doesn't contain a slash then it's a bundle id
458
- return app_path unless app_path.match(/[\/\\]/)
485
+ return app_path unless app_path =~ /[\/\\]/
459
486
 
460
487
  # relative path that must be expanded.
461
488
  # absolute_app_path is called from load_settings
462
489
  # and the txt file path is the base of the app path in that case.
463
490
  app_path = File.expand_path app_path
464
- fail "App doesn't exist #{app_path}" unless File.exist? app_path
491
+ raise "App doesn't exist #{app_path}" unless File.exist? app_path
465
492
  app_path
466
493
  end
467
494
 
@@ -498,8 +525,9 @@ module Appium
498
525
  # @return [void]
499
526
  def driver_quit
500
527
  # rescue NoSuchDriverError or nil driver
501
- # rubocop:disable Style/RescueModifier
502
- @driver.quit rescue nil
528
+ @driver.quit
529
+ rescue
530
+ nil
503
531
  end
504
532
 
505
533
  # Creates a new global driver and quits the old one if it exists.
@@ -621,7 +649,7 @@ module Appium
621
649
  # @param args [*args] the args to use
622
650
  # @return [Array<Element>] Array is empty when no elements are found.
623
651
  def find_elements(*args)
624
- @driver.find_elements(*args)
652
+ @driver.find_elements_with_appium(*args)
625
653
  end
626
654
 
627
655
  # Calls @driver.find_elements
@@ -629,7 +657,7 @@ module Appium
629
657
  # @param args [*args] the args to use
630
658
  # @return [Element]
631
659
  def find_element(*args)
632
- @driver.find_element(*args)
660
+ @driver.find_element_with_appium(*args)
633
661
  end
634
662
 
635
663
  # Calls @driver.set_location
@@ -4,16 +4,16 @@ module Appium
4
4
  # @return [void]
5
5
  def alert_accept
6
6
  # @driver.switch_to.alert.accept
7
- # ".switch_to.alert" calls getAlertText so use bridge directly
8
- driver.send(:bridge).acceptAlert
7
+ # ".switch_to.alert" calls alert_text so use bridge directly
8
+ driver.send(:bridge).accept_alert
9
9
  end
10
10
 
11
11
  # Dismiss the alert.
12
12
  # @return [void]
13
13
  def alert_dismiss
14
14
  # @driver.switch_to.alert.dismiss
15
- # ".switch_to.alert" calls getAlertText so use bridge directly
16
- driver.send(:bridge).dismissAlert
15
+ # ".switch_to.alert" calls alert_text so use bridge directly
16
+ driver.send(:bridge).dismiss_alert
17
17
  end
18
18
  end # module Ios
19
19
  end # module Appium
@@ -65,14 +65,14 @@ module Appium
65
65
  def textfield(value)
66
66
  if value.is_a? Numeric
67
67
  index = value
68
- fail "#{index} is not a valid index. Must be >= 1" if index <= 0
68
+ raise "#{index} is not a valid index. Must be >= 1" if index <= 0
69
69
  index -= 1 # eles_by_json and _textfields_with_xpath is 0 indexed.
70
70
  result = if automation_name_is_xcuitest?
71
71
  _textfields_with_xpath[index]
72
72
  else
73
73
  eles_by_json(_textfield_visible)[index]
74
74
  end
75
- fail _no_such_element if result.nil?
75
+ raise _no_such_element if result.nil?
76
76
  return result
77
77
 
78
78
  end
@@ -116,7 +116,7 @@ module Appium
116
116
  else
117
117
  eles_by_json(_textfield_visible).last
118
118
  end
119
- fail _no_such_element if result.nil?
119
+ raise _no_such_element if result.nil?
120
120
  result
121
121
  end
122
122
 
@@ -0,0 +1,6 @@
1
+ module Appium
2
+ module Ios
3
+ class CommandError < RuntimeError
4
+ end
5
+ end
6
+ end
@@ -14,21 +14,21 @@ module Appium
14
14
 
15
15
  def _print_attr(type, name, label, value, hint)
16
16
  if name == label && name == value
17
- puts "#{type}" if name || label || value || hint
17
+ puts type.to_s if name || label || value || hint
18
18
  puts " name, label, value: #{name}" if name
19
19
  puts " hint: #{hint}" if hint
20
20
  elsif name == label
21
- puts "#{type}" if name || label || value || hint
21
+ puts type.to_s if name || label || value || hint
22
22
  puts " name, label: #{name}" if name
23
23
  puts " value: #{value}" if value
24
24
  puts " hint: #{hint}" if hint
25
25
  elsif name == value
26
- puts "#{type}" if name || label || value || hint
26
+ puts type.to_s if name || label || value || hint
27
27
  puts " name, value: #{name}" if name
28
28
  puts " label: #{label}" if label
29
29
  puts " hint: #{hint}" if hint
30
30
  else
31
- puts "#{type}" if name || label || value || hint
31
+ puts type.to_s if name || label || value || hint
32
32
  puts " name: #{name}" if name
33
33
  puts " label: #{label}" if label
34
34
  puts " value: #{value}" if value
@@ -91,24 +91,24 @@ module Appium
91
91
  # rubocop:disable Metrics/BlockNesting
92
92
 
93
93
  # if class_name is set, mark non-matches as invisible
94
- visible = (type.downcase.include?(class_name)).to_s if class_name
94
+ visible = (type.downcase.include? class_namet).to_s if class_name
95
95
  if visible && visible == 'true'
96
96
  if name == label && name == value
97
- puts "#{type}" if name || label || value || hint
97
+ puts type.to_s if name || label || value || hint
98
98
  puts " name, label, value: #{name}" if name
99
99
  puts " hint: #{hint}" if hint
100
100
  elsif name == label
101
- puts "#{type}" if name || label || value || hint
101
+ puts type.to_s if name || label || value || hint
102
102
  puts " name, label: #{name}" if name
103
103
  puts " value: #{value}" if value
104
104
  puts " hint: #{hint}" if hint
105
105
  elsif name == value
106
- puts "#{type}" if name || label || value || hint
106
+ puts type.to_s if name || label || value || hint
107
107
  puts " name, value: #{name}" if name
108
108
  puts " label: #{label}" if label
109
109
  puts " hint: #{hint}" if hint
110
110
  else
111
- puts "#{type}" if name || label || value || hint
111
+ puts type.to_s if name || label || value || hint
112
112
  puts " name: #{name}" if name
113
113
  puts " label: #{label}" if label
114
114
  puts " value: #{value}" if value
@@ -236,7 +236,7 @@ module Appium
236
236
  # @param index [Integer] the index
237
237
  # @return [Element]
238
238
  def ele_index(class_name, index)
239
- fail 'Index must be >= 1' unless index == 'last()' || (index.is_a?(Integer) && index >= 1)
239
+ raise 'Index must be >= 1' unless index == 'last()' || (index.is_a?(Integer) && index >= 1)
240
240
  elements = tags(class_name)
241
241
 
242
242
  if index == 'last()'
@@ -247,7 +247,7 @@ module Appium
247
247
  result = elements[index]
248
248
  end
249
249
 
250
- fail _no_such_element if result.nil?
250
+ raise _no_such_element if result.nil?
251
251
  result
252
252
  end
253
253
 
@@ -334,7 +334,7 @@ module Appium
334
334
  def last_ele(class_name)
335
335
  if automation_name_is_xcuitest?
336
336
  result = @driver.find_elements :xpath, "(//#{class_name})"
337
- fail _no_such_element if result.empty?
337
+ raise _no_such_element if result.empty?
338
338
  result.last
339
339
  else
340
340
  ele_index class_name, 'last()'
@@ -469,7 +469,7 @@ module Appium
469
469
  #
470
470
  # Don't use window.tap. See https://github.com/appium/appium-uiauto/issues/28
471
471
  #
472
- dismiss_keyboard = (<<-JS).strip
472
+ dismiss_keyboard = <<-JS.strip
473
473
  if (!au.mainApp().keyboard().isNil()) {
474
474
  var key = au.mainApp().keyboard().buttons()['#{close_key}']
475
475
  if (key.isNil()) {
@@ -509,7 +509,7 @@ module Appium
509
509
  #
510
510
  def _all_pred(opts)
511
511
  predicate = opts[:predicate]
512
- fail 'predicate must be provided' unless predicate
512
+ raise 'predicate must be provided' unless predicate
513
513
  visible = opts.fetch :visible, true
514
514
  %($.mainApp().getAllWithPredicate("#{predicate}", #{visible});)
515
515
  end
@@ -542,22 +542,22 @@ module Appium
542
542
  end
543
543
 
544
544
  def _validate_object(*objects)
545
- fail 'objects must be an array' unless objects.is_a? Array
545
+ raise 'objects must be an array' unless objects.is_a? Array
546
546
  objects.each do |obj|
547
547
  next unless obj # obj may be nil. if so, ignore.
548
548
 
549
549
  valid_keys = [:target, :substring, :insensitive]
550
550
  unknown_keys = obj.keys - valid_keys
551
- fail "Unknown keys: #{unknown_keys}" unless unknown_keys.empty?
551
+ raise "Unknown keys: #{unknown_keys}" unless unknown_keys.empty?
552
552
 
553
553
  target = obj[:target]
554
- fail 'target must be a string' unless target.is_a? String
554
+ raise 'target must be a string' unless target.is_a? String
555
555
 
556
556
  substring = obj[:substring]
557
- fail 'substring must be a boolean' unless [true, false].include? substring
557
+ raise 'substring must be a boolean' unless [true, false].include? substring
558
558
 
559
559
  insensitive = obj[:insensitive]
560
- fail 'insensitive must be a boolean' unless [true, false].include? insensitive
560
+ raise 'insensitive must be a boolean' unless [true, false].include? insensitive
561
561
  end
562
562
  end
563
563
 
@@ -593,16 +593,16 @@ module Appium
593
593
  def _by_json(opts)
594
594
  valid_keys = [:typeArray, :onlyFirst, :onlyVisible, :name, :label, :value]
595
595
  unknown_keys = opts.keys - valid_keys
596
- fail "Unknown keys: #{unknown_keys}" unless unknown_keys.empty?
596
+ raise "Unknown keys: #{unknown_keys}" unless unknown_keys.empty?
597
597
 
598
598
  type_array = opts[:typeArray]
599
- fail 'typeArray must be an array' unless type_array.is_a? Array
599
+ raise 'typeArray must be an array' unless type_array.is_a? Array
600
600
 
601
601
  only_first = opts[:onlyFirst]
602
- fail 'onlyFirst must be a boolean' unless [true, false].include? only_first
602
+ raise 'onlyFirst must be a boolean' unless [true, false].include? only_first
603
603
 
604
604
  only_visible = opts[:onlyVisible]
605
- fail 'onlyVisible must be a boolean' unless [true, false].include? only_visible
605
+ raise 'onlyVisible must be a boolean' unless [true, false].include? only_visible
606
606
 
607
607
  # name/label/value are optional. when searching for class only, then none
608
608
  # will be present.
@@ -625,7 +625,7 @@ module Appium
625
625
  JS
626
626
 
627
627
  res = execute_script element_or_elements_by_type
628
- res ? res : fail(Selenium::Client::CommandError, 'mainWindow is nil')
628
+ res ? res : raise(Appium::Ios::CommandError, 'mainWindow is nil')
629
629
  end
630
630
 
631
631
  # For Appium(automation name), not XCUITest
@@ -649,7 +649,7 @@ module Appium
649
649
  def ele_by_json(opts)
650
650
  opts[:onlyFirst] = true
651
651
  result = _by_json(opts).first
652
- fail _no_such_element if result.nil?
652
+ raise _no_such_element if result.nil?
653
653
  result
654
654
  end
655
655