appium_lib_core 1.7.2 → 1.8.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 +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/CHANGELOG.md +11 -0
  4. data/lib/appium_lib_core/android/device/clipboard.rb +4 -4
  5. data/lib/appium_lib_core/android/device/screen.rb +1 -1
  6. data/lib/appium_lib_core/android/uiautomator2/device/battery.rb +2 -2
  7. data/lib/appium_lib_core/common/base.rb +17 -0
  8. data/lib/appium_lib_core/common/base/bridge.rb +1 -0
  9. data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +15 -0
  10. data/lib/appium_lib_core/common/base/bridge/w3c.rb +19 -0
  11. data/lib/appium_lib_core/common/base/driver.rb +599 -1
  12. data/lib/appium_lib_core/common/base/screenshot.rb +18 -0
  13. data/lib/appium_lib_core/common/device/app_management.rb +87 -0
  14. data/lib/appium_lib_core/common/device/app_state.rb +30 -0
  15. data/lib/appium_lib_core/common/device/battery_status.rb +25 -0
  16. data/lib/appium_lib_core/common/device/clipboard_content_type.rb +11 -0
  17. data/lib/appium_lib_core/common/device/context.rb +38 -0
  18. data/lib/appium_lib_core/common/device/device.rb +19 -0
  19. data/lib/appium_lib_core/common/device/device_lock.rb +22 -0
  20. data/lib/appium_lib_core/common/device/file_management.rb +26 -0
  21. data/lib/appium_lib_core/common/device/image_comparison.rb +168 -0
  22. data/lib/appium_lib_core/common/device/ime_actions.rb +29 -0
  23. data/lib/appium_lib_core/common/device/keyboard.rb +22 -0
  24. data/lib/appium_lib_core/common/device/keyevent.rb +38 -0
  25. data/lib/appium_lib_core/common/device/screen_record.rb +54 -0
  26. data/lib/appium_lib_core/common/device/setting.rb +17 -0
  27. data/lib/appium_lib_core/common/device/touch_actions.rb +21 -0
  28. data/lib/appium_lib_core/common/device/value.rb +19 -0
  29. data/lib/appium_lib_core/device.rb +24 -547
  30. data/lib/appium_lib_core/driver.rb +14 -9
  31. data/lib/appium_lib_core/element/image.rb +1 -1
  32. data/lib/appium_lib_core/ios/device/clipboard.rb +4 -4
  33. data/lib/appium_lib_core/ios/xcuitest/device/battery.rb +2 -2
  34. data/lib/appium_lib_core/ios/xcuitest/device/performance.rb +1 -3
  35. data/lib/appium_lib_core/ios/xcuitest/device/screen.rb +1 -1
  36. data/lib/appium_lib_core/ios_xcuitest.rb +0 -2
  37. data/lib/appium_lib_core/version.rb +2 -2
  38. data/release_notes.md +10 -0
  39. metadata +18 -17
  40. data/lib/appium_lib_core/device/app_management.rb +0 -113
  41. data/lib/appium_lib_core/device/app_state.rb +0 -32
  42. data/lib/appium_lib_core/device/battery_status.rb +0 -23
  43. data/lib/appium_lib_core/device/clipboard_content_type.rb +0 -9
  44. data/lib/appium_lib_core/device/context.rb +0 -48
  45. data/lib/appium_lib_core/device/device_lock.rb +0 -28
  46. data/lib/appium_lib_core/device/file_management.rb +0 -32
  47. data/lib/appium_lib_core/device/image_comparison.rb +0 -178
  48. data/lib/appium_lib_core/device/ime_actions.rb +0 -43
  49. data/lib/appium_lib_core/device/keyboard.rb +0 -26
  50. data/lib/appium_lib_core/device/keyevent.rb +0 -44
  51. data/lib/appium_lib_core/device/screen_record.rb +0 -56
  52. data/lib/appium_lib_core/device/setting.rb +0 -21
  53. data/lib/appium_lib_core/device/touch_actions.rb +0 -22
  54. data/lib/appium_lib_core/device/value.rb +0 -23
