Skip to content

Commit 6c6e916

Browse files
authored
refactor: separate uiautomator2 (#642)
1 parent 2b1a5ee commit 6c6e916

File tree

5 files changed

+248
-80
lines changed

5 files changed

+248
-80
lines changed
+32-65
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,8 @@
1-
# UIAButton methods
21
module Appium
32
module Android
43
Button = 'android.widget.Button'.freeze
54
ImageButton = 'android.widget.ImageButton'.freeze
65

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-
366
# Find the first button that contains value or by index.
377
# @param value [String, Integer] the value to exactly match.
388
# If int then the button at that index is returned.
@@ -44,21 +14,10 @@ def button(value)
4414
index = value
4515
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
4616

47-
unless automation_name_is_uiautomator2?
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)
5418
end
5519

56-
if automation_name_is_uiautomator2?
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)
6221
end
6322

6423
# Find all buttons containing value.
@@ -73,12 +32,7 @@ def buttons(value = false)
7332
# Find the first button.
7433
# @return [Button]
7534
def first_button
76-
if automation_name_is_uiautomator2?
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)
8236
end
8337

8438
# Find the last button.
@@ -91,28 +45,16 @@ def last_button
9145
image_button_index = tags(ImageButton).length
9246
image_button_index -= 1 if image_button_index > 0
9347

94-
if automation_name_is_uiautomator2?
95-
elements = find_elements :uiautomator,
96-
_button_visible_selectors(button_index: button_index,
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)
10451
end
10552

10653
# Find the first button that exactly matches value.
10754
# @param value [String] the value to match exactly
10855
# @return [Button]
10956
def button_exact(value)
110-
if automation_name_is_uiautomator2?
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)
11658
end
11759

11860
# Find all buttons that exactly match value.
@@ -128,5 +70,30 @@ def raise_no_such_element_if_empty(elements)
12870
raise _no_such_element if elements.empty?
12971
elements.first
13072
end
73+
74+
def _button_visible_selectors(opts = {})
75+
button_index = opts.fetch :button_index, false
76+
image_button_index = opts.fetch :image_button_index, false
77+
78+
if button_index && image_button_index
79+
"new UiSelector().className(#{Button}).instance(#{button_index});" \
80+
"new UiSelector().className(#{ImageButton}).instance(#{image_button_index});"
81+
else
82+
"new UiSelector().className(#{Button});" \
83+
"new UiSelector().className(#{ImageButton});"
84+
end
85+
end
86+
87+
def _button_exact_string(value)
88+
button = string_visible_exact Button, value
89+
image_button = string_visible_exact ImageButton, value
90+
button + image_button
91+
end
92+
93+
def _button_contains_string(value)
94+
button = string_visible_contains Button, value
95+
image_button = string_visible_contains ImageButton, value
96+
button + image_button
97+
end
13198
end # module Android
13299
end # module Appium

lib/appium_lib/android/helper.rb

+2-14
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,7 @@ def string_visible_contains(class_name, value)
285285
# @param value [String] the value to search for
286286
# @return [Element]
287287
def complex_find_contains(class_name, value)
288-
if automation_name_is_uiautomator2?
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)
295289
end
296290

297291
# Find all elements containing value
@@ -343,13 +337,7 @@ def string_visible_exact(class_name, value)
343337
# @param value [String] the value to search for
344338
# @return [Element]
345339
def complex_find_exact(class_name, value)
346-
if automation_name_is_uiautomator2?
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)
353341
end
354342

355343
# Find all elements exactly matching value
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
def raise_no_such_element_if_empty(elements)
75+
raise _no_such_element if elements.empty?
76+
elements.first
77+
end
78+
79+
def _button_visible_selectors(opts = {})
80+
button_index = opts.fetch :button_index, false
81+
image_button_index = opts.fetch :image_button_index, false
82+
83+
if button_index && image_button_index
84+
"new UiSelector().className(#{::Appium::Android::Button}).instance(#{button_index});" \
85+
"new UiSelector().className(#{::Appium::Android::ImageButton}).instance(#{image_button_index});"
86+
else
87+
"new UiSelector().className(#{::Appium::Android::Button});" \
88+
"new UiSelector().className(#{::Appium::Android::ImageButton});"
89+
end
90+
end
91+
92+
def _button_exact_string(value)
93+
button = string_visible_exact ::Appium::Android::Button, value
94+
image_button = string_visible_exact ::Appium::Android::ImageButton, value
95+
button + image_button
96+
end
97+
98+
def _button_contains_string(value)
99+
button = string_visible_contains ::Appium::Android::Button, value
100+
image_button = string_visible_contains ::Appium::Android::ImageButton, value
101+
button + image_button
102+
end
103+
end # module Element
104+
end # module Uiautomator2
105+
end # module Android
106+
end # module Appium
Original file line numberDiff line numberDiff line change
@@ -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

0 commit comments

Comments
 (0)