Skip to content

Commit 1c7dd0f

Browse files
authored
use xpath instead of uiselectors (#544)
* use xpath instead of uiselectors * fix index * fix tests
1 parent 5841a39 commit 1c7dd0f

File tree

4 files changed

+33
-59
lines changed

4 files changed

+33
-59
lines changed

android_tests/lib/android/specs/common/device.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
end
1313

1414
t 'get_performance_data_types' do
15-
expected = %w(cpuinfo batteryinfo networkinfo memoryinfo)
16-
get_performance_data_types.must_equal expected
15+
expected = %w(batteryinfo cpuinfo memoryinfo networkinfo)
16+
get_performance_data_types.sort.must_equal expected
1717

1818
get_performance_data(package_name: 'io.appium.android.apis',
1919
data_type: 'cpuinfo').must_equal [%w(user kernel), %w(0 0)]

android_tests/lib/android/specs/common/patch.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
set_wait 30
4444
end
4545
value = value.split("\n").first.strip
46-
exp = 'No element found'
46+
exp = 'An element could not be located on the page using the given search parameters.'
4747
value.must_equal exp
4848
end
4949

lib/appium_lib/android/element/button.rb

+18-34
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,20 @@ module Android
77
private
88

99
# @private
10-
def _button_visible_selectors(opts = {})
11-
button_index = opts.fetch :button_index, false
12-
image_button_index = opts.fetch :image_button_index, false
13-
14-
if button_index && image_button_index
15-
"new UiSelector().className(#{Button}).instance(#{button_index});" \
16-
"new UiSelector().className(#{ImageButton}).instance(#{image_button_index});"
17-
else
18-
"new UiSelector().className(#{Button});" \
19-
"new UiSelector().className(#{ImageButton});"
20-
end
10+
def _button_visible_selectors
11+
"//#{Button}|#{ImageButton}"
2112
end
2213

2314
# @private
2415
def _button_exact_string(value)
25-
button = string_visible_exact Button, value
26-
image_button = string_visible_exact ImageButton, value
27-
button + image_button
16+
string_visible_exact(Button, value) +
17+
string_visible_exact(ImageButton, value).sub(/\A\/\//, '|')
2818
end
2919

3020
# @private
3121
def _button_contains_string(value)
32-
button = string_visible_contains Button, value
33-
image_button = string_visible_contains ImageButton, value
34-
button + image_button
22+
string_visible_contains(Button, value) +
23+
string_visible_contains(ImageButton, value).sub(/\A\/\//, '|')
3524
end
3625

3726
public
@@ -47,54 +36,49 @@ def button(value)
4736
index = value
4837
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
4938

50-
return find_element :uiautomator, _button_visible_selectors(index: index)
39+
result = find_elements(:xpath, _button_visible_selectors)[value - 1]
40+
raise Selenium::WebDriver::Error::NoSuchElementError unless result
41+
return result
5142
end
5243

53-
find_element :uiautomator, _button_contains_string(value)
44+
find_element :xpath, _button_contains_string(value)
5445
end
5546

5647
# Find all buttons containing value.
5748
# If value is omitted, all buttons are returned.
5849
# @param value [String] the value to search for
5950
# @return [Array<Button>]
6051
def buttons(value = false)
61-
return find_elements :uiautomator, _button_visible_selectors unless value
62-
find_elements :uiautomator, _button_contains_string(value)
52+
return find_elements :xpath, _button_visible_selectors unless value
53+
find_elements :xpath, _button_contains_string(value)
6354
end
6455

6556
# Find the first button.
6657
# @return [Button]
6758
def first_button
68-
find_element :uiautomator, _button_visible_selectors(button_index: 0, image_button_index: 0)
59+
find_element :xpath, _button_visible_selectors
6960
end
7061

7162
# Find the last button.
7263
# @return [Button]
7364
def last_button
74-
# uiautomator index doesn't support last
75-
# and it's 0 indexed
76-
button_index = tags(Button).length
77-
button_index -= 1 if button_index > 0
78-
image_button_index = tags(ImageButton).length
79-
image_button_index -= 1 if image_button_index > 0
80-
81-
find_element :uiautomator,
82-
_button_visible_selectors(button_index: button_index,
83-
image_button_index: image_button_index)
65+
result = find_elements(:xpath, _button_visible_selectors).last
66+
raise Selenium::WebDriver::Error::NoSuchElementError unless result
67+
result
8468
end
8569

8670
# Find the first button that exactly matches value.
8771
# @param value [String] the value to match exactly
8872
# @return [Button]
8973
def button_exact(value)
90-
find_element :uiautomator, _button_exact_string(value)
74+
find_element :xpath, _button_exact_string(value)
9175
end
9276

9377
# Find all buttons that exactly match value.
9478
# @param value [String] the value to match exactly
9579
# @return [Array<Button>]
9680
def buttons_exact(value)
97-
find_elements :uiautomator, _button_exact_string(value)
81+
find_elements :xpath, _button_exact_string(value)
9882
end
9983
end # module Android
10084
end # module Appium

lib/appium_lib/android/helper.rb

+12-22
Original file line numberDiff line numberDiff line change
@@ -286,35 +286,31 @@ def resource_id(string, on_match)
286286
# @param value [String] the value to search for
287287
# @return [String]
288288
def string_visible_contains(class_name, value)
289-
value = %("#{value}")
289+
r_id = resource_id(value, " or @resource-id='#{value}'")
290290

291291
if class_name == '*'
292-
return (resource_id(value, "new UiSelector().resourceId(#{value});") +
293-
"new UiSelector().descriptionContains(#{value});" \
294-
"new UiSelector().textContains(#{value});")
292+
return "//*[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
293+
" or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
295294
end
296295

297-
class_name = %("#{class_name}")
298-
299-
resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
300-
"new UiSelector().className(#{class_name}).descriptionContains(#{value});" \
301-
"new UiSelector().className(#{class_name}).textContains(#{value});"
296+
"//#{class_name}[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
297+
" or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
302298
end
303299

304300
# Find the first element that contains value
305301
# @param element [String] the class name for the element
306302
# @param value [String] the value to search for
307303
# @return [Element]
308304
def complex_find_contains(element, value)
309-
find_element :uiautomator, string_visible_contains(element, value)
305+
find_element :xpath, string_visible_contains(element, value)
310306
end
311307

312308
# Find all elements containing value
313309
# @param element [String] the class name for the element
314310
# @param value [String] the value to search for
315311
# @return [Array<Element>]
316312
def complex_finds_contains(element, value)
317-
find_elements :uiautomator, string_visible_contains(element, value)
313+
find_elements :xpath, string_visible_contains(element, value)
318314
end
319315

320316
# @private
@@ -323,35 +319,29 @@ def complex_finds_contains(element, value)
323319
# @param value [String] the value to search for
324320
# @return [String]
325321
def string_visible_exact(class_name, value)
326-
value = %("#{value}")
322+
r_id = resource_id(value, " or @resource-id='#{value}'")
327323

328324
if class_name == '*'
329-
return (resource_id(value, "new UiSelector().resourceId(#{value});") +
330-
"new UiSelector().description(#{value});" \
331-
"new UiSelector().text(#{value});")
325+
return "//*[@text='#{value}' or @content-desc='#{value}'" + r_id + ']'
332326
end
333327

334-
class_name = %("#{class_name}")
335-
336-
resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
337-
"new UiSelector().className(#{class_name}).description(#{value});" \
338-
"new UiSelector().className(#{class_name}).text(#{value});"
328+
"//#{class_name}[@text='#{value}' or @content-desc='#{value}'" + r_id + ']'
339329
end
340330

341331
# Find the first element exactly matching value
342332
# @param class_name [String] the class name for the element
343333
# @param value [String] the value to search for
344334
# @return [Element]
345335
def complex_find_exact(class_name, value)
346-
find_element :uiautomator, string_visible_exact(class_name, value)
336+
find_element :xpath, string_visible_exact(class_name, value)
347337
end
348338

349339
# Find all elements exactly matching value
350340
# @param class_name [String] the class name for the element
351341
# @param value [String] the value to search for
352342
# @return [Element]
353343
def complex_finds_exact(class_name, value)
354-
find_elements :uiautomator, string_visible_exact(class_name, value)
344+
find_elements :xpath, string_visible_exact(class_name, value)
355345
end
356346

357347
# Returns XML string for the current page

0 commit comments

Comments
 (0)