appium_lib 9.5.0 → 9.6.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/CHANGELOG.md +33 -0
- data/docs/android_docs.md +512 -287
- data/docs/ios_docs.md +906 -315
- data/docs/ios_xcuitest.md +4 -0
- data/lib/appium_lib/android/device.rb +39 -0
- data/lib/appium_lib/android/element/button.rb +36 -65
- data/lib/appium_lib/android/element/generic.rb +20 -12
- data/lib/appium_lib/android/helper.rb +4 -16
- data/lib/appium_lib/android/uiautomator2/element/button.rb +110 -0
- data/lib/appium_lib/android/uiautomator2/helper.rb +85 -0
- data/lib/appium_lib/common/command.rb +9 -1
- data/lib/appium_lib/common/helper.rb +5 -4
- data/lib/appium_lib/common/patch.rb +21 -5
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/common/wait.rb +1 -0
- data/lib/appium_lib/device/device.rb +13 -23
- data/lib/appium_lib/device/multi_touch.rb +60 -20
- data/lib/appium_lib/device/touch_actions.rb +17 -8
- data/lib/appium_lib/driver.rb +79 -19
- data/lib/appium_lib/ios/element/button.rb +5 -25
- data/lib/appium_lib/ios/element/generic.rb +4 -22
- data/lib/appium_lib/ios/element/text.rb +5 -25
- data/lib/appium_lib/ios/element/textfield.rb +31 -78
- data/lib/appium_lib/ios/helper.rb +11 -74
- data/lib/appium_lib/ios/mobile_methods.rb +0 -20
- data/lib/appium_lib/ios/patch.rb +2 -6
- data/lib/appium_lib/ios/xcuitest/device.rb +59 -0
- data/lib/appium_lib/ios/xcuitest/element.rb +24 -0
- data/lib/appium_lib/ios/xcuitest/element/button.rb +64 -0
- data/lib/appium_lib/ios/xcuitest/element/generic.rb +50 -0
- data/lib/appium_lib/ios/xcuitest/element/text.rb +61 -0
- data/lib/appium_lib/ios/xcuitest/element/textfield.rb +94 -0
- data/lib/appium_lib/ios/{xcuitest_gestures.rb → xcuitest/gestures.rb} +10 -23
- data/lib/appium_lib/ios/xcuitest/helper.rb +103 -0
- data/lib/appium_lib/ios/xcuitest/mobile_methods.rb +23 -0
- data/release_notes.md +6 -0
- metadata +14 -3
data/docs/ios_xcuitest.md
CHANGED
@@ -8,6 +8,10 @@
|
|
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
|
+
|
11
15
|
## find elements
|
12
16
|
- supported elements by find_element are:
|
13
17
|
- [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver/blob/master/lib/commands/find.js#L17)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module Appium
|
4
|
+
module Android
|
5
|
+
module Device
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# @!method hide_keyboard
|
9
|
+
# Hide the onscreen keyboard
|
10
|
+
# @param [String] close_key The name of the key which closes the keyboard.
|
11
|
+
# Defaults to 'Done' for iOS(except for XCUITest).
|
12
|
+
# @param [Symbol] strategy The symbol of the strategy which closes the keyboard.
|
13
|
+
# XCUITest ignore this argument.
|
14
|
+
# Default for iOS is `:pressKey`. Default for Android is `:tapOutside`.
|
15
|
+
# ```ruby
|
16
|
+
# hide_keyboard # Close a keyboard with the 'Done' button
|
17
|
+
# hide_keyboard('Finished') # Close a keyboard with the 'Finished' button
|
18
|
+
# hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
|
19
|
+
# ```
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def extended(_mod)
|
23
|
+
::Appium::Device.extend_webdriver_with_forwardable
|
24
|
+
|
25
|
+
::Appium::Device.add_endpoint_method(:hide_keyboard) do
|
26
|
+
def hide_keyboard(close_key = nil, strategy = nil)
|
27
|
+
option = {}
|
28
|
+
|
29
|
+
option[:key] = close_key if close_key
|
30
|
+
option[:strategy] = strategy || :tapOutside # default to pressKey
|
31
|
+
|
32
|
+
execute :hide_keyboard, {}, option
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end # class << self
|
37
|
+
end # module Device
|
38
|
+
end # module Android
|
39
|
+
end # module Appium
|
@@ -1,38 +1,8 @@
|
|
1
|
-
# UIAButton methods
|
2
1
|
module Appium
|
3
2
|
module Android
|
4
3
|
Button = 'android.widget.Button'.freeze
|
5
4
|
ImageButton = 'android.widget.ImageButton'.freeze
|
6
5
|
|
7
|
-
private
|
8
|
-
|
9
|
-
def _button_visible_selectors(opts = {})
|
10
|
-
button_index = opts.fetch :button_index, false
|
11
|
-
image_button_index = opts.fetch :image_button_index, false
|
12
|
-
|
13
|
-
if button_index && image_button_index
|
14
|
-
"new UiSelector().className(#{Button}).instance(#{button_index});" \
|
15
|
-
"new UiSelector().className(#{ImageButton}).instance(#{image_button_index});"
|
16
|
-
else
|
17
|
-
"new UiSelector().className(#{Button});" \
|
18
|
-
"new UiSelector().className(#{ImageButton});"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def _button_exact_string(value)
|
23
|
-
button = string_visible_exact Button, value
|
24
|
-
image_button = string_visible_exact ImageButton, value
|
25
|
-
button + image_button
|
26
|
-
end
|
27
|
-
|
28
|
-
def _button_contains_string(value)
|
29
|
-
button = string_visible_contains Button, value
|
30
|
-
image_button = string_visible_contains ImageButton, value
|
31
|
-
button + image_button
|
32
|
-
end
|
33
|
-
|
34
|
-
public
|
35
|
-
|
36
6
|
# Find the first button that contains value or by index.
|
37
7
|
# @param value [String, Integer] the value to exactly match.
|
38
8
|
# If int then the button at that index is returned.
|
@@ -44,21 +14,10 @@ module Appium
|
|
44
14
|
index = value
|
45
15
|
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
46
16
|
|
47
|
-
|
48
|
-
return find_element :uiautomator, _button_visible_selectors(index: index)
|
49
|
-
end
|
50
|
-
|
51
|
-
result = find_elements :uiautomator, _button_visible_selectors(index: index)
|
52
|
-
raise _no_such_element if result.empty?
|
53
|
-
return result[value - 1]
|
17
|
+
return find_element :uiautomator, _button_visible_selectors(index: index)
|
54
18
|
end
|
55
19
|
|
56
|
-
|
57
|
-
elements = find_elements :uiautomator, _button_contains_string(value)
|
58
|
-
raise_no_such_element_if_empty(elements)
|
59
|
-
else
|
60
|
-
find_element :uiautomator, _button_contains_string(value)
|
61
|
-
end
|
20
|
+
find_element :uiautomator, _button_contains_string(value)
|
62
21
|
end
|
63
22
|
|
64
23
|
# Find all buttons containing value.
|
@@ -73,12 +32,7 @@ module Appium
|
|
73
32
|
# Find the first button.
|
74
33
|
# @return [Button]
|
75
34
|
def first_button
|
76
|
-
|
77
|
-
elements = find_elements :uiautomator, _button_visible_selectors(button_index: 0, image_button_index: 0)
|
78
|
-
raise_no_such_element_if_empty(elements)
|
79
|
-
else
|
80
|
-
find_element :uiautomator, _button_visible_selectors(button_index: 0, image_button_index: 0)
|
81
|
-
end
|
35
|
+
find_element :uiautomator, _button_visible_selectors(button_index: 0, image_button_index: 0)
|
82
36
|
end
|
83
37
|
|
84
38
|
# Find the last button.
|
@@ -91,28 +45,16 @@ module Appium
|
|
91
45
|
image_button_index = tags(ImageButton).length
|
92
46
|
image_button_index -= 1 if image_button_index > 0
|
93
47
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
image_button_index: image_button_index)
|
98
|
-
raise_no_such_element_if_empty(elements)
|
99
|
-
else
|
100
|
-
find_element :uiautomator,
|
101
|
-
_button_visible_selectors(button_index: button_index,
|
102
|
-
image_button_index: image_button_index)
|
103
|
-
end
|
48
|
+
find_element :uiautomator,
|
49
|
+
_button_visible_selectors(button_index: button_index,
|
50
|
+
image_button_index: image_button_index)
|
104
51
|
end
|
105
52
|
|
106
53
|
# Find the first button that exactly matches value.
|
107
54
|
# @param value [String] the value to match exactly
|
108
55
|
# @return [Button]
|
109
56
|
def button_exact(value)
|
110
|
-
|
111
|
-
elements = find_elements :uiautomator, _button_exact_string(value)
|
112
|
-
raise_no_such_element_if_empty(elements)
|
113
|
-
else
|
114
|
-
find_element :uiautomator, _button_exact_string(value)
|
115
|
-
end
|
57
|
+
find_element :uiautomator, _button_exact_string(value)
|
116
58
|
end
|
117
59
|
|
118
60
|
# Find all buttons that exactly match value.
|
@@ -124,9 +66,38 @@ module Appium
|
|
124
66
|
|
125
67
|
private
|
126
68
|
|
69
|
+
# @private
|
127
70
|
def raise_no_such_element_if_empty(elements)
|
128
71
|
raise _no_such_element if elements.empty?
|
129
72
|
elements.first
|
130
73
|
end
|
74
|
+
|
75
|
+
# @private
|
76
|
+
def _button_visible_selectors(opts = {})
|
77
|
+
button_index = opts.fetch :button_index, false
|
78
|
+
image_button_index = opts.fetch :image_button_index, false
|
79
|
+
|
80
|
+
if button_index && image_button_index
|
81
|
+
"new UiSelector().className(#{Button}).instance(#{button_index});" \
|
82
|
+
"new UiSelector().className(#{ImageButton}).instance(#{image_button_index});"
|
83
|
+
else
|
84
|
+
"new UiSelector().className(#{Button});" \
|
85
|
+
"new UiSelector().className(#{ImageButton});"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @private
|
90
|
+
def _button_exact_string(value)
|
91
|
+
button = string_visible_exact Button, value
|
92
|
+
image_button = string_visible_exact ImageButton, value
|
93
|
+
button + image_button
|
94
|
+
end
|
95
|
+
|
96
|
+
# @private
|
97
|
+
def _button_contains_string(value)
|
98
|
+
button = string_visible_contains Button, value
|
99
|
+
image_button = string_visible_contains ImageButton, value
|
100
|
+
button + image_button
|
101
|
+
end
|
131
102
|
end # module Android
|
132
103
|
end # module Appium
|
@@ -39,12 +39,16 @@ module Appium
|
|
39
39
|
# @return [Element] the element scrolled to
|
40
40
|
def scroll_to(text, scrollable_index = 0)
|
41
41
|
text = %("#{text}")
|
42
|
-
|
43
|
-
args =
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
rid = resource_id(text, "new UiSelector().resourceId(#{text});")
|
43
|
+
args = rid.empty? ? ["new UiSelector().textContains(#{text})", "new UiSelector().descriptionContains(#{text})"] : [rid]
|
44
|
+
args.each_with_index do |arg, index|
|
45
|
+
begin
|
46
|
+
elem = find_element :uiautomator, scroll_uiselector(arg, scrollable_index)
|
47
|
+
return elem
|
48
|
+
rescue => e
|
49
|
+
raise e if index == args.size - 1
|
50
|
+
end
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
54
|
# Scroll to the first element with the exact target text or description.
|
@@ -53,12 +57,16 @@ module Appium
|
|
53
57
|
# @return [Element] the element scrolled to
|
54
58
|
def scroll_to_exact(text, scrollable_index = 0)
|
55
59
|
text = %("#{text}")
|
56
|
-
|
57
|
-
args =
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
rid = resource_id(text, "new UiSelector().resourceId(#{text});")
|
61
|
+
args = rid.empty? ? ["new UiSelector().text(#{text})", "new UiSelector().description(#{text})"] : [rid]
|
62
|
+
args.each_with_index do |arg, index|
|
63
|
+
begin
|
64
|
+
elem = find_element :uiautomator, scroll_uiselector(arg, scrollable_index)
|
65
|
+
return elem
|
66
|
+
rescue => e
|
67
|
+
raise e if index == args.size - 1
|
68
|
+
end
|
69
|
+
end
|
62
70
|
end
|
63
71
|
end # module Android
|
64
72
|
end # module Appium
|
@@ -23,7 +23,7 @@ module Appium
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# http://nokogiri.org/Nokogiri/XML/SAX/Document.html
|
26
|
-
def start_element(name, attrs = [])
|
26
|
+
def start_element(name, attrs = [], driver = $driver)
|
27
27
|
return if filter && !name.downcase.include?(filter)
|
28
28
|
|
29
29
|
attributes = {}
|
@@ -34,7 +34,7 @@ module Appium
|
|
34
34
|
|
35
35
|
# scoped to: text resource-id content-desc
|
36
36
|
attributes_values = attributes.values
|
37
|
-
strings =
|
37
|
+
strings = driver.lazy_load_strings
|
38
38
|
id_matches = strings.empty? ? [] : strings.select { |_key, value| attributes_values.include? value }
|
39
39
|
|
40
40
|
string_ids = nil
|
@@ -285,13 +285,7 @@ module Appium
|
|
285
285
|
# @param value [String] the value to search for
|
286
286
|
# @return [Element]
|
287
287
|
def complex_find_contains(class_name, value)
|
288
|
-
|
289
|
-
elements = find_elements :uiautomator, string_visible_contains(class_name, value)
|
290
|
-
raise _no_such_element if elements.empty?
|
291
|
-
elements.first
|
292
|
-
else
|
293
|
-
find_element :uiautomator, string_visible_contains(class_name, value)
|
294
|
-
end
|
288
|
+
find_element :uiautomator, string_visible_contains(class_name, value)
|
295
289
|
end
|
296
290
|
|
297
291
|
# Find all elements containing value
|
@@ -343,13 +337,7 @@ module Appium
|
|
343
337
|
# @param value [String] the value to search for
|
344
338
|
# @return [Element]
|
345
339
|
def complex_find_exact(class_name, value)
|
346
|
-
|
347
|
-
elements = find_elements :uiautomator, string_visible_exact(class_name, value)
|
348
|
-
raise _no_such_element if elements.empty?
|
349
|
-
elements.first
|
350
|
-
else
|
351
|
-
find_element :uiautomator, string_visible_exact(class_name, value)
|
352
|
-
end
|
340
|
+
find_element :uiautomator, string_visible_exact(class_name, value)
|
353
341
|
end
|
354
342
|
|
355
343
|
# Find all elements exactly matching value
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Appium
|
2
|
+
module Android
|
3
|
+
module Uiautomator2
|
4
|
+
module Element
|
5
|
+
# Find the first button that contains value or by index.
|
6
|
+
# @param value [String, Integer] the value to exactly match.
|
7
|
+
# If int then the button at that index is returned.
|
8
|
+
# @return [Button]
|
9
|
+
def button(value)
|
10
|
+
# Don't use ele_index because that only works on one element type.
|
11
|
+
# Android needs to combine button and image button to match iOS.
|
12
|
+
if value.is_a? Numeric
|
13
|
+
index = value
|
14
|
+
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
15
|
+
|
16
|
+
result = find_elements :uiautomator, _button_visible_selectors(index: index)
|
17
|
+
raise _no_such_element if result.empty?
|
18
|
+
return result[value - 1]
|
19
|
+
end
|
20
|
+
|
21
|
+
elements = find_elements :uiautomator, _button_contains_string(value)
|
22
|
+
raise_no_such_element_if_empty(elements)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Find all buttons containing value.
|
26
|
+
# If value is omitted, all buttons are returned.
|
27
|
+
# @param value [String] the value to search for
|
28
|
+
# @return [Array<Button>]
|
29
|
+
def buttons(value = false)
|
30
|
+
return find_elements :uiautomator, _button_visible_selectors unless value
|
31
|
+
find_elements :uiautomator, _button_contains_string(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Find the first button.
|
35
|
+
# @return [Button]
|
36
|
+
def first_button
|
37
|
+
elements = find_elements :uiautomator, _button_visible_selectors(button_index: 0, image_button_index: 0)
|
38
|
+
raise_no_such_element_if_empty(elements)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find the last button.
|
42
|
+
# @return [Button]
|
43
|
+
def last_button
|
44
|
+
# uiautomator index doesn't support last
|
45
|
+
# and it's 0 indexed
|
46
|
+
button_index = tags(::Appium::Android::Button).length
|
47
|
+
button_index -= 1 if button_index > 0
|
48
|
+
image_button_index = tags(::Appium::Android::ImageButton).length
|
49
|
+
image_button_index -= 1 if image_button_index > 0
|
50
|
+
|
51
|
+
elements = find_elements :uiautomator,
|
52
|
+
_button_visible_selectors(button_index: button_index,
|
53
|
+
image_button_index: image_button_index)
|
54
|
+
raise_no_such_element_if_empty(elements)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Find the first button that exactly matches value.
|
58
|
+
# @param value [String] the value to match exactly
|
59
|
+
# @return [Button]
|
60
|
+
def button_exact(value)
|
61
|
+
elements = find_elements :uiautomator, _button_exact_string(value)
|
62
|
+
raise_no_such_element_if_empty(elements)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Find all buttons that exactly match value.
|
66
|
+
# @param value [String] the value to match exactly
|
67
|
+
# @return [Array<Button>]
|
68
|
+
def buttons_exact(value)
|
69
|
+
find_elements :uiautomator, _button_exact_string(value)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# @private
|
75
|
+
def raise_no_such_element_if_empty(elements)
|
76
|
+
raise _no_such_element if elements.empty?
|
77
|
+
elements.first
|
78
|
+
end
|
79
|
+
|
80
|
+
# @private
|
81
|
+
def _button_visible_selectors(opts = {})
|
82
|
+
button_index = opts.fetch :button_index, false
|
83
|
+
image_button_index = opts.fetch :image_button_index, false
|
84
|
+
|
85
|
+
if button_index && image_button_index
|
86
|
+
"new UiSelector().className(#{::Appium::Android::Button}).instance(#{button_index});" \
|
87
|
+
"new UiSelector().className(#{::Appium::Android::ImageButton}).instance(#{image_button_index});"
|
88
|
+
else
|
89
|
+
"new UiSelector().className(#{::Appium::Android::Button});" \
|
90
|
+
"new UiSelector().className(#{::Appium::Android::ImageButton});"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @private
|
95
|
+
def _button_exact_string(value)
|
96
|
+
button = string_visible_exact ::Appium::Android::Button, value
|
97
|
+
image_button = string_visible_exact ::Appium::Android::ImageButton, value
|
98
|
+
button + image_button
|
99
|
+
end
|
100
|
+
|
101
|
+
# @private
|
102
|
+
def _button_contains_string(value)
|
103
|
+
button = string_visible_contains ::Appium::Android::Button, value
|
104
|
+
image_button = string_visible_contains ::Appium::Android::ImageButton, value
|
105
|
+
button + image_button
|
106
|
+
end
|
107
|
+
end # module Element
|
108
|
+
end # module Uiautomator2
|
109
|
+
end # module Android
|
110
|
+
end # module Appium
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Appium
|
2
|
+
module Android
|
3
|
+
module Uiautomator2
|
4
|
+
module Helper
|
5
|
+
# Returns a string that matches the first element that contains value
|
6
|
+
# For automationName is Appium
|
7
|
+
# example: string_visible_contains 'UIATextField', 'sign in'
|
8
|
+
# note for XPath: https://github.com/appium/ruby_lib/pull/561
|
9
|
+
#
|
10
|
+
# @param class_name [String] the class name for the element
|
11
|
+
# @param value [String] the value to search for
|
12
|
+
# @return [String]
|
13
|
+
def string_visible_contains(class_name, value)
|
14
|
+
value = %("#{value}")
|
15
|
+
if class_name == '*'
|
16
|
+
return (resource_id(value, "new UiSelector().resourceId(#{value});") +
|
17
|
+
"new UiSelector().descriptionContains(#{value});" \
|
18
|
+
"new UiSelector().textContains(#{value});")
|
19
|
+
end
|
20
|
+
|
21
|
+
class_name = %("#{class_name}")
|
22
|
+
resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
|
23
|
+
"new UiSelector().className(#{class_name}).descriptionContains(#{value});" \
|
24
|
+
"new UiSelector().className(#{class_name}).textContains(#{value});"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Find the first element that contains value
|
28
|
+
# @param class_name [String] the class name for the element
|
29
|
+
# @param value [String] the value to search for
|
30
|
+
# @return [Element]
|
31
|
+
def complex_find_contains(class_name, value)
|
32
|
+
elements = find_elements :uiautomator, string_visible_contains(class_name, value)
|
33
|
+
raise _no_such_element if elements.empty?
|
34
|
+
elements.first
|
35
|
+
end
|
36
|
+
|
37
|
+
# Find all elements containing value
|
38
|
+
# @param class_name [String] the class name for the element
|
39
|
+
# @param value [String] the value to search for
|
40
|
+
# @return [Array<Element>]
|
41
|
+
def complex_finds_contains(class_name, value)
|
42
|
+
find_elements :uiautomator, string_visible_contains(class_name, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @private
|
46
|
+
# Create an string to exactly match the first element with target value
|
47
|
+
# @param class_name [String] the class name for the element
|
48
|
+
# @param value [String] the value to search for
|
49
|
+
# @return [String]
|
50
|
+
def string_visible_exact(class_name, value)
|
51
|
+
value = %("#{value}")
|
52
|
+
|
53
|
+
if class_name == '*'
|
54
|
+
return (resource_id(value, "new UiSelector().resourceId(#{value});") +
|
55
|
+
"new UiSelector().description(#{value});" \
|
56
|
+
"new UiSelector().text(#{value});")
|
57
|
+
end
|
58
|
+
|
59
|
+
class_name = %("#{class_name}")
|
60
|
+
resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
|
61
|
+
"new UiSelector().className(#{class_name}).description(#{value});" \
|
62
|
+
"new UiSelector().className(#{class_name}).text(#{value});"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Find the first element exactly matching value
|
66
|
+
# @param class_name [String] the class name for the element
|
67
|
+
# @param value [String] the value to search for
|
68
|
+
# @return [Element]
|
69
|
+
def complex_find_exact(class_name, value)
|
70
|
+
elements = find_elements :uiautomator, string_visible_exact(class_name, value)
|
71
|
+
raise _no_such_element if elements.empty?
|
72
|
+
elements.first
|
73
|
+
end
|
74
|
+
|
75
|
+
# Find all elements exactly matching value
|
76
|
+
# @param class_name [String] the class name for the element
|
77
|
+
# @param value [String] the value to search for
|
78
|
+
# @return [Element]
|
79
|
+
def complex_finds_exact(class_name, value)
|
80
|
+
find_elements :uiautomator, string_visible_exact(class_name, value)
|
81
|
+
end
|
82
|
+
end # module Helper
|
83
|
+
end # module Uiautomator2
|
84
|
+
end # module Android
|
85
|
+
end # module Appium
|