appium_lib 9.7.2 → 9.7.3
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/CHANGELOG.md +13 -0
- data/docs/android_docs.md +220 -168
- data/docs/docs.md +13 -37
- data/docs/ios_docs.md +278 -220
- data/docs/ios_xcuitest.md +0 -4
- data/docs/parallel.md +8 -0
- data/lib/appium_lib/android/android.rb +3 -0
- data/lib/appium_lib/android/common/helper.rb +3 -0
- data/lib/appium_lib/android/espresso.rb +9 -0
- data/lib/appium_lib/android/espresso/bridge.rb +14 -0
- data/lib/appium_lib/common/multi_touch.rb +151 -4
- data/lib/appium_lib/common/touch_actions.rb +21 -0
- data/lib/appium_lib/common/wait.rb +2 -22
- data/lib/appium_lib/core/android.rb +1 -0
- data/lib/appium_lib/core/android/espresso/bridge.rb +18 -0
- data/lib/appium_lib/core/android/touch.rb +15 -0
- data/lib/appium_lib/core/android/uiautomator1/bridge.rb +3 -1
- data/lib/appium_lib/core/android/uiautomator2/bridge.rb +3 -1
- data/lib/appium_lib/core/android_espresso.rb +5 -0
- data/lib/appium_lib/core/android_uiautomator2.rb +1 -0
- data/lib/appium_lib/core/core.rb +1 -1
- data/lib/appium_lib/core/device/touch_actions.rb +8 -23
- data/lib/appium_lib/core/driver.rb +93 -17
- data/lib/appium_lib/core/ios.rb +1 -0
- data/lib/appium_lib/core/ios/touch.rb +16 -0
- data/lib/appium_lib/core/ios/uiautomation/bridge.rb +2 -0
- data/lib/appium_lib/core/ios/xcuitest/bridge.rb +2 -0
- data/lib/appium_lib/core/ios/xcuitest/search_context.rb +23 -12
- data/lib/appium_lib/core/ios_xcuitest.rb +1 -0
- data/lib/appium_lib/driver.rb +18 -15
- data/lib/appium_lib/ios/xcuitest/bridge.rb +1 -0
- data/lib/appium_lib/ios/xcuitest/command.rb +1 -0
- data/lib/appium_lib/ios/xcuitest/command/source.rb +20 -0
- data/lib/appium_lib/version.rb +2 -2
- data/readme.md +14 -29
- data/release_notes.md +8 -0
- metadata +10 -3
- data/lib/appium_lib/core/device/multi_touch.rb +0 -213
data/docs/ios_xcuitest.md
CHANGED
@@ -8,10 +8,6 @@
|
|
8
8
|
- [ios-xctest-mobile-gestures](https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/ios-xctest-mobile-gestures.md)
|
9
9
|
- Required Appium1.6.4+
|
10
10
|
|
11
|
-
## Run tests on Multiple Simulators with Xcode 9
|
12
|
-
- https://github.com/appium/appium-xcuitest-driver/tree/master/test/functional/parallel
|
13
|
-
- https://github.com/appium/ruby_lib/tree/master/ios_tests/parallel
|
14
|
-
|
15
11
|
## find elements
|
16
12
|
- supported elements by find_element are:
|
17
13
|
- [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver/blob/master/lib/commands/find.js#L17)
|
data/docs/parallel.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Appium 1.7.0+ supports single server and multiple sessions, and it requires Xcode 9 for iOS.
|
2
|
+
|
3
|
+
# Example
|
4
|
+
## Run tests on Multiple Simulators with Xcode 9
|
5
|
+
- https://github.com/appium/appium-xcuitest-driver/tree/master/test/functional/parallel
|
6
|
+
- https://github.com/appium/ruby_lib/tree/master/ios_tests/parallel
|
7
|
+
- Thread programming: TestParallelRunThread
|
8
|
+
- Process programming: TestParallelRunProcess
|
@@ -122,6 +122,9 @@ module Appium
|
|
122
122
|
# "mFocusedApp=AppWindowToken{b1420058 token=Token{b128add0
|
123
123
|
# ActivityRecord{b1264d10 u0 com.example.android.apis/.ApiDemos t23}}}"
|
124
124
|
def current_app
|
125
|
+
warn '[DEPRECATION] current_app will be removed since it work only local.' \
|
126
|
+
'Please use current_activity and current_app to know package and activity for current app'
|
127
|
+
|
125
128
|
line = `adb shell dumpsys window windows`.each_line.grep(/mFocusedApp/).first.strip
|
126
129
|
|
127
130
|
_parse_current_app_line line
|
@@ -23,7 +23,7 @@ module Appium
|
|
23
23
|
# multi_touch_action.add action_2
|
24
24
|
# multi_touch_action.perform
|
25
25
|
#
|
26
|
-
class MultiTouch
|
26
|
+
class MultiTouch
|
27
27
|
class << self
|
28
28
|
# Convenience method for pinching the screen.
|
29
29
|
# Places two fingers at the edges of the screen and brings them together.
|
@@ -49,7 +49,23 @@ module Appium
|
|
49
49
|
# pinch 75, true, driver #=> Pinch the screen from the top right and bottom left corners
|
50
50
|
#
|
51
51
|
def pinch(percentage = 25, auto_perform = true, driver = $driver)
|
52
|
-
|
52
|
+
raise ArgumentError("Can't pinch to greater than screen size.") if percentage > 100
|
53
|
+
|
54
|
+
rate = Float(percentage) / 100
|
55
|
+
pinch = MultiTouch.new(driver)
|
56
|
+
|
57
|
+
if driver.automation_name_is_xcuitest?
|
58
|
+
top, bottom = pinch_for_xcuitest(rate, pinch.driver)
|
59
|
+
elsif driver.device_is_android?
|
60
|
+
top, bottom = pinch_android(rate, pinch.driver)
|
61
|
+
else
|
62
|
+
top, bottom = pinch_ios(rate, pinch.driver)
|
63
|
+
end
|
64
|
+
|
65
|
+
pinch.add top
|
66
|
+
pinch.add bottom
|
67
|
+
return pinch unless auto_perform
|
68
|
+
pinch.perform
|
53
69
|
end
|
54
70
|
|
55
71
|
# Convenience method for zooming the screen.
|
@@ -77,12 +93,143 @@ module Appium
|
|
77
93
|
# pinch 200, true, driver #=> Zoom in the screen from the center until it doubles in size.
|
78
94
|
#
|
79
95
|
def zoom(percentage = 200, auto_perform = true, driver = $driver)
|
80
|
-
|
96
|
+
raise ArgumentError("Can't zoom to smaller then screen size.") if percentage < 100
|
97
|
+
|
98
|
+
rate = 100 / Float(percentage)
|
99
|
+
zoom = MultiTouch.new(driver)
|
100
|
+
|
101
|
+
if driver.automation_name_is_xcuitest?
|
102
|
+
top, bottom = zoom_for_xcuitest(rate, zoom.driver)
|
103
|
+
elsif driver.device_is_android?
|
104
|
+
top, bottom = zoom_android(rate, zoom.driver)
|
105
|
+
else
|
106
|
+
top, bottom = zoom_ios(rate, zoom.driver)
|
107
|
+
end
|
108
|
+
|
109
|
+
zoom.add top
|
110
|
+
zoom.add bottom
|
111
|
+
return zoom unless auto_perform
|
112
|
+
zoom.perform
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# @private
|
118
|
+
def pinch_android(rate, driver)
|
119
|
+
height = 100
|
120
|
+
offset = 100
|
121
|
+
|
122
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
123
|
+
top.swipe start_x: offset, start_y: 1.0 * height + offset,
|
124
|
+
offset_x: 0.0, offset_y: (rate - 1) * height, duration: 1_000
|
125
|
+
|
126
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
127
|
+
bottom.swipe start_x: offset, start_y: 0.0 + offset,
|
128
|
+
offset_x: 0.0, offset_y: (1 - rate) * height, duration: 1_000
|
129
|
+
|
130
|
+
[top, bottom]
|
131
|
+
end
|
132
|
+
|
133
|
+
# @private
|
134
|
+
def pinch_for_xcuitest(rate, driver)
|
135
|
+
height = 100
|
136
|
+
offset = 100
|
137
|
+
|
138
|
+
ele = driver.find_element :class, 'XCUIElementTypeApplication'
|
139
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
140
|
+
top.swipe({ start_x: 0.5, start_y: 0.0 + offset,
|
141
|
+
offset_x: 0.0, offset_y: (1 - rate) * height }, ele)
|
142
|
+
|
143
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
144
|
+
bottom.swipe({ start_x: 0.5, start_y: 1.0 + offset,
|
145
|
+
offset_x: 0.0, offset_y: rate * height }, ele)
|
146
|
+
|
147
|
+
[top, bottom]
|
148
|
+
end
|
149
|
+
|
150
|
+
# @private
|
151
|
+
def pinch_ios(rate, driver)
|
152
|
+
height = 100
|
153
|
+
offset = 100
|
154
|
+
|
155
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
156
|
+
top.swipe start_x: 0.5, start_y: 0.0 + offset,
|
157
|
+
offset_x: 0.0, offset_y: (1 - rate) * height, duration: 1_000
|
158
|
+
|
159
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
160
|
+
bottom.swipe start_x: 0.5, start_y: 1.0 + offset,
|
161
|
+
offset_x: 0.0, offset_y: rate * height, duration: 1_000
|
162
|
+
|
163
|
+
[top, bottom]
|
164
|
+
end
|
165
|
+
|
166
|
+
# @private
|
167
|
+
def zoom_android(rate, driver)
|
168
|
+
height = 100
|
169
|
+
offset = 100
|
170
|
+
|
171
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
172
|
+
top.swipe start_x: offset, start_y: (1.0 - rate) * height + offset,
|
173
|
+
offset_x: 0.0, offset_y: (rate - 1.0) * height, duration: 1_000
|
174
|
+
|
175
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
176
|
+
bottom.swipe start_x: offset, start_y: rate * height + offset,
|
177
|
+
offset_x: 0.0, offset_y: (1.0 - rate) * height, duration: 1_000
|
178
|
+
|
179
|
+
[top, bottom]
|
180
|
+
end
|
181
|
+
|
182
|
+
# @private
|
183
|
+
def zoom_for_xcuitest(rate, driver)
|
184
|
+
height = 100
|
185
|
+
offset = 100
|
186
|
+
|
187
|
+
ele = driver.find_element :class, 'XCUIElementTypeApplication'
|
188
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
189
|
+
top.swipe({ start_x: 0.5, start_y: (1 - rate) * height + offset,
|
190
|
+
offset_x: 0.0, offset_y: - (1 - rate) * height }, ele)
|
191
|
+
|
192
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
193
|
+
bottom.swipe({ start_x: 0.5, start_y: rate * height + offset,
|
194
|
+
offset_x: 0.0, offset_y: (1 - rate) * height }, ele)
|
195
|
+
|
196
|
+
[top, bottom]
|
197
|
+
end
|
198
|
+
|
199
|
+
# @private
|
200
|
+
def zoom_ios(rate, driver)
|
201
|
+
height = 100
|
202
|
+
offset = 100
|
203
|
+
|
204
|
+
top = ::Appium::Core::TouchAction.new(driver)
|
205
|
+
top.swipe start_x: 0.5, start_y: (1 - rate) * height + offset,
|
206
|
+
offset_x: 0.0, offset_y: - (1 - rate) * height, duration: 1_000
|
207
|
+
|
208
|
+
bottom = ::Appium::Core::TouchAction.new(driver)
|
209
|
+
bottom.swipe start_x: 0.5, start_y: rate * height + offset,
|
210
|
+
offset_x: 0.0, offset_y: (1 - rate) * height, duration: 1_000
|
211
|
+
|
212
|
+
[top, bottom]
|
81
213
|
end
|
82
214
|
end # self
|
83
215
|
|
216
|
+
attr_reader :driver
|
217
|
+
|
84
218
|
def initialize(driver = $driver)
|
85
|
-
|
219
|
+
@actions = []
|
220
|
+
@driver = driver
|
221
|
+
end
|
222
|
+
|
223
|
+
# Add a touch_action to be performed
|
224
|
+
# @param chain (TouchAction) The action to add to the chain
|
225
|
+
def add(chain)
|
226
|
+
@actions << chain.actions
|
227
|
+
end
|
228
|
+
|
229
|
+
# Ask Appium to perform the actions
|
230
|
+
def perform
|
231
|
+
@driver.multi_touch @actions
|
232
|
+
@actions.clear
|
86
233
|
end
|
87
234
|
end # class MultiTouch
|
88
235
|
end # module Appium
|
@@ -47,5 +47,26 @@ module Appium
|
|
47
47
|
def initialize(driver = $driver)
|
48
48
|
super driver
|
49
49
|
end
|
50
|
+
|
51
|
+
def swipe(opts, ele = nil)
|
52
|
+
start_x = opts.fetch :start_x, 0
|
53
|
+
start_y = opts.fetch :start_y, 0
|
54
|
+
offset_x = opts.fetch :offset_x, nil
|
55
|
+
offset_y = opts.fetch :offset_y, nil
|
56
|
+
end_x = opts.fetch :end_x, nil
|
57
|
+
end_y = opts.fetch :end_y, nil
|
58
|
+
duration = opts.fetch :duration, 200
|
59
|
+
|
60
|
+
if end_x || end_y
|
61
|
+
warn '[DEPRECATION] end_x and end_y will be removed. Please use offset_x and offset_y for all platform.'
|
62
|
+
end_x ||= 0
|
63
|
+
end_y ||= 0
|
64
|
+
|
65
|
+
offset_x = end_x - start_x
|
66
|
+
offset_y = end_y - start_y
|
67
|
+
end
|
68
|
+
|
69
|
+
super(start_x: start_x, start_y: start_y, offset_x: offset_x, offset_y: offset_y, duration: duration, ele: ele)
|
70
|
+
end
|
50
71
|
end # class TouchAction
|
51
72
|
end # module Appium
|
@@ -8,14 +8,6 @@ module Appium
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
# process opts before calling _generic_wait
|
12
|
-
# @private
|
13
|
-
def _process_wait_opts(opts)
|
14
|
-
opts = { timeout: opts } if opts.is_a?(Numeric)
|
15
|
-
raise 'opts must be a hash' unless opts.is_a? Hash
|
16
|
-
opts
|
17
|
-
end
|
18
|
-
|
19
11
|
# Check every interval seconds to see if yield returns a truthy value.
|
20
12
|
# Note this isn't a strict boolean true, any truthy value is accepted.
|
21
13
|
# false and nil are considered failures.
|
@@ -32,13 +24,7 @@ module Appium
|
|
32
24
|
# @option opts [String] :message Exception message if timed out.
|
33
25
|
# @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Exception)
|
34
26
|
def wait_true(opts = {})
|
35
|
-
|
36
|
-
|
37
|
-
opts[:timeout] ||= @core.wait_timeout
|
38
|
-
opts[:interval] ||= @core.wait_interval
|
39
|
-
|
40
|
-
wait = ::Appium::Common::Wait.new opts
|
41
|
-
wait.until { yield }
|
27
|
+
@core.wait_true(opts) { yield }
|
42
28
|
end
|
43
29
|
|
44
30
|
# Check every interval seconds to see if yield doesn't raise an exception.
|
@@ -55,13 +41,7 @@ module Appium
|
|
55
41
|
# @option opts [String] :message Exception message if timed out.
|
56
42
|
# @option opts [Array, Exception] :ignore Exceptions to ignore while polling (default: Exception)
|
57
43
|
def wait(opts = {})
|
58
|
-
|
59
|
-
|
60
|
-
opts[:timeout] ||= @core.wait_timeout
|
61
|
-
opts[:interval] ||= @core.wait_interval
|
62
|
-
|
63
|
-
wait = ::Appium::Common::Wait.new opts
|
64
|
-
wait.until { yield }
|
44
|
+
@core.wait(opts) { yield }
|
65
45
|
end
|
66
46
|
end
|
67
47
|
end
|
@@ -0,0 +1,18 @@
|
|
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
|
@@ -0,0 +1,15 @@
|
|
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
|
data/lib/appium_lib/core/core.rb
CHANGED
@@ -6,10 +6,10 @@ require_relative 'driver'
|
|
6
6
|
|
7
7
|
# for multi touch related methods
|
8
8
|
require_relative 'device/touch_actions'
|
9
|
-
require_relative 'device/multi_touch'
|
10
9
|
|
11
10
|
require_relative 'android'
|
12
11
|
require_relative 'android_uiautomator2'
|
12
|
+
require_relative 'android_espresso'
|
13
13
|
|
14
14
|
require_relative 'ios'
|
15
15
|
require_relative 'ios_xcuitest'
|
@@ -128,21 +128,17 @@ module Appium
|
|
128
128
|
#
|
129
129
|
# @option opts [int] :start_x Where to start swiping, on the x axis. Default 0.
|
130
130
|
# @option opts [int] :start_y Where to start swiping, on the y axis. Default 0.
|
131
|
-
# @option opts [int] :offset_x
|
132
|
-
# @option opts [int] :offset_y
|
133
|
-
# @option opts [int] :end_x For Android. Where to end swiping, on the x axis. Default 0.
|
134
|
-
# @option opts [int] :end_y For Android. Where to end swiping, on the y axis. Default 0.
|
131
|
+
# @option opts [int] :offset_x Offset, on the x axis. Default 0.
|
132
|
+
# @option opts [int] :offset_y Offset, on the y axis. Default 0.
|
135
133
|
# @option opts [int] :duration How long the actual swipe takes to complete in milliseconds. Default 200.
|
136
134
|
def swipe(opts, ele = nil)
|
137
135
|
start_x = opts.fetch :start_x, 0
|
138
136
|
start_y = opts.fetch :start_y, 0
|
139
|
-
offset_x = opts.fetch :offset_x,
|
140
|
-
offset_y = opts.fetch :offset_y,
|
141
|
-
end_x = opts.fetch :end_x, nil
|
142
|
-
end_y = opts.fetch :end_y, nil
|
137
|
+
offset_x = opts.fetch :offset_x, 0
|
138
|
+
offset_y = opts.fetch :offset_y, 0
|
143
139
|
duration = opts.fetch :duration, 200
|
144
140
|
|
145
|
-
coordinates = swipe_coordinates(
|
141
|
+
coordinates = swipe_coordinates(start_x: start_x, start_y: start_y, offset_x: offset_x, offset_y: offset_y)
|
146
142
|
|
147
143
|
if ele # pinch/zoom for XCUITest
|
148
144
|
press x: start_x, y: start_y, element: ele
|
@@ -173,20 +169,9 @@ module Appium
|
|
173
169
|
|
174
170
|
# Visible for testing
|
175
171
|
# @private
|
176
|
-
def swipe_coordinates(
|
177
|
-
|
178
|
-
|
179
|
-
end_x ||= 0
|
180
|
-
end_y ||= 0
|
181
|
-
return { offset_x: end_x, offset_y: end_y }
|
182
|
-
elsif offset_x.nil? || offset_y.nil?
|
183
|
-
puts 'offset_x and offset_y are used for iOS. Not end_x and end_y point.'
|
184
|
-
end
|
185
|
-
|
186
|
-
offset_x ||= 0
|
187
|
-
offset_y ||= 0
|
188
|
-
|
189
|
-
{ offset_x: offset_x, offset_y: offset_y }
|
172
|
+
def swipe_coordinates(start_x: 0, start_y: 0, offset_x: 0, offset_y: 0)
|
173
|
+
raise NotImplementedError,
|
174
|
+
"Please define swipe_coordinates with #{start_x}, #{start_y}, #{offset_x}, #{offset_y}"
|
190
175
|
end
|
191
176
|
|
192
177
|
private
|