appium_lib 2.1.0 → 3.0.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/android_tests/lib/android/specs/android/element/button.rb +2 -2
- data/android_tests/lib/android/specs/android/helper.rb +5 -6
- data/android_tests/lib/android/specs/common/device.rb +10 -13
- data/android_tests/lib/android/specs/common/helper.rb +0 -14
- data/android_tests/lib/android/specs/driver.rb +11 -3
- data/android_tests/lib/run.rb +1 -0
- data/docs/android_docs.md +159 -239
- data/docs/ios_docs.md +147 -147
- data/lib/appium_lib/android/dynamic.rb +3 -0
- data/lib/appium_lib/android/element/button.rb +39 -16
- data/lib/appium_lib/android/element/generic.rb +4 -4
- data/lib/appium_lib/android/element/text.rb +4 -4
- data/lib/appium_lib/android/element/textfield.rb +4 -4
- data/lib/appium_lib/android/helper.rb +77 -106
- data/lib/appium_lib/common/patch.rb +1 -1
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/device/device.rb +13 -6
- data/release_notes.md +9 -0
- metadata +2 -2
@@ -30,6 +30,9 @@ module Appium
|
|
30
30
|
26 => ['classNameMatches(String regex)', 'SELECTOR_CLASS_REGEX', 26],
|
31
31
|
27 => ['descriptionMatches(String regex)', 'SELECTOR_DESCRIPTION_REGEX', 27],
|
32
32
|
28 => ['packageNameMatches(String regex)', 'SELECTOR_PACKAGE_NAME_REGEX', 28],
|
33
|
+
29 => ['resourceId(String id)', 'SELECTOR_RESOURCE_ID', 29],
|
34
|
+
30 => ['checkable(boolean val)', 'SELECTOR_CHECKABLE', 30],
|
35
|
+
31 => ['resourceIdMatches(String regex)', 'SELECTOR_RESOURCE_ID_REGEX', 31],
|
33
36
|
# // start internal methods at 100
|
34
37
|
100 => ['getStringAttribute("name")', 'GET_NAME', 100]
|
35
38
|
}
|
@@ -7,12 +7,28 @@ module Appium
|
|
7
7
|
private
|
8
8
|
|
9
9
|
# @private
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def _button_visible_selectors opts={}
|
11
|
+
button_index = opts.fetch :button_index, false
|
12
|
+
image_button_index = opts.fetch :image_button_index, false
|
13
|
+
|
14
|
+
# complex_find(...)
|
15
|
+
# 4 = className(String className)
|
16
|
+
# 9 = instance(final int instance)
|
17
|
+
|
18
|
+
if button_index && image_button_index
|
19
|
+
[
|
20
|
+
# className().instance()
|
21
|
+
[[4, Button], [9, button_index]],
|
22
|
+
# className().instance()
|
23
|
+
[[4, ImageButton], [9, image_button_index]]
|
24
|
+
]
|
14
25
|
else
|
15
|
-
|
26
|
+
[
|
27
|
+
# className()
|
28
|
+
[[4, Button]],
|
29
|
+
# className()
|
30
|
+
[[4, ImageButton]]
|
31
|
+
]
|
16
32
|
end
|
17
33
|
end
|
18
34
|
|
@@ -20,14 +36,14 @@ module Appium
|
|
20
36
|
def _button_exact_string value
|
21
37
|
button = string_visible_exact Button, value
|
22
38
|
image_button = string_visible_exact ImageButton, value
|
23
|
-
|
39
|
+
button + image_button
|
24
40
|
end
|
25
41
|
|
26
42
|
# @private
|
27
43
|
def _button_contains_string value
|
28
44
|
button = string_visible_contains Button, value
|
29
45
|
image_button = string_visible_contains ImageButton, value
|
30
|
-
|
46
|
+
button + image_button
|
31
47
|
end
|
32
48
|
|
33
49
|
public
|
@@ -41,12 +57,12 @@ module Appium
|
|
41
57
|
# Android needs to combine button and image button to match iOS.
|
42
58
|
if value.is_a? Numeric
|
43
59
|
index = value
|
44
|
-
raise "#{index} is not a valid
|
60
|
+
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
45
61
|
|
46
|
-
return
|
62
|
+
return complex_find _button_visible_selectors index: index
|
47
63
|
end
|
48
64
|
|
49
|
-
|
65
|
+
complex_find _button_contains_string value
|
50
66
|
end
|
51
67
|
|
52
68
|
# Find all buttons containing value.
|
@@ -54,34 +70,41 @@ module Appium
|
|
54
70
|
# @param value [String] the value to search for
|
55
71
|
# @return [Array<Button>]
|
56
72
|
def buttons value=false
|
57
|
-
return
|
58
|
-
|
73
|
+
return complex_find mode: 'all', selectors: _button_visible_selectors unless value
|
74
|
+
complex_find mode: 'all', selectors: _button_contains_string(value)
|
59
75
|
end
|
60
76
|
|
61
77
|
# Find the first button.
|
62
78
|
# @return [Button]
|
63
79
|
def first_button
|
64
|
-
|
80
|
+
complex_find _button_visible_selectors button_index: 0, image_button_index: 0
|
65
81
|
end
|
66
82
|
|
67
83
|
# Find the last button.
|
68
84
|
# @return [Button]
|
69
85
|
def last_button
|
70
|
-
|
86
|
+
# uiautomator index doesn't support last
|
87
|
+
# and it's 0 indexed
|
88
|
+
button_index = tags(Button).length
|
89
|
+
button_index -= 1 if button_index >= 0
|
90
|
+
image_button_index = tags(ImageButton).length
|
91
|
+
image_button_index -= 1 if image_button_index >= 0
|
92
|
+
|
93
|
+
complex_find _button_visible_selectors button_index: button_index, image_button_index: image_button_index
|
71
94
|
end
|
72
95
|
|
73
96
|
# Find the first button that exactly matches value.
|
74
97
|
# @param value [String] the value to match exactly
|
75
98
|
# @return [Button]
|
76
99
|
def button_exact value
|
77
|
-
|
100
|
+
complex_find _button_exact_string value
|
78
101
|
end
|
79
102
|
|
80
103
|
# Find all buttons that exactly match value.
|
81
104
|
# @param value [String] the value to match exactly
|
82
105
|
# @return [Array<Button>]
|
83
106
|
def buttons_exact value
|
84
|
-
|
107
|
+
complex_find mode: 'all', selectors: _button_exact_string(value)
|
85
108
|
end
|
86
109
|
end # module Android
|
87
110
|
end # module Appium
|
@@ -5,28 +5,28 @@ module Appium
|
|
5
5
|
# @param value [String] the value to search for
|
6
6
|
# @return [Element]
|
7
7
|
def find value
|
8
|
-
|
8
|
+
complex_find_contains '*', value
|
9
9
|
end
|
10
10
|
|
11
11
|
# Find all elements containing value
|
12
12
|
# @param value [String] the value to search for
|
13
13
|
# @return [Array<Element>]
|
14
14
|
def finds value
|
15
|
-
|
15
|
+
complex_finds_contains '*', value
|
16
16
|
end
|
17
17
|
|
18
18
|
# Find the first element exactly matching value
|
19
19
|
# @param value [String] the value to search for
|
20
20
|
# @return [Element]
|
21
21
|
def find_exact value
|
22
|
-
|
22
|
+
complex_find_exact '*', value
|
23
23
|
end
|
24
24
|
|
25
25
|
# Find all elements exactly matching value
|
26
26
|
# @param value [String] the value to search for
|
27
27
|
# @return [Array<Element>]
|
28
28
|
def finds_exact value
|
29
|
-
|
29
|
+
complex_finds_exact '*', value
|
30
30
|
end
|
31
31
|
|
32
32
|
# Scroll to the first element containing target text or description.
|
@@ -9,7 +9,7 @@ module Appium
|
|
9
9
|
# @return [TextView]
|
10
10
|
def text value
|
11
11
|
return ele_index TextView, value if value.is_a? Numeric
|
12
|
-
|
12
|
+
complex_find_contains TextView, value
|
13
13
|
end
|
14
14
|
|
15
15
|
# Find all TextViews containing value.
|
@@ -18,7 +18,7 @@ module Appium
|
|
18
18
|
# @return [Array<TextView>]
|
19
19
|
def texts value=false
|
20
20
|
return tags TextView unless value
|
21
|
-
|
21
|
+
complex_finds_contains TextView, value
|
22
22
|
end
|
23
23
|
|
24
24
|
# Find the first TextView.
|
@@ -37,14 +37,14 @@ module Appium
|
|
37
37
|
# @param value [String] the value to match exactly
|
38
38
|
# @return [TextView]
|
39
39
|
def text_exact value
|
40
|
-
|
40
|
+
complex_find_exact TextView, value
|
41
41
|
end
|
42
42
|
|
43
43
|
# Find all TextViews that exactly match value.
|
44
44
|
# @param value [String] the value to match exactly
|
45
45
|
# @return [Array<TextView>]
|
46
46
|
def texts_exact value
|
47
|
-
|
47
|
+
complex_finds_exact TextView, value
|
48
48
|
end
|
49
49
|
end # module Android
|
50
50
|
end # module Appium
|
@@ -8,7 +8,7 @@ module Appium
|
|
8
8
|
# @return [EditText]
|
9
9
|
def textfield value
|
10
10
|
return ele_index EditText, value if value.is_a? Numeric
|
11
|
-
|
11
|
+
complex_find_contains EditText, value
|
12
12
|
end
|
13
13
|
|
14
14
|
# Find all EditTexts containing value.
|
@@ -17,7 +17,7 @@ module Appium
|
|
17
17
|
# @return [Array<EditText>]
|
18
18
|
def textfields value=false
|
19
19
|
return tags EditText unless value
|
20
|
-
|
20
|
+
complex_finds_contains EditText, value
|
21
21
|
end
|
22
22
|
|
23
23
|
# Find the first EditText.
|
@@ -36,14 +36,14 @@ module Appium
|
|
36
36
|
# @param value [String] the value to match exactly
|
37
37
|
# @return [EditText]
|
38
38
|
def textfield_exact value
|
39
|
-
|
39
|
+
complex_find_exact EditText, value
|
40
40
|
end
|
41
41
|
|
42
42
|
# Find all EditTexts that exactly match value.
|
43
43
|
# @param value [String] the value to match exactly
|
44
44
|
# @return [Array<EditText>]
|
45
45
|
def textfields_exact value
|
46
|
-
|
46
|
+
complex_finds_exact EditText, value
|
47
47
|
end
|
48
48
|
end # module Android
|
49
49
|
end # module Appium
|
@@ -130,29 +130,20 @@ module Appium
|
|
130
130
|
am_start: pkg + '/' + act)
|
131
131
|
end
|
132
132
|
|
133
|
-
# @private
|
134
|
-
def string_id_xpath id
|
135
|
-
value = resolve_id id
|
136
|
-
# If the id doesn't resolve in strings.xml then use it as is
|
137
|
-
# It's probably a resource id which won't be in strings.xml
|
138
|
-
value = id unless value
|
139
|
-
exact = string_visible_exact '*', value
|
140
|
-
contains = string_visible_contains '*', value
|
141
|
-
"#{exact} | #{contains}"
|
142
|
-
end
|
143
|
-
|
144
133
|
# Find the first matching element by id
|
145
134
|
# @param id [String] the id to search for
|
146
135
|
# @return [Element]
|
147
136
|
def id id
|
148
|
-
|
137
|
+
# Android auto resolves strings.xml ids
|
138
|
+
find_element :id, id
|
149
139
|
end
|
150
140
|
|
151
141
|
# Find all matching elements by id
|
152
142
|
# @param id [String] the id to search for
|
153
143
|
# @return [Element]
|
154
144
|
def ids id
|
155
|
-
|
145
|
+
# Android auto resolves strings.xml ids
|
146
|
+
find_elements :id, value
|
156
147
|
end
|
157
148
|
|
158
149
|
# Find the element of type class_name at matching index.
|
@@ -160,65 +151,21 @@ module Appium
|
|
160
151
|
# @param index [Integer] the index
|
161
152
|
# @return [Element] the found element of type class_name
|
162
153
|
def ele_index class_name, index
|
163
|
-
|
164
|
-
|
165
|
-
|
154
|
+
if index == 'last()'
|
155
|
+
index = tags(class_name).length
|
156
|
+
index -= 1 if index >= 0
|
157
|
+
else
|
158
|
+
raise 'Index must be >= 1' unless index >= 1
|
159
|
+
index -= 1 if index >= 1
|
166
160
|
end
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
# @private
|
171
|
-
def string_attr_exact class_name, attr, value
|
172
|
-
%Q(//#{class_name}[@#{attr}='#{value}'])
|
173
|
-
end
|
174
|
-
|
175
|
-
# Find the first element exactly matching class and attribute value.
|
176
|
-
# @param class_name [String] the class name to search for
|
177
|
-
# @param attr [String] the attribute to inspect
|
178
|
-
# @param value [String] the expected value of the attribute
|
179
|
-
# @return [Element]
|
180
|
-
def find_ele_by_attr class_name, attr, value
|
181
|
-
@driver.find_element :xpath, string_attr_exact(class_name, attr, value)
|
182
|
-
end
|
183
|
-
|
184
|
-
# Find all elements exactly matching class and attribute value.
|
185
|
-
# @param class_name [String] the class name to match
|
186
|
-
# @param attr [String] the attribute to compare
|
187
|
-
# @param value [String] the value of the attribute that the element must have
|
188
|
-
# @return [Array<Element>]
|
189
|
-
def find_eles_by_attr class_name, attr, value
|
190
|
-
@driver.find_elements :xpath, string_attr_exact(class_name, attr, value)
|
191
|
-
end
|
192
|
-
|
193
|
-
# @private
|
194
|
-
def string_attr_include class_name, attr, value
|
195
|
-
%Q(//#{class_name}[contains(translate(@#{attr},'#{value.upcase}', '#{value}'), '#{value}')])
|
196
|
-
end
|
197
|
-
|
198
|
-
# Find the first element by attribute that exactly matches value.
|
199
|
-
# @param class_name [String] the class name to match
|
200
|
-
# @param attr [String] the attribute to compare
|
201
|
-
# @param value [String] the value of the attribute that the element must include
|
202
|
-
# @return [Element] the element of type tag who's attribute includes value
|
203
|
-
def find_ele_by_attr_include class_name, attr, value
|
204
|
-
@driver.find_element :xpath, string_attr_include(class_name, attr, value)
|
205
|
-
end
|
206
|
-
|
207
|
-
# Find elements by attribute that include value.
|
208
|
-
# @param class_name [String] the tag name to match
|
209
|
-
# @param attr [String] the attribute to compare
|
210
|
-
# @param value [String] the value of the attribute that the element must include
|
211
|
-
# @return [Array<Element>] the elements of type tag who's attribute includes value
|
212
|
-
def find_eles_by_attr_include class_name, attr, value
|
213
|
-
@driver.find_elements :xpath, string_attr_include(class_name, attr, value)
|
161
|
+
complex_find [[[4, class_name], [9, index]]]
|
214
162
|
end
|
215
163
|
|
216
164
|
# Find the first element that matches class_name
|
217
165
|
# @param class_name [String] the tag to match
|
218
166
|
# @return [Element]
|
219
167
|
def first_ele class_name
|
220
|
-
|
221
|
-
ele_index class_name, 1
|
168
|
+
tag(class_name)
|
222
169
|
end
|
223
170
|
|
224
171
|
# Find the last element that matches class_name
|
@@ -233,7 +180,7 @@ module Appium
|
|
233
180
|
# @param class_name [String] the class_name to search for
|
234
181
|
# @return [Element]
|
235
182
|
def tag class_name
|
236
|
-
|
183
|
+
find_element :class, class_name
|
237
184
|
end
|
238
185
|
|
239
186
|
# Find all elements of type class_name
|
@@ -241,84 +188,108 @@ module Appium
|
|
241
188
|
# @param class_name [String] the class_name to search for
|
242
189
|
# @return [Element]
|
243
190
|
def tags class_name
|
244
|
-
|
191
|
+
find_elements :class, class_name
|
245
192
|
end
|
246
193
|
|
247
194
|
# @private
|
248
|
-
# Returns a string
|
195
|
+
# Returns a string that matches the first element that contains value
|
249
196
|
#
|
250
|
-
# example:
|
197
|
+
# example: complex_find_contains 'UIATextField', 'sign in'
|
251
198
|
#
|
252
|
-
# @param
|
199
|
+
# @param class_name [String] the class name for the element
|
253
200
|
# @param value [String] the value to search for
|
254
201
|
# @return [String]
|
255
|
-
def string_visible_contains
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
202
|
+
def string_visible_contains class_name, value
|
203
|
+
# 4 = className(String className)
|
204
|
+
# 29 = resourceId(String id
|
205
|
+
# 7 = descriptionContains(String desc)
|
206
|
+
# 3 = textContains(String text)
|
207
|
+
# todo: textContains isn't case insensitive
|
208
|
+
# descriptionContains is case insensitive
|
209
|
+
|
210
|
+
if class_name == '*'
|
211
|
+
return [
|
212
|
+
# resourceId()
|
213
|
+
[[29, value]],
|
214
|
+
# descriptionContains()
|
215
|
+
[[7, value]],
|
216
|
+
# textContains()
|
217
|
+
[[3, value]]
|
218
|
+
]
|
264
219
|
end
|
265
220
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
221
|
+
[
|
222
|
+
# className().resourceId()
|
223
|
+
[[4, class_name], [29, value]],
|
224
|
+
# className().descriptionContains()
|
225
|
+
[[4, class_name], [7, value]],
|
226
|
+
# className().textContains()
|
227
|
+
[[4, class_name], [3, value]]
|
228
|
+
]
|
272
229
|
end
|
273
230
|
|
274
231
|
# Find the first element that contains value
|
275
232
|
# @param element [String] the class name for the element
|
276
233
|
# @param value [String] the value to search for
|
277
234
|
# @return [Element]
|
278
|
-
def
|
279
|
-
|
235
|
+
def complex_find_contains element, value
|
236
|
+
complex_find string_visible_contains element, value
|
280
237
|
end
|
281
238
|
|
282
239
|
# Find all elements containing value
|
283
240
|
# @param element [String] the class name for the element
|
284
241
|
# @param value [String] the value to search for
|
285
242
|
# @return [Array<Element>]
|
286
|
-
def
|
287
|
-
|
243
|
+
def complex_finds_contains element, value
|
244
|
+
complex_find mode: 'all', selectors: string_visible_contains(element, value)
|
288
245
|
end
|
289
246
|
|
290
247
|
# @private
|
291
|
-
# Create an
|
292
|
-
# @param
|
248
|
+
# Create an string to exactly match the first element with target value
|
249
|
+
# @param class_name [String] the class name for the element
|
293
250
|
# @param value [String] the value to search for
|
294
251
|
# @return [String]
|
295
|
-
def string_visible_exact
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
252
|
+
def string_visible_exact class_name, value
|
253
|
+
# 4 = className(String className)
|
254
|
+
# 29 = resourceId(String id
|
255
|
+
# 5 = description(String desc)
|
256
|
+
# 1 = text(String text)
|
257
|
+
|
258
|
+
if class_name == '*'
|
259
|
+
return [
|
260
|
+
# resourceId()
|
261
|
+
[[29, value]],
|
262
|
+
# description()
|
263
|
+
[[5, value]],
|
264
|
+
# text()
|
265
|
+
[[1, value]]
|
266
|
+
]
|
301
267
|
end
|
302
268
|
|
303
|
-
|
304
|
-
|
305
|
-
|
269
|
+
[
|
270
|
+
# className().resourceId()
|
271
|
+
[[4, class_name], [29, value]],
|
272
|
+
# className().description()
|
273
|
+
[[4, class_name], [5, value]],
|
274
|
+
# className().text()
|
275
|
+
[[4, class_name], [1, value]]
|
276
|
+
]
|
306
277
|
end
|
307
278
|
|
308
279
|
# Find the first element exactly matching value
|
309
|
-
# @param
|
280
|
+
# @param class_name [String] the class name for the element
|
310
281
|
# @param value [String] the value to search for
|
311
282
|
# @return [Element]
|
312
|
-
def
|
313
|
-
|
283
|
+
def complex_find_exact class_name, value
|
284
|
+
complex_find string_visible_exact class_name, value
|
314
285
|
end
|
315
286
|
|
316
287
|
# Find all elements exactly matching value
|
317
|
-
# @param
|
288
|
+
# @param class_name [String] the class name for the element
|
318
289
|
# @param value [String] the value to search for
|
319
290
|
# @return [Element]
|
320
|
-
def
|
321
|
-
|
291
|
+
def complex_finds_exact class_name, value
|
292
|
+
complex_find mode: 'all', selectors: string_visible_exact(class_name, value)
|
322
293
|
end
|
323
294
|
end # module Android
|
324
295
|
end # module Appium
|