@@ -0,0 +1,29 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ module ImeActions
6
+ def ime_activate(ime_name)
7
+ execute :ime_activate_engine, {}, engine: ime_name
8
+ end
9
+
10
+ def ime_available_engines
11
+ execute :ime_get_available_engines
12
+ end
13
+
14
+ def ime_active_engine
15
+ execute :ime_get_active_engine
16
+ end
17
+
18
+ def ime_activated
19
+ execute :ime_is_activated
20
+ end
21
+
22
+ def ime_deactivate
23
+ execute :ime_deactivate, {}
24
+ end
25
+ end # module ImeActions
26
+ end # module Device
27
+ end # class Base
28
+ end # module Core
29
+ end # module Appium
@@ -0,0 +1,22 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ module Keyboard
6
+ def hide_keyboard(close_key = nil, strategy = nil)
7
+ option = {}
8
+
9
+ option[:key] = close_key || 'Done' # default to Done key.
10
+ option[:strategy] = strategy || :pressKey # default to pressKey
11
+
12
+ execute :hide_keyboard, {}, option
13
+ end
14
+
15
+ def is_keyboard_shown # rubocop:disable Naming/PredicateName
16
+ execute :is_keyboard_shown
17
+ end
18
+ end # module Keyboard
19
+ end # module Device
20
+ end # class Base
21
+ end # module Core
22
+ end # module Appium
@@ -0,0 +1,38 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ module KeyEvent
6
+ # Only for Selendroid
7
+ def keyevent(key, metastate = nil)
8
+ args = { keycode: key }
9
+ args[:metastate] = metastate if metastate
10
+ execute :keyevent, {}, args
11
+ end
12
+
13
+ def press_keycode(key, metastate: [], flags: [])
14
+ raise ArgumentError, 'flags should be Array' unless flags.is_a? Array
15
+ raise ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
16
+
17
+ args = { keycode: key }
18
+ args[:metastate] = metastate.reduce(0) { |acc, meta| acc | meta } unless metastate.empty?
19
+ args[:flags] = flags.reduce(0) { |acc, flag| acc | flag } unless flags.empty?
20
+
21
+ execute :press_keycode, {}, args
22
+ end
23
+
24
+ def long_press_keycode(key, metastate: [], flags: [])
25
+ raise ArgumentError, 'flags should be Array' unless flags.is_a? Array
26
+ raise ArgumentError, 'metastates should be Array' unless metastate.is_a? Array
27
+
28
+ args = { keycode: key }
29
+ args[:metastate] = metastate.reduce(0) { |acc, meta| acc | meta } unless metastate.empty?
30
+ args[:flags] = flags.reduce(0) { |acc, flag| acc | flag } unless flags.empty?
31
+
32
+ execute :long_press_keycode, {}, args
33
+ end
34
+ end # module KeyEvent
35
+ end # module Device
36
+ end # class Base
37
+ end # module Core
38
+ end # module Appium
@@ -0,0 +1,54 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ class ScreenRecord
6
+ #
7
+ # @api private
8
+ #
9
+
10
+ attr_reader :upload_option
11
+
12
+ METHOD = %w(POST PUT).freeze
13
+
14
+ def initialize(remote_path: nil, user: nil, pass: nil, method: 'PUT', force_restart: nil)
15
+ @upload_option = if remote_path.nil?
16
+ {}
17
+ else
18
+ raise 'method should be POST or PUT' unless METHOD.member?(method.to_s.upcase)
19
+
20
+ option = {}
21
+ option[:remotePath] = remote_path
22
+ option[:user] = user unless user.nil?
23
+ option[:pass] = pass unless pass.nil?
24
+ option[:method] = method
25
+ option
26
+ end
27
+
28
+ return if force_restart.nil?
29
+
30
+ raise 'force_restart should be true or false' unless [true, false].member?(force_restart)
31
+ @upload_option[:forceRestart] = force_restart
32
+ end
33
+
34
+ module Command
35
+ def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT')
36
+ option = ::Appium::Core::Base::Device::ScreenRecord.new(
37
+ remote_path: remote_path, user: user, pass: pass, method: method
38
+ ).upload_option
39
+
40
+ params = option.empty? ? {} : { options: option }
41
+
42
+ execute(:stop_recording_screen, {}, params)
43
+ end
44
+
45
+ def stop_and_save_recording_screen(file_path)
46
+ base64data = execute(:stop_recording_screen, {}, {})
47
+ File.open(file_path, 'wb') { |f| f << Base64.decode64(base64data) }
48
+ end
49
+ end # module Command
50
+ end # class ScreenRecord
51
+ end # module Device
52
+ end # class Base
53
+ end # module Core
54
+ end # module Appium
@@ -0,0 +1,17 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ module Setting
6
+ def get_settings
7
+ execute :get_settings, {}
8
+ end
9
+
10
+ def update_settings(settings)
11
+ execute :update_settings, {}, settings: settings
12
+ end
13
+ end # module Setting
14
+ end # module Device
15
+ end # class Base
16
+ end # module Core
17
+ end # module Appium
@@ -0,0 +1,21 @@
1
+ require_relative '../touch_action/touch_actions'
2
+ require_relative '../touch_action/multi_touch'
3
+
4
+ module Appium
5
+ module Core
6
+ class Base
7
+ module Device
8
+ module TouchActions
9
+ def touch_actions(actions)
10
+ actions = { actions: [actions].flatten }
11
+ execute :touch_actions, {}, actions
12
+ end
13
+
14
+ def multi_touch(actions)
15
+ execute :multi_touch, {}, actions: actions
16
+ end
17
+ end # module TouchActions
18
+ end # module Device
19
+ end # class Base
20
+ end # module Core
21
+ end # module Appium
@@ -0,0 +1,19 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Device
5
+ module Value
6
+ def set_immediate_value(element, *value)
7
+ keys = ::Selenium::WebDriver::Keys.encode(value)
8
+ execute :set_immediate_value, { id: element.ref }, value: Array(keys)
9
+ end
10
+
11
+ def replace_value(element, *value)
12
+ keys = ::Selenium::WebDriver::Keys.encode(value)
13
+ execute :replace_value, { id: element.ref }, value: Array(keys)
14
+ end
15
+ end # module Value
16
+ end # module Device
17
+ end # class Base
18
+ end # module Core
19
+ end # module Appium
@@ -1,23 +1,5 @@
1
- require_relative 'common/touch_action/touch_actions'
2
- require_relative 'common/touch_action/multi_touch'
3
-
4
1
  require_relative 'element/image'
