appium_lib_core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +20 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +202 -0
  8. data/README.md +5 -0
  9. data/Rakefile +62 -0
  10. data/Thorfile +7 -0
  11. data/appium_lib_core.gemspec +35 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/appium_lib_core.rb +41 -0
  15. data/lib/appium_lib_core/android.rb +5 -0
  16. data/lib/appium_lib_core/android/device.rb +174 -0
  17. data/lib/appium_lib_core/android/espresso/bridge.rb +16 -0
  18. data/lib/appium_lib_core/android/search_context.rb +18 -0
  19. data/lib/appium_lib_core/android/touch.rb +17 -0
  20. data/lib/appium_lib_core/android/uiautomator1/bridge.rb +16 -0
  21. data/lib/appium_lib_core/android/uiautomator2/bridge.rb +16 -0
  22. data/lib/appium_lib_core/android_espresso.rb +5 -0
  23. data/lib/appium_lib_core/android_uiautomator2.rb +5 -0
  24. data/lib/appium_lib_core/common.rb +6 -0
  25. data/lib/appium_lib_core/common/base.rb +8 -0
  26. data/lib/appium_lib_core/common/base/bridge.rb +47 -0
  27. data/lib/appium_lib_core/common/base/capabilities.rb +16 -0
  28. data/lib/appium_lib_core/common/base/command.rb +10 -0
  29. data/lib/appium_lib_core/common/base/driver.rb +51 -0
  30. data/lib/appium_lib_core/common/base/http_default.rb +13 -0
  31. data/lib/appium_lib_core/common/base/search_context.rb +89 -0
  32. data/lib/appium_lib_core/common/base/wait.rb +56 -0
  33. data/lib/appium_lib_core/common/command.rb +77 -0
  34. data/lib/appium_lib_core/common/device.rb +567 -0
  35. data/lib/appium_lib_core/common/error.rb +18 -0
  36. data/lib/appium_lib_core/common/log.rb +30 -0
  37. data/lib/appium_lib_core/common/logger.rb +30 -0
  38. data/lib/appium_lib_core/device/multi_touch.rb +48 -0
  39. data/lib/appium_lib_core/device/touch_actions.rb +191 -0
  40. data/lib/appium_lib_core/driver.rb +459 -0
  41. data/lib/appium_lib_core/ios.rb +7 -0
  42. data/lib/appium_lib_core/ios/device.rb +54 -0
  43. data/lib/appium_lib_core/ios/search_context.rb +27 -0
  44. data/lib/appium_lib_core/ios/touch.rb +17 -0
  45. data/lib/appium_lib_core/ios/uiautomation/bridge.rb +18 -0
  46. data/lib/appium_lib_core/ios/uiautomation/patch.rb +20 -0
  47. data/lib/appium_lib_core/ios/xcuitest/bridge.rb +18 -0
  48. data/lib/appium_lib_core/ios/xcuitest/device.rb +66 -0
  49. data/lib/appium_lib_core/ios/xcuitest/search_context.rb +40 -0
  50. data/lib/appium_lib_core/ios_xcuitest.rb +8 -0
  51. data/lib/appium_lib_core/patch.rb +78 -0
  52. data/lib/appium_lib_core/version.rb +6 -0
  53. data/release_notes.md +0 -0
  54. metadata +262 -0
