Skip to content

Commit 1f82df4

Browse files
Fix page commnand on Android
Improve android/element/generic test
1 parent b3cd998 commit 1f82df4

File tree

3 files changed

+79
-120
lines changed

3 files changed

+79
-120
lines changed

android_tests/Rakefile

-9
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ end
4747
# rake android
4848
desc 'Run the Android tests'
4949
task :android, :args, :test_file do |args, test_file|
50-
Rake::Task[:adb_uninstall].execute
5150
run_android test_file[:args]
5251
end
5352

@@ -59,12 +58,4 @@ end
5958
desc 'Run bundle install'
6059
task :install do
6160
sh 'bundle install'
62-
end
63-
64-
desc 'ADB uninstall apk'
65-
task :adb_uninstall do
66-
wait_for_valid_device
67-
# uninstall old api
68-
cmd = 'adb uninstall com.example.android.apis'
69-
run_sh cmd
7061
end
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,50 @@
1+
# rake android['android/element/generic']
12
describe 'android/element/generic' do
2-
def m method
3-
r = method(method).call 'tent'
4-
r = r.first if r.kind_of? Array
5-
r.class.must_equal Selenium::WebDriver::Element
6-
r.text.must_equal 'Content'
7-
end
8-
9-
t 'find' do
10-
m :find
11-
end
123

13-
t 'tag' do
14-
tag 'TextView'
4+
def content
5+
'Content'
156
end
167

17-
t 'tags' do
18-
tags('TextView').length
8+
def partial
9+
'tent'
1910
end
2011

21-
t 'text' do
22-
m :text
12+
t 'find works before and after get_source' do
13+
find(partial).text.must_equal content
14+
get_source.class.must_equal String
15+
find(partial).text.must_equal content
2316
end
2417

25-
t 'texts' do
26-
m :texts
18+
t 'find' do
19+
find(partial).text.must_equal content
2720
end
2821

29-
t 'name' do
30-
m :name
22+
t 'finds' do
23+
finds(partial).first.text.must_equal content
3124
end
3225

33-
t 'name_exact' do
34-
name_exact 'App'
26+
t 'find_exact' do
27+
find_exact(content).text.must_equal content
3528
end
3629

37-
t 'names' do
38-
names('a').length.must_be :>=, 5
30+
t 'finds_exact' do
31+
finds_exact(content).first.text.must_equal content
3932
end
4033

34+
# scroll_to is broken
4135
t 'scroll_to' do
42-
text('Views').click
36+
find('Views').click
4337
e = scroll_to 'rotating button'
4438
e.text.must_equal 'Rotating Button'
4539
# back to start activity
4640
back
4741
end
4842

4943
t 'scroll_to_exact' do
50-
text('Views').click
44+
find('Views').click
5145
e = scroll_to_exact 'Rotating Button'
5246
e.text.must_equal 'Rotating Button'
5347
# back to start activity
5448
back
5549
end
56-
57-
t 'mobile find works before and after source' do
58-
m :text
59-
get_source.class.must_equal Hash
60-
m :text
61-
end
6250
end

lib/appium_lib/android/helper.rb

+59-79
Original file line numberDiff line numberDiff line change
@@ -216,102 +216,79 @@ def find_eles_attr tag_name, attribute=nil
216216
complex_find array
217217
end
218218

219-
# Android only.
220-
# Returns a string containing interesting elements.
221-
# If an element has no content desc or text, then it's not returned by this method.
222-
# @return [String]
223-
def get_android_inspect
224-
# @private
225-
def run node
226-
r = []
219+
# http://nokogiri.org/Nokogiri/XML/SAX.html
220+
class AndroidElements < Nokogiri::XML::SAX::Document
221+
# TODO: Support strings.xml ids
222+
attr_reader :result, :keys
227223

228-
run_internal = lambda do |node|
229-
if node.kind_of? Array
230-
node.each { |node| run_internal.call node }
231-
return
232-
end
224+
def filter
225+
@filter
226+
end
233227

234-
keys = node.keys
235-
return if keys.empty?
236-
if keys == %w(hierarchy)
237-
run_internal.call node['hierarchy']
238-
return
239-
end
228+
# convert to string to support symbols
229+
def filter= value
230+
# nil and false disable the filter
231+
return @filter = false unless value
232+
@filter = value.to_s.downcase
233+
end
240234

