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