@@ -0,0 +1,5 @@
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/uiautomator1/bridge'
@@ -0,0 +1,174 @@
1
+ module Appium
2
+ module Android
3
+ module Device
4
+ extend Forwardable
5
+
6
+ # @!method hide_keyboard(close_key = nil, strategy = nil)
7
+ # Hide the onscreen keyboard
8
+ # @param [String] close_key The name of the key which closes the keyboard.
9
+ # Defaults to 'Done' for iOS(except for XCUITest).
10
+ # @param [Symbol] strategy The symbol of the strategy which closes the keyboard.
11
+ # XCUITest ignore this argument.
12
+ # Default for iOS is `:pressKey`. Default for Android is `:tapOutside`.
13
+ #
14
+ # @example
15
+ #
16
+ # @driver.hide_keyboard # Close a keyboard with the 'Done' button
17
+ # @driver.hide_keyboard('Finished') # Close a keyboard with the 'Finished' button
18
+ # @driver.hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
19
+ #
20
+
21
+ # @!method end_coverage(path, intent)
22
+ # Android only; Ends the test coverage and writes the results to the given path on device.
23
+ # @param [String] path Path on the device to write too.
24
+ # @param [String] intent Intent to broadcast when ending coverage.
25
+ #
26
+
27
+ # @!method start_activity(opts)
28
+ # Android only. Start a new activity within the current app or launch a new app and start the target activity.
29
+ #
30
+ # @option [String] The package owning the activity [required]
31
+ # @option [String] The target activity [required]
32
+ # @option opts [String] The package to start before the target package [optional]
33
+ # @option opts [String] The activity to start before the target activity [optional]
34
+ #
35
+ # @example
36
+ #
37
+ # start_activity app_package: 'io.appium.android.apis',
38
+ # app_activity: '.accessibility.AccessibilityNodeProviderActivity'
39
+ #
40
+
41
+ # @!method set_network_connection(mode)
42
+ # Set the device network connection mode
43
+ # @param [String] mode Bit mask that represent the network mode
44
+ #
45
+ # Value (Alias) | Data | Wifi | Airplane Mode
46
+ # -------------------------------------------------
47
+ # 1 (Airplane Mode) | 0 | 0 | 1
48
+ # 6 (All network on) | 1 | 1 | 0
49
+ # 4 (Data only) | 1 | 0 | 0
50
+ # 2 (Wifi only) | 0 | 1 | 0
51
+ # 0 (None) | 0 | 0 | 0
52
+ #
53
+ # @example
54
+ #
55
+ # @driver.set_network_connection 1
56
+ #
57
+
58
+ # @!method get_performance_data_types
59
+ # Get the information type of the system state which is supported to read such as
60
+ # cpu, memory, network, battery via adb commands.
61
+ # https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L300
62
+ #
63
+ # @example
64
+ #
65
+ # @driver.get_performance_data_types #=> ["cpuinfo", "batteryinfo", "networkinfo", "memoryinfo"]
66
+ #
67
+
68
+ # @!method get_performance_data(package_name:, data_type:, data_read_timeout: 1000)
69
+ # Get the resource usage information of the application.
70
+ # https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L303
71
+ # @param [String] package_name Package name
72
+ # @param [String] data_type Data type get with `get_performance_data_types`
73
+ # @param [String] data_read_timeout Command timeout. Default is 2.
74
+ #
75
+ # @example
76
+ #
77
+ # @driver.get_performance_data package_name: package_name, data_type: data_type, data_read_timeout: 2
78
+ #
79
+
80
+ # @!method start_recording_screen(package_name:, data_type:, data_read_timeout: 1000)
81
+ # Record the display of devices running Android 4.4 (API level 19) and higher.
82
+ # It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.
83
+ # @param [String] file_path A path to save the video. `/sdcard/default.mp4` is by default.
84
+ # @param [String] video_size A video size. '1280x720' is by default.
85
+ # @param [String] time_limit Recording time. 180 second is by default.
86
+ # @param [String] bit_rate The video bit rate for the video, in megabits per second. 3000000(3Mbps) is by default.
87
+ #
88
+ # @example
89
+ #
90
+ # @driver.start_recording_screen(file_path: '/sdcard/default.mp4', video_size: '1280x720',
91
+ # time_limit: '180', bit_rate: '3000000')
92
+ #
93
+
94
+ # @!method stop_recording_screen
95
+ # Stop recording the screen.
96
+ #
97
+ # @example
98
+ #
99
+ # @driver.stop_recording_screen
100
+ #
101
+
102
+ ####
103
+ ## class << self
104
+ ####
105
+
106
+ class << self
107
+ def extended(_mod)
108
+ Appium::Core::Device.extend_webdriver_with_forwardable
109
+
110
+ # Android
111
+ Appium::Core::Device.add_endpoint_method(:start_activity) do
112
+ def start_activity(opts)
113
+ raise 'opts must be a hash' unless opts.is_a? Hash
114
+ app_package = opts[:app_package]
115
+ raise 'app_package is required' unless app_package
116
+ app_activity = opts[:app_activity]
117
+ raise 'app_activity is required' unless app_activity
118
+ app_wait_package = opts.fetch(:app_wait_package, '')
119
+ app_wait_activity = opts.fetch(:app_wait_activity, '')
120
+
121
+ unknown_opts = opts.keys - [:app_package, :app_activity, :app_wait_package, :app_wait_activity]
122
+ raise "Unknown options #{unknown_opts}" unless unknown_opts.empty?
123
+
124
+ execute :start_activity, {}, appPackage: app_package,
125
+ appActivity: app_activity,
126
+ appWaitPackage: app_wait_package,
127
+ appWaitActivity: app_wait_activity
128
+ end
129
+ end
130
+
131
+ # Android, Override
132
+ Appium::Core::Device.add_endpoint_method(:hide_keyboard) do
133
+ def hide_keyboard(close_key = nil, strategy = nil)
134
+ option = {}
135
+
136
+ option[:key] = close_key if close_key
137
+ option[:strategy] = strategy || :tapOutside # default to pressKey
138
+
139
+ execute :hide_keyboard, {}, option
140
+ end
141
+ end
142
+
143
+ # TODO: TEST ME
144
+ Appium::Core::Device.add_endpoint_method(:end_coverage) do
145
+ def end_coverage(path, intent)
146
+ execute :end_coverage, {}, path: path, intent: intent
147
+ end
148
+ end
149
+
150
+ Appium::Core::Device.add_endpoint_method(:set_network_connection) do
151
+ def set_network_connection(mode)
152
+ execute :set_network_connection, {}, type: mode
153
+ end
154
+ end
155
+
156
+ Appium::Core::Device.add_endpoint_method(:get_performance_data) do
157
+ def get_performance_data(package_name:, data_type:, data_read_timeout: 1000)
158
+ execute(:get_performance_data, {},
159
+ packageName: package_name, dataType: data_type, dataReadTimeout: data_read_timeout)
160
+ end
161
+ end
162
+
163
+ Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
164
+ def start_recording_screen(file_path: '/sdcard/default.mp4', video_size: '1280x720',
165
+ time_limit: '180', bit_rate: '3000000')
166
+ execute(:start_recording_screen, {},
167
+ filePath: file_path, videoSize: video_size, timeLimit: time_limit, bitRate: bit_rate)
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end # module Device
173
+ end # module Android
174
+ end # module Appium
@@ -0,0 +1,16 @@
1
+ module Appium
2
+ module Core
3
+ module Android
4
+ module Espresso
5
+ module Bridge
6
+ def self.for(target)
7
+ target.extend Appium::Android::Device
8
+ Core::Android::SearchContext.extend
9
+
10
+ Core::Android::Touch.extend_touch_actions
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
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
+ # @example
9
+ #
10
+ # @driver.find_elements :uiautomator, 'new UiSelector().clickable(true)'
11
+ #
12
+ def self.extend
13
+ ::Appium::Core::Base::SearchContext.add_finders(uiautomator: '-android uiautomator')
14
+ end
15
+ end # class << self
16
+ end # module Ios
17
+ end # module Core
18
+ end # module Appium
@@ -0,0 +1,17 @@
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
+ Appium::Logger.info "extended Appium::Core::Android::Touch, start_x: #{start_x},"\
9
+ " start_y: #{start_y}, offset_x: #{offset_x}, offset_y: #{offset_y}"
10
+ { offset_x: (start_x + offset_x), offset_y: (start_y + offset_y) }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Appium
2
+ module Core
3
+ module Android
4
+ module Uiautomator1
5
+ module Bridge
6
+ def self.for(target)
7
+ target.extend Appium::Android::Device
8
+ Core::Android::SearchContext.extend
9
+
10
+ Core::Android::Touch.extend_touch_actions
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Appium
2
+ module Core
3
+ module Android
4
+ module Uiautomator2
5
+ module Bridge
6
+ def self.for(target)
7
+ target.extend Appium::Android::Device
8
+ Core::Android::SearchContext.extend
9
+
10
+ Core::Android::Touch.extend_touch_actions
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
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'
@@ -0,0 +1,5 @@
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'
@@ -0,0 +1,6 @@
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'
@@ -0,0 +1,8 @@
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'
@@ -0,0 +1,47 @@
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
@@ -0,0 +1,16 @@
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
@@ -0,0 +1,10 @@
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
@@ -0,0 +1,51 @@
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
+ #
35
+ def window_size
36
+ manage.window.size
37
+ end
38
+
39
+ # Get the device window's size.
40
+ # @return [String]
41
+ #
42
+ # @example
43
+ # @driver.back # back to the previous view
44
+ #
45
+ def back
46
+ navigate.back
47
+ end
48
+ end # class Driver
49
+ end # class Base
50
+ end # module Core
51
+ end # module Appium
@@ -0,0 +1,13 @@
1
+ require_relative '../../version'
2
+
3
+ module Appium
4
+ module Core
5
+ class Base
6
+ module Http
7
+ class Default < Selenium::WebDriver::Remote::Http::Default
8
+ DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib_core/#{VERSION}" }.freeze
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end