241-
n_content = '@content-desc'
242-
n_text = '@text'
243-
n_class = '@class'
244-
n_resource = '@resource-id'
245-
n_node = 'node'
246-
247-
# Store the object if it has a content description, text, or resource id.
248-
# If it only has a class, then don't save it.
249-
obj = {}
250-
obj.merge!({ desc: node[n_content] }) if keys.include?(n_content) && !node[n_content].empty?
251-
obj.merge!({ text: node[n_text] }) if keys.include?(n_text) && !node[n_text].empty?
252-
obj.merge!({ resource_id: node[n_resource] }) if keys.include?(n_resource) && !node[n_resource].empty?
253-
obj.merge!({ class: node[n_class] }) if keys.include?(n_class) && !obj.empty?
254-
255-
r.push obj if !obj.empty?
256-
run_internal.call node[n_node] if keys.include?(n_node)
257-
end
235+
def initialize
236+
reset
237+
@filter = false
238+
end
258239

259-
run_internal.call node
260-
r
240+
def reset
241+
@result = ''
242+
@keys = %w[text resource-id content-desc]
261243
end
262244

263-
lazy_load_strings
264-
json = get_source
265-
node = json['hierarchy']
266-
results = run node
267-
268-
out = ''
269-
results.each { |e|
270-
e_desc = e[:desc]
271-
e_text = e[:text]
272-
e_class = e[:class]
273-
e_resource_id = e[:resource_id]
274-
out += e_class.split('.').last + "\n"
275-
276-
out += " class: #{e_class}\n"
277-
if e_text == e_desc
278-
out += " text, name: #{e_text}\n" unless e_text.nil?
279-
else
280-
out += " text: #{e_text}\n" unless e_text.nil?
281-
out += " name: #{e_desc}\n" unless e_desc.nil?
282-
end
245+
# http://nokogiri.org/Nokogiri/XML/SAX/Document.html
246+
def start_element name, attrs = []
247+
return if filter && !name.downcase.include?(filter)
283248

284-
out += " resource_id: #{e_resource_id}\n" unless e_resource_id.nil? || e_resource_id.empty?
249+
attributes = {}
285250

286-
# there may be many ids with the same value.
287-
# output all exact matches.
288-
id_matches = @strings_xml.select do |key, value|
289-
value == e_desc || value == e_text
251+
attrs.each do |key, value|
252+
if keys.include?(key) && !value.empty?
253+
attributes[key] = value
254+
end
290255
end
291256

292-
if id_matches && id_matches.length > 0
293-
match_str = ''
294-
# [0] = key, [1] = value
295-
id_matches.each do |match|
296-
match_str += ' ' * 6 + "#{match[0]}\n"
297-
end
298-
out += " id: #{match_str.strip}\n"
257+
string = ''
258+
text = attributes['text']
259+
desc = attributes['content-desc']
260+
id = attributes['resource-id']
261+
262+
if !text.nil? && text == desc
263+
string += " text, desc: #{text}\n"
264+
else
265+
string += " text: #{text}\n" unless text.nil?
266+
string += " desc: #{desc}\n" unless desc.nil?
299267
end
300-
}
301-
out
302-
end
268+
string += " id: #{id}\n" unless id.nil?
269+
270+
@result += "\n#{name}\n#{string}" unless attributes.empty?
271+
end
272+
end # class AndroidElements
303273

304-
# Automatically detects selendroid or android.
274+
# Android only.
305275
# Returns a string containing interesting elements.
276+
# If an element has no content desc or text, then it's not returned by this method.
306277
# @return [String]
307-
def get_inspect
308-
get_android_inspect
278+
def get_android_inspect class_name=false
279+
parser = @android_elements_parser ||= Nokogiri::XML::SAX::Parser.new(AndroidElements.new)
280+
281+
parser.document.reset
282+
parser.document.filter = class_name
283+
parser.parse get_source
284+
285+
parser.document.result
309286
end
310287

311288
# Intended for use with console.
312289
# Inspects and prints the current page.
313-
def page
314-
puts get_inspect
290+
def page class_name=false
291+
puts get_android_inspect class_name
315292
nil
316293
end
317294

@@ -431,7 +408,7 @@ def tags class_name
431408
# example: xpath_visible_contains 'UIATextField', text
432409
def string_visible_contains element, value
433410
result = []
434-
attributes = %w[content-desc resource-id text]
411+
attributes = %w[content-desc text]
435412

436413
value_up = value.upcase
437414
value_down = value.downcase
@@ -440,6 +417,9 @@ def string_visible_contains element, value
440417
result << %Q(contains(translate(@#{attribute},"#{value_up}","#{value_down}"), "#{value_down}"))
441418
end
442419

420+
# never partial match on a resource id
421+
result << %Q(@resource-id="#{value}")
422+
443423
result = result.join(' or ')
444424

445425
"//#{element}[#{result}]"

0 commit comments

Comments
 (0)