Skip to content

Commit ecc7d02

Browse files
Update iOS support
1 parent 8845a1e commit ecc7d02

File tree

8 files changed

+96
-244
lines changed

8 files changed

+96
-244
lines changed

ios_tests/lib/ios/specs/common/helper.rb

+11-36
Original file line numberDiff line numberDiff line change
@@ -92,63 +92,46 @@ def uibutton_text
9292
end
9393

9494
t 'ele_index' do
95-
ele_index('text', 2).name.must_equal uibutton_text
95+
ele_index('UIAStaticText', 2).name.must_equal uibutton_text
9696
end
9797

98-
t 'find_eles' do
99-
find_eles('text').length.must_equal 13
100-
end
101-
102-
t 'find_ele_by_name' do
103-
el_id = find_ele_by_name(:text, uibutton_text).instance_variable_get :@id
98+
t 'find_ele_by_attr' do
99+
el_id = find_ele_by_attr('UIAStaticText', 'name', uibutton_text).instance_variable_get :@id
104100
el_id.must_match /\d+/
105101
end
106102

107-
t 'find_eles_by_name' do
103+
t 'find_eles_by_attr' do
108104
# '!' clears the input buffer in Pry so make sure there's
109105
# no space after the !
110106
set_wait 1
111107
# empty array returned when no match
112-
found = !find_eles_by_name(:text, uibutton_text).empty?
108+
found = !find_eles_by_attr('UIAStaticText', 'name', uibutton_text).empty?
113109
found.must_equal true
114110

115-
found = !find_eles_by_name(:text, 'zz').empty?
111+
found = !find_eles_by_attr('UIAStaticText', 'name', 'zz').empty?
116112
found.must_equal false
117113
set_wait
118114
end
119115

120116
t 'find_ele_by_attr_include' do
121-
el_text = find_ele_by_attr_include(:text, :name, 'button').text
117+
el_text = find_ele_by_attr_include('UIAStaticText', :name, 'button').text
122118
el_text.must_equal ''
123119

124-
el_name = find_ele_by_attr_include(:text, :name, 'button').name
120+
el_name = find_ele_by_attr_include('UIAStaticText', :name, 'button').name
125121
el_name.must_equal uibutton_text
126122
end
127123

128124
t 'find_eles_by_attr_include' do
129-
ele_count = find_eles_by_attr_include(:text, :name, 'e').length
130-
ele_count.must_equal 12
131-
end
132-
133-
t 'find_ele_by_name_include' do
134-
el = find_ele_by_name_include(:text, 'bu')
135-
el_text = el.text
136-
el_text = el.name if el_text.nil? || el_text.empty?
137-
138-
el_text.must_equal uibutton_text
139-
end
140-
141-
t 'find_eles_by_name_include' do
142-
ele_count = find_eles_by_name_include(:text, 'e').length
125+
ele_count = find_eles_by_attr_include('UIAStaticText', :name, 'e').length
143126
ele_count.must_equal 12
144127
end
145128

146129
t 'first_ele' do
147-
first_ele(:text).name.must_equal 'UICatalog'
130+
first_ele('UIAStaticText').name.must_equal 'UICatalog'
148131
end
149132

150133
t 'last_ele' do
151-
el = last_ele(:text)
134+
el = last_ele('UIAStaticText')
152135
el.text.must_equal ''
153136
el.name.must_equal 'Transitions, Shows UIViewAnimationTransitions'
154137
end
@@ -159,14 +142,6 @@ def uibutton_text
159142
get_source.class.must_equal String
160143
end
161144

162-
t 'name_exact' do
163-
name_exact(uibutton_text).name.must_equal uibutton_text
164-
end
165-
166-
t 'names_exact' do
167-
names_exact(uibutton_text).first.name.must_equal uibutton_text
168-
end
169-
170145
t 'id' do
171146
id 'ButtonsExplain' # 'Various uses of UIButton'
172147
end

ios_tests/lib/ios/specs/ios/helper.rb

+2-13
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,8 @@ def before_first
99
before_first
1010
end
1111

12-
t 'find_eles_attr' do
13-
find_eles_attr(:text, :text).length.must_equal 13
14-
end
15-
16-
t 'find_2_eles_attr' do
17-
# find all elements of tag type :text and return the :text value plus
18-
# find all elements of tag type :text and return the :text value
19-
# use case is: find_2_eles_attr :textfield, :secure, :text
20-
find_2_eles_attr(:text, :text, :text).length.must_equal 26
12+
t 'find_eles_by_attr_include' do
13+
find_eles_by_attr_include('UIATableCell', 'name', 'Use').length.must_equal 7
2114
end
2215

2316
t 'ios_password' do
@@ -39,8 +32,4 @@ def before_first
3932
end
4033

4134
# t 'page_window' do # prints to stdout
42-
43-
t 'fast_duration' do
44-
fast_duration.must_equal 0.5
45-
end
4635
end

lib/appium_lib/common/helper.rb