5
2
 
6
- require_relative 'device/screen_record'
7
- require_relative 'device/app_state'
8
- require_relative 'device/clipboard_content_type'
9
- require_relative 'device/image_comparison'
10
- require_relative 'device/app_management'
11
- require_relative 'device/keyboard'
12
- require_relative 'device/file_management'
13
- require_relative 'device/touch_actions'
14
- require_relative 'device/device_lock'
15
- require_relative 'device/ime_actions'
16
- require_relative 'device/context'
17
- require_relative 'device/keyevent'
18
- require_relative 'device/setting'
19
- require_relative 'device/value'
20
-
21
3
  require 'base64'
22
4
 
23
5
  module Appium
@@ -25,541 +7,38 @@ module Appium
25
7
  module Device
26
8
  extend Forwardable
27
9
 
28
- # rubocop:disable Metrics/LineLength
29
-
30
- ####
31
- ## No argument
32
- ####
33
-
34
- # @!method launch_app
35
- # Start the simulator and application configured with desired capabilities
36
- #
37
- # @example
38
- #
39
- # @driver.launch_app
40
- #
41
-
42
- # @!method close_app
43
- # Close an app on device
44
- #
45
- # @example
46
- #
47
- # @driver.close_app
48
- #
49
-
50
- # @!method reset
51
- # Reset the device, relaunching the application.
52
- #
53
- # @example
54
- #
55
- # @driver.reset
56
- #
57
-
58
- # @!method shake
59
- # Cause the device to shake
60
- #
61
- # @example
62
- #
63
- # @driver.shake
64
- #
65
-
66
- # @!method unlock
67
- # Unlock the device
68
- #
69
- # @example
70
- #
71
- # @driver.unlock
72
- #
73
-
74
- # @!method device_locked?
75
- # Check current device status is weather locked or not
76
- #
77
- # @example
78
- #
79
- # @driver.device_locked?
80
- #
81
-
82
- # @!method device_time
83
- # Get the time on the device
84
- #
85
- # @param [String] format The set of format specifiers. Read https://momentjs.com/docs/ to get the full list of supported
86
- # datetime format specifiers. The default format is `YYYY-MM-DDTHH:mm:ssZ`,
87
- # which complies to ISO-8601
88
- # @return [String] Formatted datetime string or the raw command output if formatting fails
89
- #
90
- # @example
91
- #
92
- # @driver.device_time #=> "2018-06-12T11:13:31+02:00"
93
- # @driver.device_time "YYYY-MM-DD" #=> "2018-06-12"
94
- #
95
-
96
- ####
97
- ## With arguments
98
- ####
99
-
100
- # @!method install_app(path, replace: nil, timeout: nil, allow_test_packages: nil, use_sdcard: nil, grant_permissions: nil)
101
- # Install the given app onto the device
102
- #
103
- # @param [String] path The absolute local path or remote http URL to an .ipa or .apk file, or a .zip containing one of these.
104
- # @param [Boolean] replace: Only for Android. Whether to reinstall/upgrade the package if it is already present on the device under test. `true` by default
105
- # @param [Integer] timeout: Only for Android. How much time to wait for the installation to complete. 60000ms by default.
106
- # @param [Boolean] allow_test_packages: Only for Android. Whether to allow installation of packages marked as test in the manifest. `false` by default
107
- # @param [Boolean] use_sdcard: Only for Android. Whether to use the SD card to install the app. `false` by default
108
- # @param [Boolean] grant_permissions: Only for Android. whether to automatically grant application permissions on Android 6+ after the installation completes. `false` by default
109
- #
110
- # @example
111
- #
112
- # @driver.install_app("/path/to/test.apk")
113
- # @driver.install_app("/path/to/test.apk", replace: true, timeout: 20000, allow_test_packages: true, use_sdcard: false, grant_permissions: false)
114
- #
115
-
116
- # @!method remove_app(app_id, keep_data: nil, timeout: nil)
117
- #
118
- # @param [Strong] app_id BundleId for iOS or package name for Android
119
- # @param [Boolean] keep_data: Only for Android. Whether to keep application data and caches after it is uninstalled. `false` by default
120
- # @param [Integer] timeout: Only for Android. How much time to wait for the uninstall to complete. 20000ms by default.
121
- #
122
- # @example
123
- #
124
- # @driver.remove_app("io.appium.bundle")
125
- # @driver.remove_app("io.appium.bundle", keep_data: false, timeout, 10000)
126
- #
127
-
128
- # @!method app_installed?(app_id)
129
- # Check whether the specified app is installed on the device
130
- # @return [Boolean]
131
- #
132
- # @example
133
- #
134
- # @driver.app_installed?("io.appium.bundle")
135
- #
136
-
137
- # @!method terminate_app(app_id)
138
- # Terminate the specified app.
139
- #
140
- # @param [Strong] app_id BundleId for iOS or package name for Android
141
- # @param [Integer] timeout: Only for Android. How much time to wait for the application termination to complete. 500ms by default.
142
- # @return [Boolean]
143
- #
144
- # @example
145
- #
146
- # @driver.terminate_app("io.appium.bundle") # true
147
- # @driver.terminate_app("io.appium.bundle", timeout: 500)
148
- #
149
-
150
- # @!method activate_app(app_id)
151
- # Activate(Launch) the specified app.
152
- # @return [Hash]
153
- #
154
- # @example
155
- #
156
- # @driver.activate_app("io.appium.bundle") #=> {}
157
- #
158
-
159
- # Get the status of an existing application on the device.
160
- # State:
161
- # :not_installed : The current application state cannot be determined/is unknown
162
- # :not_running : The application is not running
163
- # :running_in_background_suspended : The application is running in the background and is suspended
164
- # :running_in_background : The application is running in the background and is not suspended
165
- # :running_in_foreground : The application is running in the foreground
166
- #
167
- # For more details: https://developer.apple.com/documentation/xctest/xcuiapplicationstate
168
- #
169
- # @param [String] bundle_id A target app's bundle id
170
- # @return [AppState::STATUS] A number of the state
171
- #
172
- # @example
173
- #
174
- # @driver.app_state("io.appium.bundle") #=> :not_running
175
- #
176
-
177
- # @!method app_strings(language = nil)
178
- # Return the hash of all localization strings.
179
- # @return [Hash]
180
- #
181
- # @example
182
- #
183
- # @driver.app_strings #=> "TransitionsTitle"=>"Transitions", "WebTitle"=>"Web"
184
- #
185
-
186
- # @!method lock(duration = nil)
187
- # Lock the device
188
- # @return [String]
189
- #
190
- # @example
191
- #
192
- # @driver.lock #=> Lock the device
193
- # @driver.lock(5) #=> Lock the device in 5 sec and unlock the device after 5 sec.
194
- # # Block other commands during locking the device.
195
- #
196
-
197
- # @!method background_app(duration = 0)
198
- # Backgrounds the app for a set number of seconds.
199
- # This is a blocking application
200
- # @param [Integer] duration How many seconds to background the app for.
201
- # @return [String]
202
- #
203
- # @example
204
- #
205
- # @driver.background_app
206
- # @driver.background_app(5)
207
- # @driver.background_app(-1) #=> the app never come back. https://github.com/appium/appium/issues/7741
208
- #
209
-
210
- # @!method hide_keyboard(close_key = nil, strategy = nil)
211
- # Hide the onscreen keyboard
212
- # @param [String] close_key The name of the key which closes the keyboard.
213
- # Defaults to 'Done' for iOS(except for XCUITest).
214
- # @param [Symbol] strategy The symbol of the strategy which closes the keyboard.
215
- # XCUITest ignore this argument.
216
- # Default for iOS is `:pressKey`. Default for Android is `:tapOutside`.
217
- #
218
- # @example
219
- #
220
- # @driver.hide_keyboard # Close a keyboard with the 'Done' button
221
- # @driver.hide_keyboard('Finished') # Close a keyboard with the 'Finished' button
222
- # @driver.hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
223
- #
224
-
225
- # @!method is_keyboard_shown
226
- # Get whether keyboard is displayed or not.
227
- # @return [Boolean] Return true if keyboard is shown. Return false if keyboard is hidden.
228
- #
229
- # @example
230
- # @driver.is_keyboard_shown # false
231
- #
232
-
233
- # @!method keyevent(key, metastate = nil)
234
- # Send keyevent on the device.(Only for Selendroid)
235
- # http://developer.android.com/reference/android/view/KeyEvent.html
236
- # @param [integer] key The key to press.
237
- # @param [String] metastate The state the metakeys should be in when pressing the key.
238
- #
239
- # @example
240
- #
241
- # @driver.keyevent 82
242
- #
243
-
244
- # @!method press_keycode(key, metastate: [], flags: [])
245
- # Press keycode on the device.
246
- # http://developer.android.com/reference/android/view/KeyEvent.html
247
- # @param [Integer] key The key to press. The values which have `KEYCODE_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
248
- # e.g.: KEYCODE_HOME is `3` or `0x00000003`
249
- # @param [[Integer]] metastate: The state the metakeys should be in when pressing the key. Default is empty Array.
250
- # Metastate have `META_` prefix in https://developer.android.com/reference/android/view/KeyEvent.html
251
- # e.g.: META_SHIFT_ON is `1` or `0x00000001`
252
- # @param [[Integer]] flags: Native Android flag value. Several flags can be combined into a single key event.
253
- # Default is empty Array. Can set multiple flags as Array.
254
- # Flags have `FLAG_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
255
- # e.g.: FLAG_CANCELED is `32` or `0x00000020`
256
- #
257
- # @example
258
- #
259
- # @driver.press_keycode 66
260
- # @driver.press_keycode 66, flags: [0x02]
261
- # @driver.press_keycode 66, metastate: [1], flags: [32]
262
- #
263
-
264
- # @!method long_press_keycode(key, metastate: [], flags: [])
265
- # Long press keycode on the device.
266
- # http://developer.android.com/reference/android/view/KeyEvent.html
267
- # @param [Integer] key The key to long press. The values which have `KEYCODE_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
268
- # e.g.: KEYCODE_HOME is `3` or `0x00000003`
269
- # @param [[Integer]] metastate: The state the metakeys should be in when pressing the key. Default is empty Array.
270
- # Metastate have `META_` prefix in https://developer.android.com/reference/android/view/KeyEvent.html
271
- # e.g.: META_SHIFT_ON is `1` or `0x00000001`
272
- # @param [[Integer]] flags: Native Android flag value. Several flags can be combined into a single key event.
273
- # Default is empty Array. Can set multiple flags as Array.
274
- # Flags have `FLAG_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
275
- # e.g.: FLAG_CANCELED is `32` or `0x00000020`
276
- #
277
- # @example
278
- #
279
- # @driver.long_press_keycode 66
280
- # @driver.long_press_keycode 66, flags: [0x20, 0x2000]
281
- # @driver.long_press_keycode 66, metastate: [1], flags: [32, 8192]
282
- #
283
-
284
- # @!method push_file(path, filedata)
285
- # Place a file in a specific location on the device.
286
- # On iOS, the server should have ifuse libraries installed and configured properly for this feature to work on real devices.
287
- # On Android, the application under test should be built with debuggable flag enabled in order to get access to
288
- # its container on the internal file system.
289
- #
290
- # @see https://github.com/libimobiledevice/ifuse iFuse GitHub page6
291
- # @see https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ
292
- # @see https://developer.android.com/studio/debug/ 'Debug Your App' developer article
293
- #
294
- # @param [String] path The absolute path on the device to store data at.
295
- # If the path starts with application id prefix, then the file will be pushed to
296
- # the root of the corresponding application container.
297
-
298
- # @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
299
- # If the path starts with application id prefix, then the file will be pushed to the root of
300
- # the corresponding application container.
301
- # @param [String] filedata Raw file data to be sent to the device. Converted to base64 in the method.
302
- #
303
- # @example
304
- #
305
- # @driver.push_file "/file/to/path", "data"
306
- #
307
-
308
- # @!method pull_file(path)
309
- # Pull a file from the simulator/device.
310
- # On iOS the server should have ifuse
311
- # libraries installed and configured properly for this feature to work on real devices.
312
- # On Android the application under test should be built with debuggable flag enabled in order to get access
313
- # to its container on the internal file system.
314
- #
315
- # @see https://github.com/libimobiledevice/ifuse iFuse GitHub page6
316
- # @see https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ
317
- # @see https://developer.android.com/studio/debug/ 'Debug Your App' developer article
318
- #
319
- # @param [String] path Either an absolute path OR, for iOS devices, a path relative to the app, as described.
320
- # If the path starts with application id prefix, then the file will be pulled from the root
321
- # of the corresponding application container.
322
- # Otherwise the root folder is considered as / on Android and on iOS it is a media folder root
323
- # (real devices only).
324
- # @return [Base64-decoded] Base64 decoded data
325
- #
326
- # @example
327
- #
328
- # @driver.pull_file '/local/data/some/path' #=> Get the file at that path
329
- # @driver.pull_file 'Shenanigans.app/some/file' #=> Get 'some/file' from the install location of Shenanigans.app
330
- #
331
-
332
- # @!method pull_folder(path)
333
- # Pull a folder content from the simulator/device.
334
- # On iOS the server should have ifuse libraries installed and configured properly for this feature to work on real devices.
335
- # On Android the application under test should be built with debuggable flag enabled in order to get access to its container
336
- # on the internal file system.
337
- #
338
- # @see https://github.com/libimobiledevice/ifuse iFuse GitHub page6
339
- # @see https://github.com/osxfuse/osxfuse/wiki/FAQ osxFuse FAQ
340
- # @see https://developer.android.com/studio/debug/ 'Debug Your App' developer article
341
- #
342
- # @param [String] path Absolute path to the folder.
343
- # If the path starts with <em>@applicationId/</em> prefix, then the folder will be pulled
344
- # from the root of the corresponding application container.
345
- # Otherwise the root folder is considered as / on Android and on iOS it is a media folder root
346
- # (real devices only).
347
- #
348
- # @return [Base64-decoded] Base64 decoded data which is zip archived
349
- #
350
- # @example
351
- #
352
- # @driver.pull_folder '/data/local/tmp' #=> Get the folder at that path
353
- #
354
-
355
- # @!method get_settings
356
- # Get appium Settings for current test session
357
- #
358
- # @example
359
- #
360
- # @driver.pull_folder '/data/local/tmp' #=> Get the folder at that path
361
- #
362
-
363
- # @since 1.3.4
364
- # @!method save_viewport_screenshot
365
- # Save screenshot except for status bar while `@driver.save_screenshot` save entire screen.
366
- #
367
- # @example
368
- #
369
- # @driver.save_viewport_screenshot 'path/to/save.png' #=> Get the File instance of viewport_screenshot
370
- #
371
-
372
- # @!method update_settings(settings)
373
- # Update Appium Settings for current test session
374
- # @param [Hash] settings Settings to update, keys are settings, values to value to set each setting to
375
- #
376
- # @example
377
- #
378
- # @driver.update_settings('allowInvisibleElements': true)
379
- #
380
-
381
- # @!method set_immediate_value(element, *value)
382
- # Set the value to element directly
383
- #
384
- # @example
385
- #
386
- # set_immediate_value element, 'hello'
387
- #
388
-
389
- # @!method replace_value(element, *value)
390
- # Replace the value to element directly
391
- #
392
- # @example
393
- #
394
- # replace_value element, 'hello'
395
- #
396
-
397
- # @!method ime_activate(ime_name)
398
- # Android only. Make an engine that is available active.
399
- # @param [String] ime_name The IME owning the activity [required]
400
- #
401
- # @example
402
- #
403
- # ime_activate engine: 'com.android.inputmethod.latin/.LatinIME'
404
- #
405
-
406
- # @!method ime_available_engines
407
- # Android only. List all available input engines on the machine.
408
- #
409
- # @example
410
- #
411
- # ime_available_engines #=> Get the list of IME installed in the target device
412
- #
413
-
414
- # @!method ime_active_engine
415
- # Android only. Get the name of the active IME engine.
416
- #
417
- # @example
418
- #
419
- # ime_active_engine #=> Get the current active IME such as 'com.android.inputmethod.latin/.LatinIME'
420
- #
421
-
422
- # @!method ime_activated
423
- # Android only. Indicates whether IME input is active at the moment (not if it is available).
424
- #
425
- # @example
426
- #
427
- # ime_activated #=> True if IME is activated
428
- #
429
-
430
- # @!method ime_deactivate
431
- # Android only. De-activates the currently-active IME engine.
432
- #
433
- # @example
434
- #
435
- # ime_deactivate #=> Deactivate current IME engine
436
- #
437
-
438
- # @!method set_context(context)
439
- # Change the context to the given context.
440
- # @param [String] context The context to change to
441
- #
442
- # @example
443
- #
444
- # @driver.set_context "NATIVE_APP"
445
- #
446
-
447
- # @!method current_context
448
- # @return [String] The context currently being used.
449
- #
450
- # @example
451
- #
452
- # @driver.current_context
453
- #
454
-
455
- # @!method available_contexts
456
- # @return [Array<String>] All usable contexts, as an array of strings.
457
- #
458
- # @example
459
- #
460
- # @driver.available_contexts
461
- #
462
-
463
- # Perform a block within the given context, then switch back to the starting context.
464
- # @param [String] context The context to switch to for the duration of the block.
465
- #
466
- # @example
467
- #
468
- # result = @driver.within_context('NATIVE_APP') do
469
- # @driver.find_element :tag, "button"
470
- # end # The result of `find_element :tag, "button"`
471
- #
472
-
473
- # Change to the default context. This is equivalent to `set_context nil`.
474
- #
475
- # @example
476
- #
477
- # @driver.switch_to_default_context
478
- #
479
-
480
- # @!method stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT')
481
- # @param [String] remote_path: The path to the remote location, where the resulting video should be uploaded.
482
- # The following protocols are supported: http/https, ftp.
483
- # Null or empty string value (the default setting) means the content of resulting
484
- # file should be encoded as Base64 and passed as the endpoint response value.
485
- # An exception will be thrown if the generated media file is too big to
486
- # fit into the available process memory.
487
- # @param [String] user: The name of the user for the remote authentication.
488
- # @param [String] pass: The password for the remote authentication.
489
- # @param [String] method: The http multipart upload method name. The 'PUT' one is used by default.
490
- #
491
- # @example
492
- #
493
- # @driver.stop_recording_screen
494
- # @driver.stop_recording_screen remote_path: 'https://example.com', user: 'example', pass: 'pass', method: 'POST'
495
- #
496
-
497
- # @!method stop_and_save_recording_screen(file_path)
498
- # @param [String] file_path The path to save video decoded from base64 from Appium server.
499
- #
500
- # @example
501
- #
502
- # @driver.stop_and_save_recording_screen 'example.mp4'
503
- #
504
-
505
- # rubocop:enable Metrics/LineLength
506
-
507
- ####
508
- ## class << self
509
- ####
510
-
511
10
  class << self
