appium_lib 9.5.0 → 9.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|