+49-116
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module Common
1515
# Android and iOS have proper accessibility attributes.
1616
# .text and .value should be the same so use .text over .value.
1717
#
18-
# secure tag_name is iOS only because it can't be implemented using uiautomator for Android.
18+
# secure class_name is iOS only because it can't be implemented using uiautomator for Android.
1919
#
2020
# find_element :text doesn't work so use XPath to find by text.
2121

@@ -77,17 +77,6 @@ def wait_true max_wait=30, interval=0.5, &block
7777
result
7878
end
7979

80-
def tag_to_class tag_name
81-
case tag_name
82-
when 'text', :text
83-
device_is_android? ? 'android.widget.TextView' : 'UIAStaticText'
84-
when 'button', :button
85-
device_is_android? ? 'android.widget.Button' : 'UIAButton'
86-
else
87-
tag_name
88-
end
89-
end
90-
9180
# Navigate back.
9281
# @return [void]
9382
def back
@@ -115,115 +104,62 @@ def xpaths xpath_str
115104
find_elements :xpath, xpath_str
116105
end
117106

118-
# Get the element of type tag_name at matching index.
119-
# @param tag_name [String] the tag name to find
107+
# Get the element of type class_name at matching index.
108+
# @param class_name [String] the class name to find
120109
# @param index [Integer] the index
121-
# @return [Element] the found element of type tag_name
122-
def ele_index tag_name, index
123-
class_name = tag_to_class tag_name
110+
# @return [Element] the found element of type class_name
111+
def ele_index class_name, index
124112
# XPath index starts at 1.
125113
raise "#{index} is not a valid xpath index. Must be >= 1" if index <= 0
126114
find_element :xpath, "//#{class_name}[#{index}]"
127115
end
128116