512
11
  def extended(_mod)
513
12
  extend_webdriver_with_forwardable
514
13
 
515
- add_endpoint_method(:shake) do
516
- def shake
517
- execute :shake
518
- end
519
- end
520
-
521
- add_endpoint_method(:device_time) do
522
- def device_time(format = nil)
523
- arg = {}
524
- arg[:format] = format unless format.nil?
525
- execute :device_time, {}, arg
526
- end
527
- end
528
-
529
- add_endpoint_method(:save_viewport_screenshot) do
530
- def save_viewport_screenshot(png_path)
531
- extension = File.extname(png_path).downcase
532
- if extension != '.png'
533
- ::Appium::Logger.warn 'name used for saved screenshot does not match file type. '\
534
- 'It should end with .png extension'
535
- end
536
- viewport_screenshot_encode64 = execute_script('mobile: viewportScreenshot')
537
- File.open(png_path, 'wb') { |f| f << viewport_screenshot_encode64.unpack('m')[0] }
538
- end
539
- end
540
-
541
- Value.add_methods
542
- Setting.add_methods
543
- KeyEvent.add_methods
544
- Context.add_methods
545
- ImeActions.add_methods
546
- DeviceLock.add_methods
547
- TouchActions.add_methods
548
- FileManagement.add_methods
549
- Keyboard.add_methods
550
- AppManagement.add_methods
551
- ScreenRecord.add_methods
552
- ImageComparison.add_methods
553
- AppState.add_methods
554
-
555
14
  # Compatibility for appium_lib
