appium_lib 9.3.3 → 9.3.4
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 +13 -0
- data/appium_lib.gemspec +1 -2
- data/docs/android_docs.md +247 -239
- data/docs/android_uiautomator.md +7 -0
- data/docs/ios_docs.md +333 -269
- data/docs/ios_xcuitest.md +18 -4
- data/ios_tests/lib/ios/specs/common/helper.rb +29 -1
- data/ios_tests/lib/ios/specs/device/device.rb +5 -0
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +6 -3
- data/ios_tests/lib/ios/specs/ios/helper.rb +14 -5
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/device/device.rb +15 -3
- data/lib/appium_lib/driver.rb +3 -3
- data/lib/appium_lib/ios/element/button.rb +4 -4
- data/lib/appium_lib/ios/element/generic.rb +2 -30
- data/lib/appium_lib/ios/element/text.rb +4 -4
- data/lib/appium_lib/ios/element/textfield.rb +12 -17
- data/lib/appium_lib/ios/helper.rb +78 -10
- data/release_notes.md +6 -0
- metadata +6 -25
data/docs/ios_xcuitest.md
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
- Mapping
|
14
14
|
- https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBElementTypeTransformer.m#L19
|
15
15
|
|
16
|
-
### with except for XPath
|
16
|
+
### with except for XPath and Predicate
|
17
17
|
#### examples
|
18
18
|
- [button_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/button.rb#L8), [static_text_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/text.rb#L8), [text_field_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/textfield.rb#L10) and [secure_text_field_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/textfield.rb#L15) provide class name.
|
19
19
|
- If `automationName` is `Appium` or `nil`, then they provide `UIAxxxx`
|
@@ -36,6 +36,22 @@ find_element(:accessibility_id, element) # Return a element which has accessibil
|
|
36
36
|
buttons(value) # Return button elements include `value` as its name attributes.
|
37
37
|
```
|
38
38
|
|
39
|
+
### with Predicate
|
40
|
+
- We recommend to use predicate strategy instead of XPath strategy.
|
41
|
+
- e.g. `find_ele_by_predicate/find_eles_by_predicate`, `find_ele_by_predicate_include/find_eles_by_predicate_include`
|
42
|
+
- A helpful cheatsheet for predicate
|
43
|
+
- https://realm.io/news/nspredicate-cheatsheet/
|
44
|
+
- For XCUITest(WebDriverAgent), without 'wd' prefixes are supported.
|
45
|
+
- https://github.com/facebook/WebDriverAgent/wiki/Queries
|
46
|
+
- For example, `%(name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}")` is equal to `%(wdName ==[c] "#{value}" || wdLabel ==[c] "#{value}" || wdValue ==[c] "#{value}")` in WebDriverAgent.
|
47
|
+
|
48
|
+
#### examples
|
49
|
+
- `textfield/s(value)`, `find/s`, `find_exact/finds_exact`, `find_ele_by_predicate/find_eles_by_predicate` and `find_ele_by_predicate_include/find_eles_by_predicate_include` use predicate strategy in their method.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
textfield(value) # Return a XCUIElementTypeSecureTextField or XCUIElementTypeTextField element which has `value` text.
|
53
|
+
finds_exact(value) # Return any elements include `value` as its name attributes.
|
54
|
+
```
|
39
55
|
|
40
56
|
### with XPath
|
41
57
|
- It is better to avoid XPath strategy.
|
@@ -48,11 +64,9 @@ buttons(value) # Return button elements include `value` as its name attributes.
|
|
48
64
|
- https://github.com/facebook/WebDriverAgent/blob/2158a8d0f305549532f1338fe1e4628cfbd53cd9/WebDriverAgentLib/Categories/XCElementSnapshot%2BFBHelpers.m#L57
|
49
65
|
|
50
66
|
#### examples
|
51
|
-
- `textfield/s(value)`, `find/s`, `find_exact/finds_exact` uses XPath in their method. So, these methods are slower than other find_element directly.
|
52
67
|
|
53
68
|
```ruby
|
54
|
-
|
55
|
-
finds_exact(value) # Return any elements include `value` as its name attributes.
|
69
|
+
xpaths("//some xpaths")
|
56
70
|
```
|
57
71
|
|
58
72
|
## Other actions
|
@@ -125,6 +125,22 @@ describe 'common/helper.rb' do
|
|
125
125
|
set_wait
|
126
126
|
end
|
127
127
|
|
128
|
+
t 'find_ele_by_predicate' do
|
129
|
+
el_text = find_ele_by_predicate(value: uibutton_text).text
|
130
|
+
el_text.must_equal uibutton_text
|
131
|
+
|
132
|
+
el_name = find_ele_by_predicate(value: uibutton_text).name
|
133
|
+
el_name.must_equal uibutton_text
|
134
|
+
end
|
135
|
+
|
136
|
+
t 'find_eles_by_predicate' do
|
137
|
+
ele_count = find_eles_by_predicate(value: uibutton_text).length
|
138
|
+
ele_count.must_equal 1
|
139
|
+
|
140
|
+
ele_count = find_eles_by_predicate(value: 'zz').length
|
141
|
+
ele_count.must_equal 0
|
142
|
+
end
|
143
|
+
|
128
144
|
# TODO: 'string_attr_include'
|
129
145
|
|
130
146
|
t 'find_ele_by_attr_include' do
|
@@ -141,6 +157,18 @@ describe 'common/helper.rb' do
|
|
141
157
|
ele_count.must_equal expected
|
142
158
|
end
|
143
159
|
|
160
|
+
t 'find_ele_by_predicate_include' do
|
161
|
+
el_text = find_ele_by_predicate_include(value: 'button').text
|
162
|
+
el_text.must_equal uibutton_text
|
163
|
+
|
164
|
+
el_name = find_ele_by_predicate_include(value: 'button').name
|
165
|
+
el_name.must_equal uibutton_text
|
166
|
+
end
|
167
|
+
|
168
|
+
t 'find_eles_by_predicate_include' do
|
169
|
+
find_eles_by_predicate_include(value: 'e').length.must_equal 21
|
170
|
+
end
|
171
|
+
|
144
172
|
t 'first_ele' do
|
145
173
|
first_ele(UI::Inventory.static_text).name.must_equal 'UICatalog'
|
146
174
|
end
|
@@ -174,7 +202,7 @@ describe 'common/helper.rb' do
|
|
174
202
|
tags(UI::Inventory.table_cell).length.must_equal 12
|
175
203
|
end
|
176
204
|
|
177
|
-
t '
|
205
|
+
t 'find_eles_by_attr_include_length' do
|
178
206
|
find_eles_by_attr_include(UI::Inventory.static_text, 'name', 'Use').length.must_equal 7
|
179
207
|
end
|
180
208
|
|
@@ -52,6 +52,11 @@ describe 'device/device' do
|
|
52
52
|
tag(UI::Inventory.navbar).name.must_equal 'UICatalog'
|
53
53
|
end
|
54
54
|
|
55
|
+
t 'background_app homescreen' do
|
56
|
+
background_app(-1) # background_app(nil) should work as same.
|
57
|
+
screen.must_raise ::Selenium::WebDriver::Error::NoSuchElementError
|
58
|
+
end
|
59
|
+
|
55
60
|
t 'reset' do
|
56
61
|
reset
|
57
62
|
end
|
@@ -34,10 +34,13 @@ describe 'ios/element/textfield' do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
t 'predicate textfields' do
|
37
|
-
|
37
|
+
textfields = if UI::Inventory.xcuitest?
|
38
|
+
find_elements(:predicate, "type contains[c] 'textfield'")
|
39
|
+
else
|
40
|
+
execute_script(%(au.mainApp().getAllWithPredicate("type contains[c] 'textfield'", true)))
|
41
|
+
end
|
38
42
|
|
39
|
-
|
40
|
-
textfield_count.must_equal 4
|
43
|
+
textfields.length.must_equal 4
|
41
44
|
end
|
42
45
|
|
43
46
|
t 'first_textfield' do
|
@@ -32,19 +32,28 @@ describe 'ios/helper' do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
t 'tags_include' do
|
35
|
+
elements = tags_include class_names: %w(XCUIElementTypeTextView)
|
36
|
+
elements.length.must_equal 0
|
37
|
+
|
35
38
|
elements = tags_include class_names: %w(XCUIElementTypeTextView XCUIElementTypeStaticText)
|
36
|
-
elements.length.
|
39
|
+
elements.length.must_equal 24
|
37
40
|
|
38
41
|
elements = tags_include class_names: %w(XCUIElementTypeTextView XCUIElementTypeStaticText), value: 'u'
|
39
|
-
elements.length.
|
42
|
+
elements.length.must_equal 13
|
40
43
|
end
|
41
44
|
|
42
|
-
t '
|
45
|
+
t 'tags_exact' do
|
46
|
+
elements = tags_exact class_names: %w()
|
47
|
+
elements.length.must_equal 0
|
48
|
+
|
49
|
+
elements = tags_exact class_names: %w(XCUIElementTypeStaticText)
|
50
|
+
elements.length.must_equal 24
|
51
|
+
|
43
52
|
elements = tags_exact class_names: %w(XCUIElementTypeTextView XCUIElementTypeStaticText)
|
44
|
-
elements.length.
|
53
|
+
elements.length.must_equal 24
|
45
54
|
|
46
55
|
elements = tags_exact class_names: %w(XCUIElementTypeTextView XCUIElementTypeStaticText), value: 'Buttons'
|
47
|
-
elements.length.
|
56
|
+
elements.length.must_equal 1
|
48
57
|
elements.first.value.must_equal 'Buttons'
|
49
58
|
end
|
50
59
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Appium
|
2
2
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
3
|
-
VERSION = '9.3.
|
4
|
-
DATE = '2017-
|
3
|
+
VERSION = '9.3.4'.freeze unless defined? ::Appium::VERSION
|
4
|
+
DATE = '2017-03-16'.freeze unless defined? ::Appium::DATE
|
5
5
|
end
|
@@ -13,7 +13,13 @@ module Appium
|
|
13
13
|
# @!method background_app
|
14
14
|
# Backgrounds the app for a set number of seconds.
|
15
15
|
# This is a blocking application
|
16
|
-
# @param seconds
|
16
|
+
# @param [Integer] seconds How many seconds to background the app for.
|
17
|
+
#
|
18
|
+
# ```ruby
|
19
|
+
# background_app
|
20
|
+
# background_app(5)
|
21
|
+
# background_app(-1) #=> the app never come back. https://github.com/appium/appium/issues/7741
|
22
|
+
# ```
|
17
23
|
|
18
24
|
# @!method current_activity
|
19
25
|
|
@@ -202,8 +208,14 @@ module Appium
|
|
202
208
|
end
|
203
209
|
|
204
210
|
add_endpoint_method(:background_app) do
|
205
|
-
def background_app(duration)
|
206
|
-
|
211
|
+
def background_app(duration = 0)
|
212
|
+
# https://github.com/appium/ruby_lib/issues/500, https://github.com/appium/appium/issues/7741
|
213
|
+
if $driver.automation_name_is_xcuitest? && $driver.appium_server_status['build']['version'] >= '1.6.4'
|
214
|
+
duration_milli_sec = duration.nil? ? nil : duration * 1000
|
215
|
+
execute :background_app, {}, seconds: { timeout: duration_milli_sec }
|
216
|
+
else
|
217
|
+
execute :background_app, {}, seconds: duration
|
218
|
+
end
|
207
219
|
end
|
208
220
|
end
|
209
221
|
|
data/lib/appium_lib/driver.rb
CHANGED
@@ -299,7 +299,7 @@ module Appium
|
|
299
299
|
# If automation_name is nil, it is not set both client side and server side.
|
300
300
|
attr_reader :automation_name
|
301
301
|
# Appium's server version
|
302
|
-
attr_reader :
|
302
|
+
attr_reader :appium_server_status
|
303
303
|
# Boolean debug mode for the Appium Ruby bindings
|
304
304
|
attr_accessor :appium_debug
|
305
305
|
# instance of AbstractEventListener for logging support
|
@@ -476,7 +476,7 @@ module Appium
|
|
476
476
|
# If the Appium server is under REQUIRED_VERSION_XCUITEST, then error is raised.
|
477
477
|
# @return [Boolean]
|
478
478
|
def check_server_version_xcuitest
|
479
|
-
if automation_name_is_xcuitest? && (@
|
479
|
+
if automation_name_is_xcuitest? && (@appium_server_status['build']['version'] < REQUIRED_VERSION_XCUITEST)
|
480
480
|
raise Appium::Error::NotSupportedAppiumServer, "XCUITest requires Appium version >= #{REQUIRED_VERSION_XCUITEST}"
|
481
481
|
end
|
482
482
|
true
|
@@ -618,7 +618,7 @@ module Appium
|
|
618
618
|
raise "ERROR: Unable to connect to Appium. Is the server running on #{server_url}?"
|
619
619
|
end
|
620
620
|
|
621
|
-
@
|
621
|
+
@appium_server_status = appium_server_version
|
622
622
|
|
623
623
|
check_server_version_xcuitest
|
624
624
|
set_automation_name_if_nil
|
@@ -32,8 +32,8 @@ module Appium
|
|
32
32
|
return tags button_class unless value
|
33
33
|
|
34
34
|
if automation_name_is_xcuitest?
|
35
|
-
|
36
|
-
|
35
|
+
elements = find_eles_by_predicate_include(class_name: button_class, value: value)
|
36
|
+
select_visible_elements elements
|
37
37
|
else
|
38
38
|
eles_by_json_visible_contains button_class, value
|
39
39
|
end
|
@@ -69,8 +69,8 @@ module Appium
|
|
69
69
|
# @return [Array<UIAButton|XCUIElementTypeButton>]
|
70
70
|
def buttons_exact(value)
|
71
71
|
if automation_name_is_xcuitest?
|
72
|
-
|
73
|
-
|
72
|
+
elements = find_eles_by_predicate(class_name: button_class, value: value)
|
73
|
+
select_visible_elements elements
|
74
74
|
else
|
75
75
|
eles_by_json_visible_exact button_class, value
|
76
76
|
end
|
@@ -16,7 +16,7 @@ module Appium
|
|
16
16
|
# @return [Array<Element>]
|
17
17
|
def finds(value)
|
18
18
|
if automation_name_is_xcuitest?
|
19
|
-
elements =
|
19
|
+
elements = find_eles_by_predicate_include value: value
|
20
20
|
select_visible_elements elements
|
21
21
|
else
|
22
22
|
eles_by_json_visible_contains '*', value
|
@@ -39,7 +39,7 @@ module Appium
|
|
39
39
|
# @return [Array<Element>]
|
40
40
|
def finds_exact(value)
|
41
41
|
if automation_name_is_xcuitest?
|
42
|
-
elements =
|
42
|
+
elements = find_eles_by_predicate value: value
|
43
43
|
select_visible_elements elements
|
44
44
|
else
|
45
45
|
eles_by_json_visible_exact '*', value
|
@@ -54,34 +54,6 @@ module Appium
|
|
54
54
|
element
|
55
55
|
end
|
56
56
|
|
57
|
-
# Return all elements include not displayed elements.
|
58
|
-
def elements_include(elements, value)
|
59
|
-
return [] if elements.empty?
|
60
|
-
elements.select do |element|
|
61
|
-
# `text` is equal to `value` if value is not `nil`
|
62
|
-
# `text` is equal to `name` if value is `nil`
|
63
|
-
name = element.name
|
64
|
-
text = element.value
|
65
|
-
name_result = name.nil? ? false : name.downcase.include?(value.downcase)
|
66
|
-
text_result = text.nil? ? false : text.downcase.include?(value.downcase)
|
67
|
-
name_result || text_result
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Return all elements include not displayed elements.
|
72
|
-
def elements_exact(elements, value)
|
73
|
-
return [] if elements.empty?
|
74
|
-
elements.select do |element|
|
75
|
-
# `text` is equal to `value` if value is not `nil`
|
76
|
-
# `text` is equal to `name` if value is `nil`
|
77
|
-
name = element.name
|
78
|
-
text = element.value
|
79
|
-
name_result = name.nil? ? false : name.casecmp(value).zero?
|
80
|
-
text_result = text.nil? ? false : text.casecmp(value).zero?
|
81
|
-
name_result || text_result
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
57
|
# Return visible elements.
|
86
58
|
def select_visible_elements(elements)
|
87
59
|
elements.select(&:displayed?)
|
@@ -31,8 +31,8 @@ module Appium
|
|
31
31
|
return tags static_text_class unless value
|
32
32
|
|
33
33
|
if automation_name_is_xcuitest?
|
34
|
-
|
35
|
-
|
34
|
+
elements = find_eles_by_predicate_include(class_name: static_text_class, value: value)
|
35
|
+
select_visible_elements elements
|
36
36
|
else
|
37
37
|
eles_by_json_visible_contains static_text_class, value
|
38
38
|
end
|
@@ -66,8 +66,8 @@ module Appium
|
|
66
66
|
# @return [Array<UIAStaticText|XCUIElementTypeStaticText>]
|
67
67
|
def texts_exact(value)
|
68
68
|
if automation_name_is_xcuitest?
|
69
|
-
|
70
|
-
|
69
|
+
elements = find_eles_by_predicate(class_name: static_text_class, value: value)
|
70
|
+
select_visible_elements elements
|
71
71
|
else
|
72
72
|
eles_by_json_visible_exact static_text_class, value
|
73
73
|
end
|
@@ -20,20 +20,14 @@ module Appium
|
|
20
20
|
|
21
21
|
# @private
|
22
22
|
# for XCUITest
|
23
|
-
def
|
24
|
-
|
23
|
+
def _textfield_with_predicate
|
24
|
+
raise_error_if_no_element _textfields_with_predicate.first
|
25
25
|
end
|
26
26
|
|
27
27
|
# @private
|
28
28
|
# for XCUITest
|
29
|
-
def
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
# @private
|
34
|
-
# for XCUITest
|
35
|
-
def _textfields_with_xpath
|
36
|
-
elements = xpaths "//#{_textfields}"
|
29
|
+
def _textfields_with_predicate
|
30
|
+
elements = tags_include(class_names: [text_field_class, secure_text_field_class])
|
37
31
|
select_visible_elements elements
|
38
32
|
end
|
39
33
|
|
@@ -67,9 +61,9 @@ module Appium
|
|
67
61
|
if value.is_a? Numeric
|
68
62
|
index = value
|
69
63
|
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
70
|
-
index -= 1 # eles_by_json and
|
64
|
+
index -= 1 # eles_by_json and _textfields_with_predicate is 0 indexed.
|
71
65
|
result = if automation_name_is_xcuitest?
|
72
|
-
|
66
|
+
_textfields_with_predicate[index]
|
73
67
|
else
|
74
68
|
eles_by_json(_textfield_visible)[index]
|
75
69
|
end
|
@@ -91,8 +85,9 @@ module Appium
|
|
91
85
|
# @return [Array<TextField>]
|
92
86
|
def textfields(value = false)
|
93
87
|
if automation_name_is_xcuitest?
|
94
|
-
return
|
95
|
-
|
88
|
+
return tags_include(class_names: [text_field_class, secure_text_field_class]) unless value
|
89
|
+
|
90
|
+
elements = tags_include class_names: [text_field_class, secure_text_field_class], value: value
|
96
91
|
select_visible_elements elements
|
97
92
|
else
|
98
93
|
return eles_by_json _textfield_visible unless value
|
@@ -104,7 +99,7 @@ module Appium
|
|
104
99
|
# @return [TextField]
|
105
100
|
def first_textfield
|
106
101
|
if automation_name_is_xcuitest?
|
107
|
-
|
102
|
+
_textfield_with_predicate
|
108
103
|
else
|
109
104
|
ele_by_json _textfield_visible
|
110
105
|
end
|
@@ -114,7 +109,7 @@ module Appium
|
|
114
109
|
# @return [TextField]
|
115
110
|
def last_textfield
|
116
111
|
result = if automation_name_is_xcuitest?
|
117
|
-
|
112
|
+
_textfields_with_predicate.last
|
118
113
|
else
|
119
114
|
eles_by_json(_textfield_visible).last
|
120
115
|
end
|
@@ -138,7 +133,7 @@ module Appium
|
|
138
133
|
# @return [Array<TextField>]
|
139
134
|
def textfields_exact(value)
|
140
135
|
if automation_name_is_xcuitest?
|
141
|
-
elements =
|
136
|
+
elements = tags_exact class_names: [text_field_class, secure_text_field_class], value: value
|
142
137
|
select_visible_elements elements
|
143
138
|
else
|
144
139
|
eles_by_json _textfield_exact_string value
|
@@ -273,6 +273,31 @@ module Appium
|
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
276
|
+
# Find the first element exactly matching attribute case insensitive value.
|
277
|
+
# Note: Uses Predicate
|
278
|
+
# @param value [String] the expected value of the attribute
|
279
|
+
# @return [Element]
|
280
|
+
def find_ele_by_predicate(class_name: '*', value:)
|
281
|
+
elements = find_eles_by_predicate(class_name: class_name, value: value)
|
282
|
+
raise _no_such_element if elements.empty?
|
283
|
+
elements.first
|
284
|
+
end
|
285
|
+
|
286
|
+
# Find all elements exactly matching attribute case insensitive value.
|
287
|
+
# Note: Uses Predicate
|
288
|
+
# @param value [String] the value of the attribute that the element must have
|
289
|
+
# @param class_name [String] the tag name to match
|
290
|
+
# @return [Array<Element>]
|
291
|
+
def find_eles_by_predicate(class_name: '*', value:)
|
292
|
+
predicate = if class_name == '*'
|
293
|
+
%(name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}")
|
294
|
+
else
|
295
|
+
%(type == "#{class_name}" && ) +
|
296
|
+
%((name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}"))
|
297
|
+
end
|
298
|
+
@driver.find_elements_with_appium :predicate, predicate
|
299
|
+
end
|
300
|
+
|
276
301
|
# Get the first tag by attribute that exactly matches value.
|
277
302
|
# Note: Uses XPath
|
278
303
|
# @param class_name [String] the tag name to match
|
@@ -293,6 +318,31 @@ module Appium
|
|
293
318
|
@driver.find_elements :xpath, string_attr_include(class_name, attr, value)
|
294
319
|
end
|
295
320
|
|
321
|
+
# Get the first elements that include insensitive value.
|
322
|
+
# Note: Uses Predicate
|
323
|
+
# @param value [String] the value of the attribute that the element must include
|
324
|
+
# @return [Element] the element of type tag who's attribute includes value
|
325
|
+
def find_ele_by_predicate_include(class_name: '*', value:)
|
326
|
+
elements = find_eles_by_predicate_include(class_name: class_name, value: value)
|
327
|
+
raise _no_such_element if elements.empty?
|
328
|
+
elements.first
|
329
|
+
end
|
330
|
+
|
331
|
+
# Get elements that include case insensitive value.
|
332
|
+
# Note: Uses Predicate
|
333
|
+
# @param value [String] the value of the attribute that the element must include
|
334
|
+
# @param class_name [String] the tag name to match
|
335
|
+
# @return [Array<Element>] the elements of type tag who's attribute includes value
|
336
|
+
def find_eles_by_predicate_include(class_name: '*', value:)
|
337
|
+
predicate = if class_name == '*'
|
338
|
+
%(name contains[c] "#{value}" || label contains[c] "#{value}" || value contains[c] "#{value}")
|
339
|
+
else
|
340
|
+
%(type == "#{class_name}" && ) +
|
341
|
+
%((name contains[c] "#{value}" || label contains[c] "#{value}" || value contains[c] "#{value}"))
|
342
|
+
end
|
343
|
+
@driver.find_elements_with_appium :predicate, predicate
|
344
|
+
end
|
345
|
+
|
296
346
|
# Get the first tag that matches class_name
|
297
347
|
# @param class_name [String] the tag to match
|
298
348
|
# @return [Element]
|
@@ -348,11 +398,20 @@ module Appium
|
|
348
398
|
def tags_include(class_names:, value: nil)
|
349
399
|
return unless class_names.is_a? Array
|
350
400
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
401
|
+
if automation_name_is_xcuitest?
|
402
|
+
c_names = class_names.map { |class_name| %(type == "#{class_name}") }.join(' || ')
|
403
|
+
|
404
|
+
predicate = if value
|
405
|
+
%((#{c_names}) && ) +
|
406
|
+
%((name contains[c] "#{value}" || label contains[c] "#{value}" || value contains[c] "#{value}"))
|
407
|
+
else
|
408
|
+
c_names
|
409
|
+
end
|
410
|
+
|
411
|
+
elements = @driver.find_elements_with_appium :predicate, predicate
|
412
|
+
select_visible_elements elements
|
413
|
+
else
|
414
|
+
class_names.flat_map do |class_name|
|
356
415
|
value ? eles_by_json_visible_contains(class_name, value) : tags(class_name)
|
357
416
|
end
|
358
417
|
end
|
@@ -368,11 +427,20 @@ module Appium
|
|
368
427
|
def tags_exact(class_names:, value: nil)
|
369
428
|
return unless class_names.is_a? Array
|
370
429
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
430
|
+
if automation_name_is_xcuitest?
|
431
|
+
c_names = class_names.map { |class_name| %(type == "#{class_name}") }.join(' || ')
|
432
|
+
|
433
|
+
predicate = if value
|
434
|
+
%((#{c_names}) && ) +
|
435
|
+
%((name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}"))
|
436
|
+
else
|
437
|
+
c_names
|
438
|
+
end
|
439
|
+
|
440
|
+
elements = @driver.find_elements_with_appium :predicate, predicate
|
441
|
+
select_visible_elements elements
|
442
|
+
else
|
443
|
+
class_names.flat_map do |class_name|
|
376
444
|
value ? eles_by_json_visible_exact(class_name, value) : tags(class_name)
|
377
445
|
end
|
378
446
|
end
|