appium_lib 8.2.1 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/android_tests/lib/android/specs/common/device_touchaction.rb +2 -2
- data/appium_lib.gemspec +2 -2
- data/docs/android_docs.md +245 -212
- data/docs/docs.md +17 -15
- data/docs/index_paths.md +2 -2
- data/docs/ios_docs.md +422 -240
- data/docs/ios_xcuitest.md +25 -0
- data/ios_tests/Gemfile +2 -0
- data/ios_tests/appium.txt +2 -1
- data/ios_tests/lib/common.rb +98 -4
- data/ios_tests/lib/ios/specs/common/helper.rb +24 -28
- data/ios_tests/lib/ios/specs/common/patch.rb +1 -1
- data/ios_tests/lib/ios/specs/device/device.rb +17 -11
- data/ios_tests/lib/ios/specs/device/multi_touch.rb +22 -1
- data/ios_tests/lib/ios/specs/device/touch_actions.rb +14 -5
- data/ios_tests/lib/ios/specs/driver.rb +13 -9
- data/ios_tests/lib/ios/specs/ios/element/alert.rb +12 -8
- data/ios_tests/lib/ios/specs/ios/element/button.rb +6 -3
- data/ios_tests/lib/ios/specs/ios/element/text.rb +5 -3
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +12 -8
- data/ios_tests/lib/ios/specs/ios/helper.rb +9 -3
- data/ios_tests/lib/ios/specs/ios/patch.rb +9 -1
- data/ios_tests/readme.md +3 -2
- data/lib/appium_lib/common/error.rb +5 -0
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/device/device.rb +7 -1
- data/lib/appium_lib/device/multi_touch.rb +27 -9
- data/lib/appium_lib/device/touch_actions.rb +12 -5
- data/lib/appium_lib/driver.rb +29 -1
- data/lib/appium_lib/ios/element/button.rb +50 -24
- data/lib/appium_lib/ios/element/generic.rb +20 -4
- data/lib/appium_lib/ios/element/text.rb +48 -24
- data/lib/appium_lib/ios/element/textfield.rb +80 -40
- data/lib/appium_lib/ios/helper.rb +107 -33
- data/lib/appium_lib/ios/mobile_methods.rb +1 -0
- data/lib/appium_lib/ios/patch.rb +5 -2
- data/readme.md +1 -0
- data/release_notes.md +10 -0
- metadata +16 -2
@@ -4,28 +4,44 @@ module Appium
|
|
4
4
|
# @param value [String] the value to search for
|
5
5
|
# @return [Element]
|
6
6
|
def find(value)
|
7
|
-
|
7
|
+
if automation_name_is_xcuitest?
|
8
|
+
find_ele_by_attr_include '*', '*', value
|
9
|
+
else
|
10
|
+
ele_by_json_visible_contains '*', value
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
# Find all elements containing value
|
11
15
|
# @param value [String] the value to search for
|
12
16
|
# @return [Array<Element>]
|
13
17
|
def finds(value)
|
14
|
-
|
18
|
+
if automation_name_is_xcuitest?
|
19
|
+
find_eles_by_attr_include '*', '*', value
|
20
|
+
else
|
21
|
+
eles_by_json_visible_contains '*', value
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
17
25
|
# Find the first element exactly matching value
|
18
26
|
# @param value [String] the value to search for
|
19
27
|
# @return [Element]
|
20
28
|
def find_exact(value)
|
21
|
-
|
29
|
+
if automation_name_is_xcuitest?
|
30
|
+
find_ele_by_attr '*', '*', value
|
31
|
+
else
|
32
|
+
ele_by_json_visible_exact '*', value
|
33
|
+
end
|
22
34
|
end
|
23
35
|
|
24
36
|
# Find all elements exactly matching value
|
25
37
|
# @param value [String] the value to search for
|
26
38
|
# @return [Array<Element>]
|
27
39
|
def finds_exact(value)
|
28
|
-
|
40
|
+
if automation_name_is_xcuitest?
|
41
|
+
find_ele_by_attr '*', '*', value
|
42
|
+
else
|
43
|
+
eles_by_json_visible_exact '*', value
|
44
|
+
end
|
29
45
|
end
|
30
46
|
end # module Ios
|
31
47
|
end # module Appium
|
@@ -1,50 +1,74 @@
|
|
1
|
-
# UIAStaticText methods
|
1
|
+
# UIAStaticText|XCUIElementTypeStaticText methods
|
2
2
|
module Appium
|
3
3
|
module Ios
|
4
|
-
|
4
|
+
IAStaticText = 'UIAStaticText'.freeze
|
5
|
+
XCUIElementTypeStaticText = 'XCUIElementTypeStaticText'.freeze
|
5
6
|
|
6
|
-
#
|
7
|
+
# @return [String] Class name for text
|
8
|
+
def static_text_class
|
9
|
+
automation_name_is_xcuitest? ? XCUIElementTypeStaticText : IAStaticText
|
10
|
+
end
|
11
|
+
|
12
|
+
# Find the first UIAStaticText|XCUIElementTypeStaticText that contains value or by index.
|
7
13
|
# @param value [String, Integer] the value to find.
|
8
|
-
# If int then the UIAStaticText at that index is returned.
|
9
|
-
# @return [UIAStaticText]
|
14
|
+
# If int then the UIAStaticText|XCUIElementTypeStaticText at that index is returned.
|
15
|
+
# @return [UIAStaticText|XCUIElementTypeStaticText]
|
10
16
|
def text(value)
|
11
|
-
return ele_index
|
12
|
-
|
17
|
+
return ele_index static_text_class, value if value.is_a? Numeric
|
18
|
+
|
19
|
+
if automation_name_is_xcuitest?
|
20
|
+
find_ele_by_attr_include static_text_class, '*', value
|
21
|
+
else
|
22
|
+
ele_by_json_visible_contains static_text_class, value
|
23
|
+
end
|
13
24
|
end
|
14
25
|
|
15
|
-
# Find all
|
16
|
-
# If value is omitted, all UIAStaticTexts are returned
|
26
|
+
# Find all UIAStaticTexts|XCUIElementTypeStaticTexts containing value.
|
27
|
+
# If value is omitted, all UIAStaticTexts|XCUIElementTypeStaticTexts are returned
|
17
28
|
# @param value [String] the value to search for
|
18
|
-
# @return [Array<UIAStaticText>]
|
29
|
+
# @return [Array<UIAStaticText|XCUIElementTypeStaticText>]
|
19
30
|
def texts(value = false)
|
20
|
-
return tags
|
21
|
-
|
31
|
+
return tags static_text_class unless value
|
32
|
+
|
33
|
+
if automation_name_is_xcuitest?
|
34
|
+
find_eles_by_attr_include static_text_class, '*', value
|
35
|
+
else
|
36
|
+
eles_by_json_visible_contains static_text_class, value
|
37
|
+
end
|
22
38
|
end
|
23
39
|
|
24
|
-
# Find the first UIAStaticText.
|
25
|
-
# @return [UIAStaticText]
|
40
|
+
# Find the first UIAStaticText|XCUIElementTypeStaticText.
|
41
|
+
# @return [UIAStaticText|XCUIElementTypeStaticText]
|
26
42
|
def first_text
|
27
|
-
first_ele
|
43
|
+
first_ele static_text_class
|
28
44
|
end
|
29
45
|
|
30
|
-
# Find the last UIAStaticText.
|
31
|
-
# @return [UIAStaticText]
|
46
|
+
# Find the last UIAStaticText|XCUIElementTypeStaticText.
|
47
|
+
# @return [UIAStaticText|XCUIElementTypeStaticText]
|
32
48
|
def last_text
|
33
|
-
last_ele
|
49
|
+
last_ele static_text_class
|
34
50
|
end
|
35
51
|
|
36
|
-
# Find the first UIAStaticText that exactly matches value.
|
52
|
+
# Find the first UIAStaticText|XCUIElementTypeStaticText that exactly matches value.
|
37
53
|
# @param value [String] the value to match exactly
|
38
|
-
# @return [UIAStaticText]
|
54
|
+
# @return [UIAStaticText|XCUIElementTypeStaticText]
|
39
55
|
def text_exact(value)
|
40
|
-
|
56
|
+
if automation_name_is_xcuitest?
|
57
|
+
find_ele_by_attr static_text_class, '*', value
|
58
|
+
else
|
59
|
+
ele_by_json_visible_exact static_text_class, value
|
60
|
+
end
|
41
61
|
end
|
42
62
|
|
43
|
-
# Find all UIAStaticTexts that exactly match value.
|
63
|
+
# Find all UIAStaticTexts|XCUIElementTypeStaticTexts that exactly match value.
|
44
64
|
# @param value [String] the value to match exactly
|
45
|
-
# @return [Array<UIAStaticText>]
|
65
|
+
# @return [Array<UIAStaticText|XCUIElementTypeStaticText>]
|
46
66
|
def texts_exact(value)
|
47
|
-
|
67
|
+
if automation_name_is_xcuitest?
|
68
|
+
find_eles_by_attr static_text_class, '*', value
|
69
|
+
else
|
70
|
+
eles_by_json_visible_exact static_text_class, value
|
71
|
+
end
|
48
72
|
end
|
49
73
|
end # module Ios
|
50
74
|
end # module Appium
|
@@ -1,68 +1,87 @@
|
|
1
1
|
module Appium
|
2
2
|
module Ios
|
3
|
-
UIATextField
|
4
|
-
UIASecureTextField = 'UIASecureTextField'
|
3
|
+
UIATextField = 'UIATextField'.freeze
|
4
|
+
UIASecureTextField = 'UIASecureTextField'.freeze
|
5
|
+
|
6
|
+
XCUIElementTypeTextField = 'XCUIElementTypeTextField'.freeze
|
7
|
+
XCUIElementTypeSecureTextField = 'XCUIElementTypeSecureTextField'.freeze
|
8
|
+
|
9
|
+
# @return [String] Class name for text field
|
10
|
+
def text_field_class
|
11
|
+
automation_name_is_xcuitest? ? XCUIElementTypeTextField : UIATextField
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [String] Class name for secure text field
|
15
|
+
def secure_text_field_class
|
16
|
+
automation_name_is_xcuitest? ? XCUIElementTypeSecureTextField : UIASecureTextField
|
17
|
+
end
|
5
18
|
|
6
19
|
private
|
7
20
|
|
8
21
|
# @private
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
onlyVisible: true
|
13
|
-
}
|
22
|
+
# for XCUITest
|
23
|
+
def _textfields
|
24
|
+
%(#{text_field_class} | //#{secure_text_field_class})
|
14
25
|
end
|
15
26
|
|
16
27
|
# @private
|
28
|
+
# for XCUITest
|
29
|
+
def _textfield_with_xpath
|
30
|
+
xpath "//#{_textfields}"
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
# for XCUITest
|
35
|
+
def _textfields_with_xpath
|
36
|
+
xpaths "//#{_textfields}"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Appium
|
40
|
+
def _textfield_visible
|
41
|
+
{ typeArray: [UIATextField, UIASecureTextField], onlyVisible: true }
|
42
|
+
end
|
43
|
+
|
44
|
+
# Appium
|
17
45
|
def _textfield_exact_string(value)
|
18
|
-
exact
|
19
|
-
|
20
|
-
substring: false,
|
21
|
-
insensitive: false
|
22
|
-
}
|
23
|
-
exact_obj = {
|
24
|
-
name: exact,
|
25
|
-
label: exact,
|
26
|
-
value: exact
|
27
|
-
}
|
46
|
+
exact = { target: value, substring: false, insensitive: false }
|
47
|
+
exact_obj = { name: exact, label: exact, value: exact }
|
28
48
|
_textfield_visible.merge(exact_obj)
|
29
49
|
end
|
30
50
|
|
31
|
-
#
|
51
|
+
# Appium
|
32
52
|
def _textfield_contains_string(value)
|
33
|
-
contains
|
34
|
-
|
35
|
-
substring: true,
|
36
|
-
insensitive: true
|
37
|
-
}
|
38
|
-
contains_obj = {
|
39
|
-
name: contains,
|
40
|
-
label: contains,
|
41
|
-
value: contains
|
42
|
-
}
|
53
|
+
contains = { target: value, substring: true, insensitive: true }
|
54
|
+
contains_obj = { name: contains, label: contains, value: contains }
|
43
55
|
_textfield_visible.merge(contains_obj)
|
44
56
|
end
|
45
57
|
|
46
58
|
public
|
47
59
|
|
48
60
|
# Find the first TextField that contains value or by index.
|
61
|
+
# Note: Uses XPath
|
49
62
|
# @param value [String, Integer] the text to match exactly.
|
50
63
|
# If int then the TextField at that index is returned.
|
51
64
|
# @return [TextField]
|
52
65
|
def textfield(value)
|
53
|
-
# Don't use ele_index because that only works on one element type.
|
54
|
-
# iOS needs to combine textfield and secure to match Android.
|
55
66
|
if value.is_a? Numeric
|
56
67
|
index = value
|
57
68
|
fail "#{index} is not a valid index. Must be >= 1" if index <= 0
|
58
|
-
index -= 1 # eles_by_json is 0 indexed.
|
59
|
-
|
60
|
-
|
69
|
+
index -= 1 # eles_by_json and _textfields_with_xpath is 0 indexed.
|
70
|
+
result = if automation_name_is_xcuitest?
|
71
|
+
_textfields_with_xpath[index]
|
72
|
+
else
|
73
|
+
eles_by_json(_textfield_visible)[index]
|
74
|
+
end
|
61
75
|
fail _no_such_element if result.nil?
|
62
76
|
return result
|
77
|
+
|
63
78
|
end
|
64
79
|
|
65
|
-
|
80
|
+
if automation_name_is_xcuitest?
|
81
|
+
find_ele_by_attr_include _textfields, '*', value
|
82
|
+
else
|
83
|
+
ele_by_json _textfield_contains_string value
|
84
|
+
end
|
66
85
|
end
|
67
86
|
|
68
87
|
# Find all TextFields containing value.
|
@@ -70,20 +89,33 @@ module Appium
|
|
70
89
|
# @param value [String] the value to search for
|
71
90
|
# @return [Array<TextField>]
|
72
91
|
def textfields(value = false)
|
73
|
-
|
74
|
-
|
92
|
+
if automation_name_is_xcuitest?
|
93
|
+
return _textfields_with_xpath unless value
|
94
|
+
find_eles_by_attr_include _textfields, '*', value
|
95
|
+
else
|
96
|
+
return eles_by_json _textfield_visible unless value
|
97
|
+
eles_by_json _textfield_contains_string value
|
98
|
+
end
|
75
99
|
end
|
76
100
|
|
77
101
|
# Find the first TextField.
|
78
102
|
# @return [TextField]
|
79
103
|
def first_textfield
|
80
|
-
|
104
|
+
if automation_name_is_xcuitest?
|
105
|
+
_textfield_with_xpath
|
106
|
+
else
|
107
|
+
ele_by_json _textfield_visible
|
108
|
+
end
|
81
109
|
end
|
82
110
|
|
83
111
|
# Find the last TextField.
|
84
112
|
# @return [TextField]
|
85
113
|
def last_textfield
|
86
|
-
result =
|
114
|
+
result = if automation_name_is_xcuitest?
|
115
|
+
_textfields_with_xpath.last
|
116
|
+
else
|
117
|
+
eles_by_json(_textfield_visible).last
|
118
|
+
end
|
87
119
|
fail _no_such_element if result.nil?
|
88
120
|
result
|
89
121
|
end
|
@@ -92,14 +124,22 @@ module Appium
|
|
92
124
|
# @param value [String] the value to match exactly
|
93
125
|
# @return [TextField]
|
94
126
|
def textfield_exact(value)
|
95
|
-
|
127
|
+
if automation_name_is_xcuitest?
|
128
|
+
find_ele_by_attr _textfields, '*', value
|
129
|
+
else
|
130
|
+
ele_by_json _textfield_exact_string value
|
131
|
+
end
|
96
132
|
end
|
97
133
|
|
98
134
|
# Find all TextFields that exactly match value.
|
99
135
|
# @param value [String] the value to match exactly
|
100
136
|
# @return [Array<TextField>]
|
101
137
|
def textfields_exact(value)
|
102
|
-
|
138
|
+
if automation_name_is_xcuitest?
|
139
|
+
find_eles_by_attr _textfields, '*', value
|
140
|
+
else
|
141
|
+
eles_by_json _textfield_exact_string value
|
142
|
+
end
|
103
143
|
end
|
104
144
|
end # module Ios
|
105
145
|
end # module Appium
|
@@ -1,5 +1,41 @@
|
|
1
1
|
module Appium
|
2
2
|
module Ios
|
3
|
+
class UITestElementsPrinter < Nokogiri::XML::SAX::Document
|
4
|
+
attr_accessor :filter
|
5
|
+
|
6
|
+
def start_element(type, attrs = [])
|
7
|
+
return if filter && !filter.eql?(type)
|
8
|
+
page = attrs.inject({}) do |hash, attr|
|
9
|
+
hash[attr[0]] = attr[1] if %w(name label value hint).include?(attr[0])
|
10
|
+
hash
|
11
|
+
end
|
12
|
+
_print_attr(type, page['name'], page['label'], page['value'], page['hint'])
|
13
|
+
end
|
14
|
+
|
15
|
+
def _print_attr(type, name, label, value, hint)
|
16
|
+
if name == label && name == value
|
17
|
+
puts "#{type}" if name || label || value || hint
|
18
|
+
puts " name, label, value: #{name}" if name
|
19
|
+
puts " hint: #{hint}" if hint
|
20
|
+
elsif name == label
|
21
|
+
puts "#{type}" if name || label || value || hint
|
22
|
+
puts " name, label: #{name}" if name
|
23
|
+
puts " value: #{value}" if value
|
24
|
+
puts " hint: #{hint}" if hint
|
25
|
+
elsif name == value
|
26
|
+
puts "#{type}" if name || label || value || hint
|
27
|
+
puts " name, value: #{name}" if name
|
28
|
+
puts " label: #{label}" if label
|
29
|
+
puts " hint: #{hint}" if hint
|
30
|
+
else
|
31
|
+
puts "#{type}" if name || label || value || hint
|
32
|
+
puts " name: #{name}" if name
|
33
|
+
puts " label: #{label}" if label
|
34
|
+
puts " value: #{value}" if value
|
35
|
+
puts " hint: #{hint}" if hint
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
3
39
|
# iOS only. On Android uiautomator always returns an empty string for EditText password.
|
4
40
|
#
|
5
41
|
# Password character returned from value of UIASecureTextField
|
@@ -143,14 +179,13 @@ module Appium
|
|
143
179
|
parser.parse s
|
144
180
|
parser.document.result
|
145
181
|
else
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
else
|
152
|
-
get_page source_window(window_number || 0), class_name
|
182
|
+
|
183
|
+
s = source_window(window_number || 0)
|
184
|
+
parser = Nokogiri::XML::SAX::Parser.new(UITestElementsPrinter.new)
|
185
|
+
if class_name
|
186
|
+
parser.document.filter = class_name.is_a?(Symbol) ? class_name.to_s : class_name
|
153
187
|
end
|
188
|
+
parser.parse s
|
154
189
|
nil
|
155
190
|
end
|
156
191
|
end
|
@@ -158,12 +193,13 @@ module Appium
|
|
158
193
|
# Gets the JSON source of window number
|
159
194
|
# @param window_number [Integer] the int index of the target window
|
160
195
|
# @return [JSON]
|
161
|
-
def source_window(
|
196
|
+
def source_window(_window_number = 0)
|
197
|
+
# TODO: update comments
|
162
198
|
# appium 1.0 still returns JSON when getTree() is invoked so this
|
163
199
|
# doesn't need to change to XML. If getTree() is removed then
|
164
200
|
# source_window will need to parse the elements of getTreeForXML()\
|
165
201
|
# https://github.com/appium/appium-uiauto/blob/247eb71383fa1a087ff8f8fc96fac25025731f3f/uiauto/appium/element.js#L145
|
166
|
-
|
202
|
+
get_source
|
167
203
|
end
|
168
204
|
|
169
205
|
# Prints parsed page source to console.
|
@@ -181,14 +217,18 @@ module Appium
|
|
181
217
|
# @param id [String] the id to search for
|
182
218
|
# @return [Element]
|
183
219
|
def id(id)
|
184
|
-
find_element
|
220
|
+
find_element(:id, id)
|
185
221
|
end
|
186
222
|
|
187
223
|
# Return the iOS version as an array of integers
|
188
224
|
# @return [Array<Integer>]
|
189
225
|
def ios_version
|
190
|
-
|
191
|
-
|
226
|
+
if automation_name_is_xcuitest?
|
227
|
+
@driver.capabilities['platformVersion']
|
228
|
+
else
|
229
|
+
ios_version = execute_script 'UIATarget.localTarget().systemVersion()'
|
230
|
+
ios_version.split('.').map(&:to_i)
|
231
|
+
end
|
192
232
|
end
|
193
233
|
|
194
234
|
# Get the element of type class_name at matching index.
|
@@ -213,7 +253,15 @@ module Appium
|
|
213
253
|
|
214
254
|
# @private
|
215
255
|
def string_attr_exact(class_name, attr, value)
|
216
|
-
|
256
|
+
if automation_name_is_xcuitest?
|
257
|
+
if attr == '*'
|
258
|
+
%((//#{class_name})[@*[.='#{value}']])
|
259
|
+
else
|
260
|
+
%((//#{class_name})[@#{attr}='#{value}'])
|
261
|
+
end
|
262
|
+
else
|
263
|
+
%(//#{class_name}[@visible="true" and @#{attr}='#{value}'])
|
264
|
+
end
|
217
265
|
end
|
218
266
|
|
219
267
|
# Find the first element exactly matching class and attribute value.
|
@@ -238,7 +286,15 @@ module Appium
|
|
238
286
|
|
239
287
|
# @private
|
240
288
|
def string_attr_include(class_name, attr, value)
|
241
|
-
|
289
|
+
if automation_name_is_xcuitest?
|
290
|
+
if attr == '*'
|
291
|
+
%((//#{class_name})[@*[contains(translate(., '#{value.upcase}', '#{value}'), '#{value}')]])
|
292
|
+
else
|
293
|
+
%((//#{class_name})[contains(translate(@#{attr}, '#{value.upcase}', '#{value}'), '#{value}')])
|
294
|
+
end
|
295
|
+
else
|
296
|
+
%(//#{class_name}[@visible="true" and contains(translate(@#{attr},'#{value.upcase}', '#{value}'), '#{value}')])
|
297
|
+
end
|
242
298
|
end
|
243
299
|
|
244
300
|
# Get the first tag by attribute that exactly matches value.
|
@@ -265,15 +321,24 @@ module Appium
|
|
265
321
|
# @param class_name [String] the tag to match
|
266
322
|
# @return [Element]
|
267
323
|
def first_ele(class_name)
|
268
|
-
|
269
|
-
|
324
|
+
if automation_name_is_xcuitest?
|
325
|
+
@driver.find_element :class, class_name
|
326
|
+
else
|
327
|
+
ele_index class_name, 1
|
328
|
+
end
|
270
329
|
end
|
271
330
|
|
272
331
|
# Get the last tag that matches class_name
|
273
332
|
# @param class_name [String] the tag to match
|
274
333
|
# @return [Element]
|
275
334
|
def last_ele(class_name)
|
276
|
-
|
335
|
+
if automation_name_is_xcuitest?
|
336
|
+
result = @driver.find_elements :xpath, "(//#{class_name})"
|
337
|
+
fail _no_such_element if result.empty?
|
338
|
+
result.last
|
339
|
+
else
|
340
|
+
ele_index class_name, 'last()'
|
341
|
+
end
|
277
342
|
end
|
278
343
|
|
279
344
|
# Returns the first visible element matching class_name
|
@@ -281,10 +346,11 @@ module Appium
|
|
281
346
|
# @param class_name [String] the class_name to search for
|
282
347
|
# @return [Element]
|
283
348
|
def tag(class_name)
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
349
|
+
if automation_name_is_xcuitest?
|
350
|
+
first_ele(class_name)
|
351
|
+
else
|
352
|
+
ele_by_json(typeArray: [class_name], onlyVisible: true)
|
353
|
+
end
|
288
354
|
end
|
289
355
|
|
290
356
|
# Returns all visible elements matching class_name
|
@@ -292,10 +358,11 @@ module Appium
|
|
292
358
|
# @param class_name [String] the class_name to search for
|
293
359
|
# @return [Element]
|
294
360
|
def tags(class_name)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
361
|
+
if automation_name_is_xcuitest?
|
362
|
+
@driver.find_elements :class, class_name
|
363
|
+
else
|
364
|
+
eles_by_json(typeArray: [class_name], onlyVisible: true)
|
365
|
+
end
|
299
366
|
end
|
300
367
|
|
301
368
|
# @private
|
@@ -322,7 +389,8 @@ module Appium
|
|
322
389
|
}
|
323
390
|
end
|
324
391
|
|
325
|
-
# Find the first element that contains value
|
392
|
+
# Find the first element that contains value.
|
393
|
+
# For Appium(automation name), not XCUITest
|
326
394
|
# @param element [String] the class name for the element
|
327
395
|
# @param value [String] the value to search for
|
328
396
|
# @return [Element]
|
@@ -331,6 +399,7 @@ module Appium
|
|
331
399
|
end
|
332
400
|
|
333
401
|
# Find all elements containing value
|
402
|
+
# For Appium(automation name), not XCUITest
|
334
403
|
# @param element [String] the class name for the element
|
335
404
|
# @param value [String] the value to search for
|
336
405
|
# @return [Array<Element>]
|
@@ -360,6 +429,7 @@ module Appium
|
|
360
429
|
end
|
361
430
|
|
362
431
|
# Find the first element exactly matching value
|
432
|
+
# For Appium(automation name), not XCUITest
|
363
433
|
# @param element [String] the class name for the element
|
364
434
|
# @param value [String] the value to search for
|
365
435
|
# @return [Element]
|
@@ -368,6 +438,7 @@ module Appium
|
|
368
438
|
end
|
369
439
|
|
370
440
|
# Find all elements exactly matching value
|
441
|
+
# For Appium(automation name), not XCUITest
|
371
442
|
# @param element [String] the class name for the element
|
372
443
|
# @param value [String] the value to search for
|
373
444
|
# @return [Element]
|
@@ -376,6 +447,7 @@ module Appium
|
|
376
447
|
end
|
377
448
|
|
378
449
|
# @private
|
450
|
+
# For Appium(automation name), not XCUITest
|
379
451
|
# If there's no keyboard, then do nothing.
|
380
452
|
# If there's no close key, fallback to window tap.
|
381
453
|
# If close key is present then tap it.
|
@@ -489,6 +561,7 @@ module Appium
|
|
489
561
|
end
|
490
562
|
end
|
491
563
|
|
564
|
+
# For Appium(automation name), not XCUITest
|
492
565
|
# typeArray - array of string types to search for. Example: ["UIAStaticText"]
|
493
566
|
# onlyFirst - boolean. returns only the first result if true. Example: true
|
494
567
|
# onlyVisible - boolean. returns only visible elements if true. Example: true
|
@@ -539,15 +612,15 @@ module Appium
|
|
539
612
|
# $._elementOrElementsByType will validate that the window isn't nil
|
540
613
|
element_or_elements_by_type = <<-JS
|
541
614
|
(function() {
|
542
|
-
|
543
|
-
|
615
|
+
var opts = #{opts.to_json};
|
616
|
+
var result = false;
|
544
617
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
618
|
+
try {
|
619
|
+
result = $._elementOrElementsByType($.mainWindow(), opts);
|
620
|
+
} catch (e) {
|
621
|
+
}
|
549
622
|
|
550
|
-
|
623
|
+
return result;
|
551
624
|
})();
|
552
625
|
JS
|
553
626
|
|
@@ -555,6 +628,7 @@ module Appium
|
|
555
628
|
res ? res : fail(Selenium::Client::CommandError, 'mainWindow is nil')
|
556
629
|
end
|
557
630
|
|
631
|
+
# For Appium(automation name), not XCUITest
|
558
632
|
# example usage:
|
559
633
|
#
|
560
634
|
# eles_by_json({
|