@@ -17,7 +17,7 @@ def ios_password length=1
17
17
# @param element [Object] the element to search. omit to search everything
18
18
# @return [String]
19
19
def get_page element = source_window ( 0 ) , class_name = nil
20
- lazy_load_strings
20
+ lazy_load_strings # populate @strings_xml
21
21
22
22
# @private
23
23
def empty ele
@@ -42,12 +42,12 @@ def fix_space s
42
42
end
43
43
44
44
unless empty ( element ) || element [ 'visible' ] == false
45
- name = fix_space element [ 'name' ]
46
- label = fix_space element [ 'label' ]
47
- value = fix_space element [ 'value' ]
48
- hint = fix_space element [ 'hint' ]
45
+ name = fix_space element [ 'name' ]
46
+ label = fix_space element [ 'label' ]
47
+ value = fix_space element [ 'value' ]
48
+ hint = fix_space element [ 'hint' ]
49
49
visible = fix_space element [ 'visible' ]
50
- type = fix_space element [ 'type' ]
50
+ type = fix_space element [ 'type' ]
51
51
52
52
# if class_name is set, mark non-matches as invisible
53
53
visible = ( type == class_name ) . to_s if class_name
@@ -99,7 +99,7 @@ def fix_space s
99
99
# @return [void]
100
100
def page opts = { }
101
101
window_number = opts . fetch :window , -1
102
- class_name = opts . fetch :class , nil
102
+ class_name = opts . fetch :class , nil
103
103
104
104
if window_number == -1
105
105
# if the 0th window has no children, find the next window that does.
@@ -135,11 +135,10 @@ def page_window window_number=0
135
135
# @param id [String] the id to search for
136
136
# @return [Element]
137
137
def id id
138
- lazy_load_strings
139
- value = @strings_xml [ id ]
138
+ value = resolve_id id
140
139
raise "Invalid id `#{ id } `" unless value
141
- exact = string_visible_exact '*' , value
142
- contains = string_visible_include '*' , value
140
+ exact = string_visible_exact '*' , value
141
+ contains = string_visible_include '*' , value
143
142
xpath "#{ exact } | #{ contains } "
144
143
end
145
144
@@ -149,5 +148,127 @@ def ios_version
149
148
ios_version = execute_script 'UIATarget.localTarget().systemVersion()'
150
149
ios_version . split ( '.' ) . map { |e | e . to_i }
151
150
end
151
+
152
+ # Get the element of type class_name at matching index.
153
+ # @param class_name [String] the class name to find
154
+ # @param index [Integer] the index
155
+ # @return [Element] the found element of type class_name
156
+ def ele_index class_name , index
157
+ # XPath index starts at 1.
158
+ raise "#{ index } is not a valid xpath index. Must be >= 1" if index <= 0
159
+ find_element :xpath , %Q(//#{ class_name } [@visible="true"][#{ index } ])
160
+ end
161
+
162
+ def string_attr_exact class_name , attr , value
163
+ %Q(//#{ class_name } [@visible="true" and @#{ attr } ='#{ value } '])
164
+ end
165
+
166
+ def find_ele_by_attr class_name , attr , value
167
+ @driver . find_element :xpath , string_attr_exact ( class_name , attr , value )
168
+ end
169
+
170
+ def find_eles_by_attr class_name , attr , value
171
+ @driver . find_elements :xpath , string_attr_exact ( class_name , attr , value )
172
+ end
173
+
174
+ def string_attr_include class_name , attr , value
175
+ %Q(//#{ class_name } [@visible="true" and contains(translate(@#{ attr } ,'#{ value . upcase } ', '#{ value } '), '#{ value } ')])
176
+ end
177
+
178
+ # Get the first tag by attribute that exactly matches value.
179
+ # @param class_name [String] the tag name to match
180
+ # @param attr [String] the attribute to compare
181
+ # @param value [String] the value of the attribute that the element must include
182
+ # @return [Element] the element of type tag who's attribute includes value
183
+ def find_ele_by_attr_include class_name , attr , value
184
+ @driver . find_element :xpath , string_attr_include ( class_name , attr , value )
185
+ end
186
+
187
+ # Get tags by attribute that include value.
188
+ # @param class_name [String] the tag name to match
189
+ # @param attr [String] the attribute to compare
190
+ # @param value [String] the value of the attribute that the element must include
191
+ # @return [Array<Element>] the elements of type tag who's attribute includes value
192
+ def find_eles_by_attr_include class_name , attr , value
193
+ @driver . find_elements :xpath , string_attr_include ( class_name , attr , value )
194
+ end
195
+
196
+ # Get the first tag that matches class_name
197
+ # @param class_name [String] the tag to match
198
+ # @return [Element]
199
+ def first_ele class_name
200
+ # XPath index starts at 1
201
+ find_element :xpath , %Q(//#{ class_name } [@visible="true"][1])
202
+ end
203
+
204
+ # Get the last tag that matches class_name
205
+ # @param class_name [String] the tag to match
206
+ # @return [Element]
207
+ def last_ele class_name
208
+ xpath %Q(//#{ class_name } [@visible="true"][last()])
209
+ end
210
+
211
+ # Returns the first element matching class_name
212
+ #
213
+ # @param class_name [String] the class_name to search for
214
+ # @return [Element]
215
+ def tag class_name
216
+ xpath %Q(//#{ class_name } [@visible="true"])
217
+ end
218
+
219
+ # Returns all elements matching class_name
220
+ #
221
+ # @param class_name [String] the class_name to search for
222
+ # @return [Element]
223
+ def tags class_name
224
+ xpaths %Q(//#{ class_name } [@visible="true"])
225
+ end
226
+
227
+ # xpath fragment helper
228
+ # example: xpath_visible_contains 'UIATextField', text
229
+ def string_visible_include element , value
230
+ result = [ ]
231
+ attributes = %w[ name hint label value ]
232
+
233
+ value_up = value . upcase
234
+ value_down = value . downcase
235
+
236
+ attributes . each do |attribute |
237
+ result << %Q(contains(translate(@#{ attribute } ,"#{ value_up } ","#{ value_down } "), "#{ value_down } "))
238
+ end
239
+
240
+ result = result . join ( ' or ' )
241
+ result = %Q(@visible="true" and (#{ result } ))
242
+ "//#{ element } [#{ result } ]"
243
+ end
244
+
245
+ def xpath_visible_contains element , value
246
+ xpath string_visible_include element , value
247
+ end
248
+
249
+ def xpaths_visible_contains element , value
250
+ xpaths string_visible_include element , value
251
+ end
252
+
253
+ def string_visible_exact element , value
254
+ result = [ ]
255
+ attributes = %w[ name hint label value ]
256
+
257
+ attributes . each do |attribute |
258
+ result << %Q(@#{ attribute } ="#{ value } ")
259
+ end
260
+
261
+ result = result . join ( ' or ' )
262
+ result = %Q(@visible="true" and (#{ result } ))
263
+ "//#{ element } [#{ result } ]"
264
+ end
265
+
266
+ def xpath_visible_exact element , value
267
+ xpath string_visible_exact element , value
268
+ end
269
+
270
+ def xpaths_visible_exact element , value
271
+ xpaths string_visible_exact element , value
272
+ end
152
273
end # module Ios
153
274
end # module Appium
0 commit comments