129-
# Get all elements exactly matching tag name
130-
# @param tag_name [String] the tag name to find
131-
# @return [Array<Element>] the found elements of type tag_name
132-
def find_eles tag_name
133-
class_name = tag_to_class tag_name
134-
@driver.find_elements :class, class_name
135-
end
136-
137-
# Get the first tag that exactly matches tag and text.
138-
# @param tag_name [String] the tag name to match
139-
# @param text [String] the text to exactly match
140-
# @return [Element] the element of type tag exactly matching text
141-
def find_ele_by_text tag_name, text
142-
class_name = tag_to_class tag_name
143-
@driver.find_element :xpath, %Q(//#{class_name}[@text='#{text}'])
117+
def string_attr_exact class_name, attr, value
118+
%Q(//#{class_name}[@visible="true" and @#{attr}='#{value}'])
144119
end
145120

146-
# Get all tags that exactly match tag and text.
147-
# @param tag_name [String] the tag name to match
148-
# @param text [String] the text to exactly match
149-
# @return [Array<Element>] the elements of type tag exactly matching text
150-
def find_eles_by_text tag_name, text
151-
class_name = tag_to_class tag_name
152-
@driver.find_elements :xpath, %Q(//#{class_name}[@text='#{text}'])
121+
def find_ele_by_attr class_name, attr, value
122+
@driver.find_element :xpath, string_attr_exact(class_name, attr, value)
153123
end
154124

155-
def find_ele_by_name tag_name, name
156-
class_name = tag_to_class tag_name
157-
@driver.find_element :xpath, %Q(//#{class_name}[@name='#{name}'])
125+
def find_eles_by_attr class_name, attr, value
126+
@driver.find_elements :xpath, string_attr_exact(class_name, attr, value)
158127
end
159128

160-
def find_eles_by_name tag_name, name
161-
class_name = tag_to_class tag_name
162-
@driver.find_elements :xpath, %Q(//#{class_name}[@name='#{name}'])
129+
def string_attr_include class_name, attr, value
130+
%Q(//#{class_name}[@visible="true" and contains(translate(@#{attr},'#{value.upcase}', '#{value}'), '#{value}')])
163131
end
164132

165133
# Get the first tag by attribute that exactly matches value.
166-
# @param tag_name [String] the tag name to match
134+
# @param class_name [String] the tag name to match
167135
# @param attr [String] the attribute to compare
168136
# @param value [String] the value of the attribute that the element must include
169137
# @return [Element] the element of type tag who's attribute includes value
170-
def find_ele_by_attr_include tag_name, attr, value
171-
class_name = tag_to_class tag_name
172-
value.downcase!
173-
@driver.find_element :xpath, %Q(//#{class_name}[contains(translate(@#{attr},'#{value.upcase}', '#{value}'), '#{value}')])
138+
def find_ele_by_attr_include class_name, attr, value
139+
@driver.find_element :xpath, string_attr_include(class_name, attr, value)
174140
end
175141

176142
# Get tags by attribute that include value.
177-
# @param tag_name [String] the tag name to match
143+
# @param class_name [String] the tag name to match
178144
# @param attr [String] the attribute to compare
179145
# @param value [String] the value of the attribute that the element must include
180146
# @return [Array<Element>] the elements of type tag who's attribute includes value
181-
def find_eles_by_attr_include tag_name, attr, value
182-
class_name = tag_to_class tag_name
183-
value.downcase!
184-
@driver.find_elements :xpath, %Q(//#{class_name}[contains(translate(@#{attr},'#{value.upcase}', '#{value}'), '#{value}')])
185-
end
186-
187-
# Get the first tag that includes text.
188-
# @param tag_name [String] the tag name to match
189-
# @param text [String] the text the element must include
190-
# @return [Element] the element of type tag that includes text
191-
# element.attribute(:text).include? text
192-
def find_ele_by_text_include tag_name, text
193-
find_ele_by_attr_include tag_name, :text, text
194-
end
195-
196-
# Get the tags that include text.
197-
# @param tag_name [String] the tag name to match
198-
# @param text [String] the text the element must include
199-
# @return [Array<Element>] the elements of type tag that includes text
200-
# element.attribute(:text).include? text
201-
def find_eles_by_text_include tag_name, text
202-
find_eles_by_attr_include tag_name, :text, text
147+
def find_eles_by_attr_include class_name, attr, value
148+
@driver.find_elements :xpath, string_attr_include(class_name, attr, value)
203149
end
204150

205-
def find_ele_by_name_include tag_name, text
206-
find_ele_by_attr_include tag_name, :name, text
207-
end
208-
209-
def find_eles_by_name_include tag_name, text
210-
find_eles_by_attr_include tag_name, :name, text
211-
end
212-
213-
# Get the first tag that matches tag_name
214-
# @param tag_name [String] the tag to match
151+
# Get the first tag that matches class_name
152+
# @param class_name [String] the tag to match
215153
# @return [Element]
216-
def first_ele tag_name
154+
def first_ele class_name
217155
# XPath index starts at 1
218-
class_name = tag_to_class tag_name
219156
find_element :xpath, "//#{class_name}[1]"
220157
end
221158

222-
# Get the last tag that matches tag_name
223-
# @param tag_name [String] the tag to match
159+
# Get the last tag that matches class_name
160+
# @param class_name [String] the tag to match
224161
# @return [Element]
225-
def last_ele tag_name
226-
class_name = tag_to_class tag_name
162+
def last_ele class_name
227163
xpath "//#{class_name}[last()]"
228164
end
229165

@@ -236,7 +172,6 @@ def source
236172
puts doc.to_xml indent: 2
237173
end
238174

239-
240175
# Returns XML string for the current page
241176
# Same as driver.page_source
242177
# @return [String]
@@ -288,37 +223,19 @@ def page_class
288223
nil
289224
end
290225

291-
# Returns the first element that exactly matches name
226+
# Returns the first element matching class_name
292227
#
293-
# @param name [String] the name to exactly match
228+
# @param class_name [String] the class_name to search for
294229
# @return [Element]
295-
def name_exact name
296-
find_element :name, name
297-
end
298-
299-
# Returns all elements that exactly match name
300-
#
301-
# @param name [String] the name to exactly match
302-
# @return [Array<Element>]
303-
def names_exact name
304-
find_elements :name, name
305-
end
306-
307-
# Returns the first element matching tag_name
308-
#
309-
# @param tag_name [String] the tag_name to search for
310-
# @return [Element]
311-
def tag tag_name
312-
class_name = tag_to_class tag_name
230+
def tag class_name
313231
find_element :class, class_name
314232
end
315233

316-
# Returns all elements matching tag_name
234+
# Returns all elements matching class_name
317235
#
318-
# @param tag_name [String] the tag_name to search for
236+
# @param class_name [String] the class_name to search for
319237
# @return [Element]
320-
def tags tag_name
321-
class_name = tag_to_class tag_name
238+
def tags class_name
322239
find_elements :class, class_name
323240
end
324241

@@ -367,7 +284,7 @@ def resolve_id id
367284

368285
# xpath fragment helper
369286
# example: xpath_visible_contains 'UIATextField', text
370-
def xpath_visible_contains element, value
287+
def string_visible_contains element, value
371288
result = []
372289
attributes = %w[name hint label value]
373290

@@ -383,7 +300,15 @@ def xpath_visible_contains element, value
383300
"//#{element}[#{result}]"
384301
end
385302

386-
def xpath_visible_exact element, value
303+
def xpath_visible_contains element, value
304+
xpath string_visible_contains element, value
305+
end
306+
307+
def xpaths_visible_contains element, value
308+
xpaths string_visible_contains element, value
309+
end
310+
311+
def string_visible_exact element, value
387312
result = []
388313
attributes = %w[name hint label value]
389314

@@ -396,6 +321,14 @@ def xpath_visible_exact element, value
396321
"//#{element}[#{result}]"
397322
end
398323

324+
def xpath_visible_exact element, value
325+
xpath string_visible_exact element, value
326+
end
327+
328+
def xpaths_visible_exact element, value
329+
xpaths string_visible_exact element, value
330+
end
331+
399332
# Used to error when finding a single element fails.
400333
def raise_no_element_error
401334
raise Selenium::WebDriver::Error::NoSuchElementError, 'An element could not be located on the page using the given search parameters.'

0 commit comments

Comments
 (0)