556
15
  # TODO: Will remove
557
- delegate_from_appium_driver :take_element_screenshot
16
+ [
17
+ :take_element_screenshot, :save_viewport_screenshot,
18
+ :lock, :device_locked?, :unlock,
19
+ :hide_keyboard, :is_keyboard_shown,
20
+ :ime_activate, :ime_available_engines, :ime_active_engine, :ime_activated, :ime_deactivate,
21
+ :get_settings, :update_settings,
22
+ :within_context, :switch_to_default_context, :current_context, :available_contexts, :set_context,
23
+ :set_immediate_value, :replace_value,
24
+ :push_file, :pull_file, :pull_folder,
25
+ :keyevent, :press_keycode, :long_press_keycode,
26
+ :match_images_features, :find_image_occurrence, :get_images_similarity, :compare_images,
27
+ :launch_app, :close_app, :reset, :app_strings, :background_app,
28
+ :install_app, :remove_app, :app_installed?, :activate_app, :terminate_app,
29
+ :app_state,
30
+ :stop_recording_screen, :stop_and_save_recording_screen,
31
+ :shake, :device_time,
32
+ :touch_actions, :multi_touch
33
+ ].each do |key|
34
+ delegate_from_appium_driver key
35
+ end
558
36
  end
559
37
 
560
38
  # def extended
