appium_lib 9.7.5 → 9.8.1

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/appium_lib.gemspec +1 -3
  4. data/contributing.md +2 -0
  5. data/docs/android_docs.md +186 -180
  6. data/docs/ios_docs.md +238 -234
  7. data/docs/ios_xcuitest.md +1 -1
  8. data/lib/appium_lib/android/common/helper.rb +0 -30
  9. data/lib/appium_lib/appium.rb +3 -4
  10. data/lib/appium_lib/common/helper.rb +0 -1
  11. data/lib/appium_lib/common/http_client.rb +1 -1
  12. data/lib/appium_lib/common/touch_actions.rb +4 -4
  13. data/lib/appium_lib/common/wait.rb +1 -1
  14. data/lib/appium_lib/driver.rb +7 -8
  15. data/lib/appium_lib/ios/common/helper.rb +1 -8
  16. data/lib/appium_lib/version.rb +2 -2
  17. data/readme.md +29 -8
  18. data/release_notes.md +6 -0
  19. metadata +5 -77
  20. data/lib/appium_lib/core/android.rb +0 -5
  21. data/lib/appium_lib/core/android/device.rb +0 -142
  22. data/lib/appium_lib/core/android/espresso/bridge.rb +0 -18
  23. data/lib/appium_lib/core/android/search_context.rb +0 -17
  24. data/lib/appium_lib/core/android/touch.rb +0 -15
  25. data/lib/appium_lib/core/android/uiautomator1/bridge.rb +0 -18
  26. data/lib/appium_lib/core/android/uiautomator2/bridge.rb +0 -18
  27. data/lib/appium_lib/core/android_espresso.rb +0 -5
  28. data/lib/appium_lib/core/android_uiautomator2.rb +0 -5
  29. data/lib/appium_lib/core/common.rb +0 -6
  30. data/lib/appium_lib/core/common/base.rb +0 -8
  31. data/lib/appium_lib/core/common/base/bridge.rb +0 -47
  32. data/lib/appium_lib/core/common/base/capabilities.rb +0 -16
  33. data/lib/appium_lib/core/common/base/command.rb +0 -10
  34. data/lib/appium_lib/core/common/base/driver.rb +0 -40
  35. data/lib/appium_lib/core/common/base/http_default.rb +0 -12
  36. data/lib/appium_lib/core/common/base/search_context.rb +0 -89
  37. data/lib/appium_lib/core/common/base/wait.rb +0 -56
  38. data/lib/appium_lib/core/common/command.rb +0 -75
  39. data/lib/appium_lib/core/common/device.rb +0 -462
  40. data/lib/appium_lib/core/common/error.rb +0 -18
  41. data/lib/appium_lib/core/common/log.rb +0 -30
  42. data/lib/appium_lib/core/common/logger.rb +0 -35
  43. data/lib/appium_lib/core/core.rb +0 -67
  44. data/lib/appium_lib/core/device/multi_touch.rb +0 -48
  45. data/lib/appium_lib/core/device/touch_actions.rb +0 -191
  46. data/lib/appium_lib/core/driver.rb +0 -417
  47. data/lib/appium_lib/core/ios.rb +0 -7
  48. data/lib/appium_lib/core/ios/device.rb +0 -44
  49. data/lib/appium_lib/core/ios/search_context.rb +0 -27
  50. data/lib/appium_lib/core/ios/touch.rb +0 -16
  51. data/lib/appium_lib/core/ios/uiautomation/bridge.rb +0 -20
  52. data/lib/appium_lib/core/ios/uiautomation/patch.rb +0 -20
  53. data/lib/appium_lib/core/ios/xcuitest/bridge.rb +0 -20
  54. data/lib/appium_lib/core/ios/xcuitest/device.rb +0 -59
  55. data/lib/appium_lib/core/ios/xcuitest/search_context.rb +0 -40
  56. data/lib/appium_lib/core/ios_xcuitest.rb +0 -8
  57. data/lib/appium_lib/core/patch.rb +0 -56
