@@ -18,13 +18,13 @@ def filter= value
18
18
19
19
def initialize
20
20
reset
21
- @filter = false
21
+ @filter = false
22
22
@instance = Hash . new -1
23
23
end
24
24
25
25
def reset
26
- @result = ''
27
- @keys = %w[ text resource-id content-desc ]
26
+ @result = ''
27
+ @keys = %w[ text resource-id content-desc ]
28
28
@instance = Hash . new -1
29
29
end
30
30
@@ -83,6 +83,41 @@ def start_element name, attrs = []
83
83
end
84
84
end # class AndroidElements
85
85
86
+ # Fix uiautomator's xml dump.
87
+ # https://github.com/appium/appium/issues/2822
88
+ # https://code.google.com/p/android/issues/detail?id=74143
89
+ def _fix_android_native_source source
90
+ # <android.app.ActionBar$Tab
91
+ # <android.app.ActionBar $ Tab
92
+
93
+ # find each closing tag that contains a dollar sign.
94
+ source . scan ( /<\/ ([^>]*\$ [^>]*)>/ ) . flatten . uniq . each do |problem_tag |
95
+ # "android.app.ActionBar$Tab"
96
+ before , after = problem_tag . split ( '$' )
97
+ before . strip!
98
+ after . strip!
99
+
100
+ fixed = "#{ before } .#{ after } "
101
+
102
+ # now escape . in before/after because they're used in regex
103
+ before . gsub! ( '.' , '\.' )
104
+ after . gsub! ( '.' , '\.' )
105
+
106
+ # <android.app.ActionBar$Tab => <android.app.ActionBar.Tab
107
+ # </android.app.ActionBar$Tab> => </android.app.ActionBar.Tab>
108
+ source = source . gsub ( /<#{ before } \s *\$ \s *#{ after } / , "<#{ fixed } " ) .
109
+ gsub ( /<\/ #{ before } \s *\$ \s *#{ after } >/ , "</#{ fixed } >" )
110
+ end
111
+
112
+ source
113
+ end
114
+
115
+ # Prints xml of the current page
116
+ # @return [void]
117
+ def source
118
+ _print_source _fix_android_native_source get_source
119
+ end
120
+
86
121
# Android only.
87
122
# Returns a string containing interesting elements.
88
123
# The text, content description, and id are returned.
@@ -91,10 +126,11 @@ def start_element name, attrs = []
91
126
# @return [String]
92
127
def get_android_inspect class_name = false
93
128
source = get_source
94
- if source . start_with? '<html>'
129
+ if source . start_with? '<html>' # parse html from webview
95
130
parser = @android_html_parser ||= Nokogiri ::HTML ::SAX ::Parser . new ( Common ::HTMLElements . new )
96
131
else
97
- parser = @android_webview_parser ||= Nokogiri ::XML ::SAX ::Parser . new ( AndroidElements . new )
132
+ source = _fix_android_native_source source
133
+ parser = @android_native_parser ||= Nokogiri ::XML ::SAX ::Parser . new ( AndroidElements . new )
98
134
end
99
135
parser . document . reset # ensure document is reset before parsing
100
136
parser . document . filter = class_name
0 commit comments