561
39
 
562
40
  # @private
41
+ # Define method in Bridges
563
42
  def add_endpoint_method(method)
564
43
  block_given? ? create_bridge_command(method, &Proc.new) : create_bridge_command(method)
565
44
 
@@ -575,19 +54,17 @@ module Appium
575
54
  end
576
55
  end
577
56
 
578
- # For ruby_lib compatibility
579
- # @private
57
+ private
58
+
580
59
  def delegate_from_appium_driver(method, delegation_target = :driver)
581
60
  def_delegator delegation_target, method
582
61
  end
583
62
 
584
- # @private
585
63
  def delegate_driver_method(method)
586
64
  return if ::Appium::Core::Base::Driver.method_defined? method
587
65
  ::Appium::Core::Base::Driver.class_eval { def_delegator :@bridge, method }
588
66
  end
589
67
 
590
- # @private
591
68
  def create_bridge_command(method)
592
69
  ::Appium::Core::Base::Bridge::MJSONWP.class_eval do
593
70
  block_given? ? class_eval(&Proc.new) : define_method(method) { execute method }
@@ -597,6 +74,6 @@ module Appium
597
74
  end
598
75
  end
599
76
  end # class << self
600
- end # module Device
77
+ end
601
78
  end # module Core
602
79
  end # module Appium