@@ -1,18 +0,0 @@
1
- require_relative '../../android_espresso'
2
-
3
- module Appium
4
- module Core
5
- module Android
6
- module Espresso
7
- module Bridge
8
- def self.for(target)
9
- target.extend Appium::Android::Device
10
- Core::Android::SearchContext.extend
11
-
12
- Core::Android::Touch.extend_touch_actions
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,17 +0,0 @@
1
- module Appium
2
- module Core
3
- module Android
4
- module SearchContext
5
- # @!method uiautomator_find
6
- # find_element/s can be used with a [UISelector](http://developer.android.com/tools/help/uiautomator/UiSelector.html).
7
- #
8
- # ```ruby
9
- # find_elements :uiautomator, 'new UiSelector().clickable(true)'
10
- # ```
11
- def self.extend
12
- ::Appium::Core::Base::SearchContext.add_finders(uiautomator: '-android uiautomator')
13
- end
14
- end # class << self
15
- end # module Ios
16
- end # module Core
17
- end # module Appium
@@ -1,15 +0,0 @@
1
- module Appium
2
- module Core
3
- module Android
4
- module Touch
5
- def self.extend_touch_actions
6
- ::Appium::Core::TouchAction.class_eval do
7
- def swipe_coordinates(start_x: 0, start_y: 0, offset_x: 0, offset_y: 0)
8
- { offset_x: (start_x + offset_x), offset_y: (start_y + offset_y) }
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,18 +0,0 @@
1
- require_relative '../../android'
2
-
3
- module Appium
4
- module Core
5
- module Android
6
- module Uiautomator1
7
- module Bridge
8
- def self.for(target)
9
- target.extend Appium::Android::Device
10
- Core::Android::SearchContext.extend
11
-
12
- Core::Android::Touch.extend_touch_actions
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,18 +0,0 @@
1
- require_relative '../../android_uiautomator2'
2
-
3
- module Appium
4
- module Core
5
- module Android
6
- module Uiautomator2
7
- module Bridge
8
- def self.for(target)
9
- target.extend Appium::Android::Device
10
- Core::Android::SearchContext.extend
11
-
12
- Core::Android::Touch.extend_touch_actions
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,5 +0,0 @@
1
- # loaded in common/driver.rb
2
- require_relative 'android/search_context'
3
- require_relative 'android/device'
4
- require_relative 'android/touch'
5
- require_relative 'android/espresso/bridge'
@@ -1,5 +0,0 @@
1
- # loaded in common/driver.rb
2
- require_relative 'android/search_context'
3
- require_relative 'android/device'
4
- require_relative 'android/touch'
5
- require_relative 'android/uiautomator2/bridge'
@@ -1,6 +0,0 @@
1
- require_relative 'common/logger'
2
- require_relative 'common/error'
3
- require_relative 'common/log'
4
- require_relative 'common/command'
5
- require_relative 'common/device'
6
- require_relative 'common/base'
@@ -1,8 +0,0 @@
1
- # The following files have selenium-webdriver related stuff.
2
- require_relative 'base/driver'
3
- require_relative 'base/bridge'
4
- require_relative 'base/capabilities'
5
- require_relative 'base/http_default'
6
- require_relative 'base/search_context'
7
- require_relative 'base/command'
8
- require_relative 'base/wait'
@@ -1,47 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- class Bridge < ::Selenium::WebDriver::Remote::Bridge
5
- def self.handshake(**opts)
6
- desired_capabilities = opts.delete(:desired_capabilities)
7
-
8
- if desired_capabilities.is_a?(Symbol)
9
- unless Remote::Capabilities.respond_to?(desired_capabilities)
10
- raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
11
- end
12
- desired_capabilities = Remote::Capabilities.__send__(desired_capabilities)
13
- end
14
-
15
- bridge = new(opts)
16
- capabilities = bridge.create_session(desired_capabilities)
17
-
18
- case bridge.dialect
19
- when :oss
20
- CoreBridgeOSS.new(capabilities, bridge.session_id, opts)
21
- when :w3c
22
- CoreBridgeW3C.new(capabilities, bridge.session_id, opts)
23
- else
24
- raise CoreError, 'cannot understand dialect'
25
- end
26
- end
27
- end # class Bridge
28
-
29
- class CoreBridgeOSS < ::Selenium::WebDriver::Remote::OSS::Bridge
30
- def commands(command)
31
- ::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
32
- end
33
- end # class CoreBridgeOSS
34
-
35
- class CoreBridgeW3C < ::Selenium::WebDriver::Remote::W3C::Bridge
36
- def commands(command)
37
- case command
38
- when :status, :is_element_displayed
39
- ::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
40
- else
41
- ::Appium::Core::Commands::COMMANDS_EXTEND_W3C[command]
42
- end
43
- end
44
- end # class CoreBridgeW3C
45
- end # class Base
46
- end # module Core
47
- end # module Appium
@@ -1,16 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- module Capabilities
5
- # @private
6
- # @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
7
- # this client sends capabilities to Appium server as JSON format.
8
- # @return [::Selenium::WebDriver::Remote::W3C::Capabilities] Return instance of Appium::Core::Base::Capabilities
9
- # inherited ::Selenium::WebDriver::Remote::W3C::Capabilities
10
- def self.create_capabilities(opts_caps = {})
11
- ::Selenium::WebDriver::Remote::W3C::Capabilities.new(opts_caps)
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,10 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- module Commands
5
- OSS = ::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS.freeze
6
- W3C = ::Selenium::WebDriver::Remote::W3C::Bridge::COMMANDS.freeze
7
- end # module Commands
8
- end # module Base
9
- end # module Core
10
- end # module Appium
@@ -1,40 +0,0 @@
1
- require_relative 'search_context'
2
-
3
- module Appium
4
- module Core
5
- class Base
6
- class Driver < ::Selenium::WebDriver::Driver
7
- include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
8
- include ::Selenium::WebDriver::DriverExtensions::TakesScreenshot
9
- include ::Selenium::WebDriver::DriverExtensions::HasSessionId
10
- include ::Selenium::WebDriver::DriverExtensions::Rotatable
11
- include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
12
- include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
13
-
14
- include ::Appium::Core::Base::SearchContext
15
-
16
- def initialize(opts = {})
17
- listener = opts.delete(:listener)
18
- @bridge = ::Appium::Core::Base::Bridge.handshake(opts)
19
- if @bridge.dialect == :oss
20
- extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
21
- extend ::Selenium::WebDriver::DriverExtensions::HasLocation
22
- extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
23
- end
24
- super(@bridge, listener: listener)
25
- end
26
-
27
- # Get the device window's size.
28
- # @return [Selenium::WebDriver::Dimension]
29
- #
30
- # @example
31
- # size = @driver.window_size
32
- # size.width #=> Integer
33
- # size.height #=> Integer
34
- def window_size
35
- manage.window.size
36
- end
37
- end # class Driver
38
- end # class Base
39
- end # module Core
40
- end # module Appium
@@ -1,12 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- module Http
5
- class Default < Selenium::WebDriver::Remote::Http::Default
6
- # TODO: when divide the core to the other gem, then update here. appium/ruby_lib_core/#{version}
7
- DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => 'appium/ruby_lib_core/0.0.0' }.freeze
8
- end
9
- end
10
- end
11
- end
12
- end
@@ -1,89 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- module SearchContext
5
- # referenced: ::Selenium::WebDriver::SearchContext
6
-
7
- FINDERS = ::Selenium::WebDriver::SearchContext::FINDERS.merge(accessibility_id: 'accessibility id')
8
-
9
- def self.add_finders(finders)
10
- FINDERS.merge!(finders)
11
- end
12
-
13
- #
14
- # Find the first element matching the given arguments
15
- #
16
- # @overload find_element(how, what)
17
- # @param [Symbol, String] how The method to find the element by
18
- # @param [String] what The locator to use
19
- # @overload find_element(opts)
20
- # @param [Hash] opts Find options
21
- # @option opts [Symbol] :how Key named after the method to find the element by, containing the locator
22
- # @return [Element]
23
- #
24
- # @raise [Error::NoSuchElementError] if the element doesn't exist
25
- #
26
- # @example Find element with accessibility id
27
- # find_elements :accessibility_id, 'Animation'
28
- # find_elements :accessibility_id, 'Animation'
29
- #
30
- def find_element(*args)
31
- how, what = extract_args(args)
32
- by = _set_by_from_finders(how)
33
- begin
34
- bridge.find_element_by by, what.to_s, ref
35
- rescue Selenium::WebDriver::Error::TimeOutError
36
- raise Selenium::WebDriver::Error::NoSuchElementError
37
- end
38
- end
39
-
40
- #
41
- # Find all elements matching the given arguments
42
- #
43
- # @see SearchContext#find_element
44
- #
45
- def find_elements(*args)
46
- how, what = extract_args(args)
47
- by = _set_by_from_finders(how)
48
- begin
49
- bridge.find_elements_by by, what.to_s, ref
50
- rescue Selenium::WebDriver::Error::TimeOutError
51
- raise Selenium::WebDriver::Error::NoSuchElementError
52
- end
53
- end
54
-
55
- private
56
-
57
- def _set_by_from_finders(how)
58
- finders = FINDERS
59
- by = finders[how.to_sym]
60
- raise ArgumentError, "cannot find element by #{how.inspect}" unless by
61
- by
62
- end
63
-
64
- def extract_args(args)
65
- case args.size
66
- when 2
67
- args
68
- when 1
69
- arg = args.first
70
-
71
- unless arg.respond_to?(:shift)
72
- raise ArgumentError, "expected #{arg.inspect}:#{arg.class} to respond to #shift"
73
- end
74
-
75
- # this will be a single-entry hash, so use #shift over #first or #[]
76
- arr = arg.dup.shift
77
- unless arr.size == 2
78
- raise ArgumentError, "expected #{arr.inspect} to have 2 elements"
79
- end
80
-
81
- arr
82
- else
83
- raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
84
- end
85
- end
86
- end # module SearchContext
87
- end # class Base
88
- end # module Core
89
- end # module Appium
@@ -1,56 +0,0 @@
1
- module Appium
2
- module Core
3
- class Base
4
- class Wait < ::Selenium::WebDriver::Wait
5
- require 'timeout' # for wait
6
-
7
- def initialize(opts = {})
8
- valid_keys = [:timeout, :interval, :message, :ignore, :return_if_true]
9
- invalid_keys = []
10
- opts.keys.each { |key| invalid_keys << key unless valid_keys.include?(key) }
11
- # [:one, :two] => :one, :two
12
- unless invalid_keys.empty?
13
- raise "Invalid keys #{invalid_keys.to_s[1..-2]}. Valid keys are #{valid_keys.to_s[1..-2]}"
14
- end
15
-
16
- @timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
17
- @interval = opts.fetch(:interval, DEFAULT_INTERVAL)
18
- @message = opts[:message]
19
- @ignored = Array(opts[:ignore] || ::Exception)
20
- @return_if_true = opts[:return_if_true]
21
-
22
- super(timeout: @timeout, interval: @interval, message: @message, ignore: @ignored)
23
- end
24
-
25
- # Wait code from the selenium Ruby gem
26
- # https://github.com/SeleniumHQ/selenium/blob/cf501dda3f0ed12233de51ce8170c0e8090f0c20/rb/lib/selenium/webdriver/common/wait.rb
27
- # @override
28
- def until
29
- end_time = Time.now + @timeout
30
- last_error = nil
31
-
32
- until Time.now > end_time
33
- begin
34
- return yield unless @return_if_true
35
-
36
- result = yield
37
- return result if result
38
- rescue ::Errno::ECONNREFUSED => e
39
- raise e
40
- rescue *@ignored => last_error # rubocop:disable Lint/HandleExceptions
41
- # swallowed
42
- end
43
-
44
- sleep @interval
45
- end
46
-
47
- msg = @message ? @message.dup : "timed out after #{@timeout} seconds"
48
-
49
- msg << " (#{last_error.message})" if last_error
50
-
51
- raise Selenium::WebDriver::Error::TimeOutError, msg
52
- end
53
- end # module Wait
54
- end # module Base
55
- end # module Core
56
- end # module Appium
@@ -1,75 +0,0 @@
1
- require_relative 'base/command'
2
-
3
- module Appium
4
- module Core
5
- # ref: https://github.com/appium/appium-base-driver/blob/master/lib/mjsonwp/routes.js
6
- module Commands
7
- COMMAND_NO_ARG = {
8
- # Common
9
- shake: [:post, 'session/:session_id/appium/device/shake'.freeze],
10
- launch_app: [:post, 'session/:session_id/appium/app/launch'.freeze],
11
- close_app: [:post, 'session/:session_id/appium/app/close'.freeze],
12
- reset: [:post, 'session/:session_id/appium/app/reset'.freeze],
13
- device_locked?: [:post, 'session/:session_id/appium/device/is_locked'.freeze],
14
- unlock: [:post, 'session/:session_id/appium/device/unlock'.freeze],
15
- device_time: [:get, 'session/:session_id/appium/device/system_time'.freeze],
16
- current_context: [:get, 'session/:session_id/context'.freeze],
17
-
18
- # Android
19
- open_notifications: [:post, 'session/:session_id/appium/device/open_notifications'.freeze],
20
- toggle_airplane_mode: [:post, 'session/:session_id/appium/device/toggle_airplane_mode'.freeze],
21
- current_activity: [:get, 'session/:session_id/appium/device/current_activity'.freeze],
22
- current_package: [:get, 'session/:session_id/appium/device/current_package'.freeze],
23
- get_system_bars: [:get, 'session/:session_id/appium/device/system_bars'.freeze],
24
- get_display_density: [:get, 'session/:session_id/appium/device/display_density'.freeze],
25
- is_keyboard_shown: [:get, 'session/:session_id/appium/device/is_keyboard_shown'.freeze],
26
- get_network_connection: [:get, 'session/:session_id/network_connection'.freeze],
27
- get_performance_data_types: [:post, 'session/:session_id/appium/performanceData/types'.freeze],
28
-
29
- # iOS
30
- }.freeze
31
-
32
- # Some commands differ for each driver.
33
- COMMAND = {
34
- # common
35
- available_contexts: [:get, 'session/:session_id/contexts'.freeze],
36
- set_context: [:post, 'session/:session_id/context'.freeze],
37
- app_strings: [:post, 'session/:session_id/appium/app/strings'.freeze],
38
- lock: [:post, 'session/:session_id/appium/device/lock'.freeze],
39
- install_app: [:post, 'session/:session_id/appium/device/install_app'.freeze],
40
- remove_app: [:post, 'session/:session_id/appium/device/remove_app'.freeze],
41
- app_installed?: [:post, 'session/:session_id/appium/device/app_installed'.freeze],
42
- background_app: [:post, 'session/:session_id/appium/app/background'.freeze],
43
- hide_keyboard: [:post, 'session/:session_id/appium/device/hide_keyboard'.freeze],
44
- press_keycode: [:post, 'session/:session_id/appium/device/press_keycode'.freeze],
45
- long_press_keycode: [:post, 'session/:session_id/appium/device/long_press_keycode'.freeze],
46
- set_immediate_value: [:post, 'session/:session_id/appium/element/:id/value'.freeze],
47
- push_file: [:post, 'session/:session_id/appium/device/push_file'.freeze],
48
- pull_file: [:post, 'session/:session_id/appium/device/pull_file'.freeze],
49
- pull_folder: [:post, 'session/:session_id/appium/device/pull_folder'.freeze],
50
- get_settings: [:get, 'session/:session_id/appium/settings'.freeze],
51
- update_settings: [:post, 'session/:session_id/appium/settings'.freeze],
52
- touch_actions: [:post, 'session/:session_id/touch/perform'.freeze],
53
- multi_touch: [:post, 'session/:session_id/touch/multi/perform'.freeze]
54
- }.freeze
55
-
56
- COMMAND_ANDROID = {
57
- start_activity: [:post, 'session/:session_id/appium/device/start_activity'.freeze],
58
- end_coverage: [:post, 'session/:session_id/appium/app/end_test_coverage'.freeze],
59
- set_network_connection: [:post, 'session/:session_id/network_connection'.freeze],
60
- get_performance_data: [:post, 'session/:session_id/appium/getPerformanceData'.freeze]
61
- }.freeze
62
-
63
- COMMAND_IOS = {
64
- touch_id: [:post, 'session/:session_id/appium/simulator/touch_id'.freeze],
65
- toggle_touch_id_enrollment: [:post, 'session/:session_id/appium/simulator/toggle_touch_id_enrollment'.freeze]
66
- }.freeze
67
-
68
- COMMANDS = {}.merge(COMMAND).merge(COMMAND_ANDROID).merge(COMMAND_IOS)
69
- .merge(COMMAND_NO_ARG).freeze
70
-
71
- COMMANDS_EXTEND_OSS = COMMANDS.merge(::Appium::Core::Base::Commands::OSS).freeze
72
- COMMANDS_EXTEND_W3C = COMMANDS.merge(::Appium::Core::Base::Commands::W3C).freeze
73
- end
74
- end
75
- end