11module Appium
22 module Ios
3- UITextField = 'UITextField '
4- UISecureTextField = 'UISecureTextField '
3+ UIATextField = 'UIATextField '
4+ UIASecureTextField = 'UIASecureTextField '
55
66 private
7- =begin
8- contains only works with strings. will fail if used on non-string
9- value may randomly be a number so value contains is going to randomly fail
10- must use [cd] for case and diacritic insensitivity.
11-
12- @interface CustomTextField : UITextField
13-
14- The predicate type will always be CustomTextField even though element.type() in uiautomation
15- returns UIATextField and UIASecureTextField. There's no way to identify the underlying predicate
16- type without reading the source or brute force.
17- https://github.com/appium/ruby_lib/issues/226#issuecomment-50036962
18- =end
197
208 # @private
21- def _textfield_visible_pred
22- # type refers to the underlying app specific class for the textfield which
23- # could be anything. we're assuming that textfields contain the string
24- # textfield in the type.
25- "type contains[cd] 'textfield'"
9+ def _textfield_visible_string opts = { }
10+ index = opts . fetch :index , false
11+ if index
12+ %Q((//#{ UIATextField } [@visible="true"])[#{ index } ] | (//#{ UIASecureTextField } [@visible="true"])[#{ index } ])
13+ else
14+ %Q(//#{ UIATextField } [@visible="true"] | //#{ UIASecureTextField } [@visible="true"])
15+ end
2616 end
2717
2818 # @private
29- def _textfield_exact_pred value
30- value . gsub! ( "'" , "\\ \\ '" ) # escape '
31- "#{ _textfield_visible_pred } && value == '#{ value } '"
19+ def _textfield_exact_string value
20+ textfield = string_visible_exact UIATextField , value
21+ secure = string_visible_exact UIASecureTextField , value
22+ "#{ textfield } | #{ secure } "
3223 end
3324
3425 # @private
35- def _textfield_contains_pred value
36- value . gsub! ( "'" , "\\ \\ '" ) # escape '
37- # c - case insensitive
38- # d - diacritic insensitive
39- "#{ _textfield_visible_pred } && value contains[cd] '#{ value } '"
26+ def _textfield_contains_string value
27+ textfield = string_visible_contains UIATextField , value
28+ secure = string_visible_contains UIASecureTextField , value
29+ "#{ textfield } | #{ secure } "
4030 end
4131
4232 public
@@ -50,49 +40,47 @@ def textfield value
5040 # iOS needs to combine textfield and secure to match Android.
5141 if value . is_a? Numeric
5242 index = value
53- raise "#{ index } is not a valid index. Must be >= 1" if index <= 0
54- index -= 1 # predicates are 0 indexed.
55- result = eles_with_pred ( _textfield_visible_pred )
56- return result [ index ] if result && result . length > 0 && index < result . length
57- _no_such_element # failure to find a single element = raise error.
43+ raise "#{ index } is not a valid xpath index. Must be >= 1" if index <= 0
44+
45+ return xpath _textfield_visible_string index : index
5846 end
5947
60- ele_with_pred ( _textfield_contains_pred ( value ) )
48+ xpath _textfield_contains_string value
6149 end
6250
6351 # Find all TextFields containing value.
6452 # If value is omitted, all TextFields are returned.
6553 # @param value [String] the value to search for
6654 # @return [Array<TextField>]
6755 def textfields value = false
68- return eles_with_pred ( _textfield_visible_pred ) unless value
69- eles_with_pred ( _textfield_contains_pred ( value ) )
56+ return xpaths _textfield_visible_string unless value
57+ xpaths _textfield_contains_string value
7058 end
7159
7260 # Find the first TextField.
7361 # @return [TextField]
7462 def first_textfield
75- ele_with_pred ( _textfield_visible_pred )
63+ xpath _textfield_visible_string
7664 end
7765
7866 # Find the last TextField.
7967 # @return [TextField]
8068 def last_textfield
81- eles_with_pred ( _textfield_visible_pred ) . last
69+ xpath _textfield_visible_string index : 'last()'
8270 end
8371
8472 # Find the first TextField that exactly matches value.
8573 # @param value [String] the value to match exactly
8674 # @return [TextField]
8775 def textfield_exact value
88- ele_with_pred ( _textfield_exact_pred ( value ) )
76+ xpath _textfield_exact_string value
8977 end
9078
9179 # Find all TextFields that exactly match value.
9280 # @param value [String] the value to match exactly
9381 # @return [Array<TextField>]
9482 def textfields_exact value
95- eles_with_pred ( _textfield_exact_pred ( value ) )
83+ xpaths _textfield_exact_string value
9684 end
9785 end # module Ios
9886end # module Appium
0 commit comments