module Appium::Ios
def alert_accept
-
(void)
-
def alert_accept # @driver.switch_to.alert.accept # ".switch_to.alert" calls getAlertText so use bridge directly driver.send(:bridge).acceptAlert end
def alert_accept_text
-
(String)
-
def alert_accept_text a = @driver.find_element(:tag_name, :alert) return if a.nil? b = a.find_elements(:tag_name, :button) b.last.text if b && b.size >= 1 end
def alert_click value
-
(void)
-
Parameters:
-
value
(Integer, String
) -- either an integer index of the button or the button's name
def alert_click value value = "'#{value}'" if value.is_a?(String) @driver.execute_script "UIATarget.localTarget().frontMostApp().alert().buttons()[#{value}].tap();" end
def alert_dismiss
-
(void)
-
def alert_dismiss # @driver.switch_to.alert.dismiss # ".switch_to.alert" calls getAlertText so use bridge directly driver.send(:bridge).dismissAlert end
def alert_dismiss_text
-
(String)
-
def alert_dismiss_text a = @driver.find_element(:tag_name, :alert) return if a.nil? b = a.find_elements(:tag_name, :button) b.first.text if b && b.size >= 1 end
def alert_text
-
(String)
-
def alert_text # this will call get text twice so call bridge directly # ".switch_to.alert" calls it once, then ".text" another time. # @driver.switch_to.alert.text driver.send(:bridge).getAlertText end
def all_ele_js predicate
-
(String)
- the completed JavaScript program
Parameters:
-
predicate
(String
) -- the predicate
Other tags:
- Private: -
def all_ele_js predicate (<<-JS).strip # remove trailing newline au.mainApp.getAllWithPredicate("#{predicate}"); JS end
def e_textfields
-
(Array
-)
def e_textfields execute_script textfield_js end
def empty ele
- Private: -
def empty ele (ele['name'] || ele['label'] || ele['value']) == nil end
def fast_duration
-
(Float)
-
def fast_duration 0.5 end
def find text
-
(Element)
- the first matching element
Parameters:
-
text
(String
) -- the text to search for
def find text ele = nil # prefer value search. this may error with: # Can't use in/contains operator with collection 1 js = first_ele_js "value contains[c] '#{text}'" ele = ignore { execute_script js } # now search name and label if the value search didn't match. unless ele js = first_ele_js "name contains[c] '#{text}' || label contains[c] '#{text}'" ele = ignore { execute_script js } end # manually raise error if no element was found raise Selenium::WebDriver::Error::NoSuchElementError, 'An element could not be located on the page using the given search parameters.' unless ele ele end
def find_2_eles_attr tag_name_1, tag_name_2, attribute
-
(Array
- an array of strings containing the attribute from found elements of type tag_name.)
Parameters:
-
attribute
(String
) -- the attribute to collect -
tag_name_2
(String
) -- the 2nd tag name to find -
tag_name_1
(String
) -- the 1st tag name to find
def find_2_eles_attr tag_name_1, tag_name_2, attribute # Use au.lookup(tag_name) instead of $(tag_name) # See https://github.com/appium/appium/issues/214 js = %Q( var eles = au.lookup('#{tag_name_1}'); eles = $(eles.concat(au.lookup('#{tag_name_2}'))); var result = []; for (var a = 0, length = eles.length; a < length; a++) { result.push(eles[a].#{attribute}()); } result ) @driver.execute_script js end
def find_eles_attr tag_name, attribute
-
(Array
- an array of strings containing the attribute from found elements of type tag_name.)
Parameters:
-
attribute
(String
) -- the attribute to collect -
tag_name
(String
) -- the tag name to find
def find_eles_attr tag_name, attribute # Use au.lookup(tag_name) instead of $(tag_name) # See https://github.com/appium/appium/issues/214 js = %Q( var eles = au.lookup('#{tag_name}'); var result = []; for (var a = 0, length = eles.length; a < length; a++) { result.push(eles[a].#{attribute}()); } result ) @driver.execute_script js end
def finds text
-
(Array
- all matching elements)
Parameters:
-
text
(String
) -- the text to search for
def finds text eles = [] # value contains may error js = all_ele_js "value contains[c] '#{text}'" eles = ignore { execute_script js } js = all_ele_js "name contains[c] '#{text}' || label contains[c] '#{text}'" eles += ignore { execute_script js } eles end
def first_ele_js predicate
-
(String)
- the completed JavaScript program
Parameters:
-
predicate
(String
) -- the predicate
Other tags:
- Private: -
def first_ele_js predicate (<<-JS).strip # remove trailing newline au.mainApp.getFirstWithPredicateWeighted("#{predicate}"); JS end
def first_textfield
-
(Textfield)
-
def first_textfield js = textfield_js 'r = r.length > 0 ? $(r[0]) : r;' execute_script(js).first end
def fix_space s
- Private: -
def fix_space s # ints don't respond to force encoding return s unless s.respond_to? :force_encoding # char code 160 (name, label) vs 32 (value) will break comparison. # convert string to binary and remove 160. # \xC2\xA0 s.force_encoding('binary').gsub("\xC2\xA0".force_encoding('binary'), ' ') if s end
def get_page element=source_window(0)
-
(String)
-
Parameters:
-
element
(Object
) -- the element to search. omit to search everything
def get_page element=source_window(0) lazy_load_strings # @private def empty ele (ele['name'] || ele['label'] || ele['value']) == nil end # @private def fix_space s # ints don't respond to force encoding return s unless s.respond_to? :force_encoding # char code 160 (name, label) vs 32 (value) will break comparison. # convert string to binary and remove 160. # \xC2\xA0 s.force_encoding('binary').gsub("\xC2\xA0".force_encoding('binary'), ' ') if s end unless empty(element) puts "#{element['type']}" name = fix_space element['name'] label = fix_space element['label'] value = fix_space element['value'] if name == label && name == value puts " name, label, value: #{name}" if name elsif name == label puts " name, label: #{name}" if name puts " value: #{value}" if value elsif name == value puts " name, value: #{name}" if name puts " label: #{label}" if label else puts " name: #{name}" if name puts " label: #{label}" if label puts " value: #{value}" if value end # there may be many ids with the same value. # output all exact matches. id_matches = @strings_xml.select do |key, val| val == name || val == label || val == value end if id_matches && id_matches.length > 0 match_str = '' # [0] = key, [1] = value id_matches.each do |match| match_str += ' ' * 7 + "#{match[0]}\n" end puts " id: #{match_str.strip}\n" end end children = element['children'] children.each { |c| get_page c } if children nil end
def get_page_class
def get_page_class r = [] run_internal = lambda do |node| if node.kind_of? Array node.each { |node| run_internal.call node } return end keys = node.keys return if keys.empty? r.push node['type'] if keys.include?('type') run_internal.call node['children'] if keys.include?('children') end json = get_source run_internal.call json['children'] res = [] r = r.sort r.uniq.each do |ele| res.push "#{r.count(ele)}x #{ele}\n" end count_sort = ->(one,two) { two.match(/(\d+)x/)[1].to_i <=> one.match(/(\d+)x/)[1].to_i } res.sort(&count_sort).join '' end
def last_textfield
-
(Textfield)
-
def last_textfield js = textfield_js 'r = r.length > 0 ? $(r[r.length - 1]) : r;' execute_script(js).first end
def name name
-
(Element)
- the first matching element
Parameters:
-
name
(String
) -- the name to search for
def name name mobile :findElementNameContains, name: name end
def names name
-
(Array
- all matching elements)
Parameters:
-
name
(String
) -- the name to search for
def names name # :name is not consistent across iOS and Android so use custom JavaScript # https://github.com/appium/appium/issues/379 js = all_ele_js "name contains[c] '#{name}' || label contains[c] '#{name}'" execute_script js end
def page
-
(void)
-
def page get_page nil end
def page_class
def page_class puts get_page_class nil end
def page_window window_number=0
-
window_number
(Integer
) -- the int index of the target window
def page_window window_number=0 get_page source_window window_number nil end
def password length=1
-
(String)
- the returned string is of size length
Parameters:
-
length
(Integer
) -- the length of the password to generate
def password length=1 '•' * length end
def patch_webdriver_element
- Private: -
def patch_webdriver_element Selenium::WebDriver::Element.class_eval do # Cross platform way of entering text into a textfield def type text # enter text then tap window to hide the keyboard. egin nd the top left corner of the keyboard and move up 10 pixels (origin.y - 10) w swipe down until the end of the window - 10 pixels. 0 to ensure we're not going outside the window bounds. iping inside the keyboard will not dismiss it. nd # type $driver.execute_script %(au.getElement('#{self.ref}').setValue('#{text}');) $driver.ignore { # wait 5 seconds for keyboard. if the textfield is disabled then # setValue will work, however the keyboard will never display # because users are normally not allowed to type into it. $driver.wait_true(5) do $driver.execute_script %(au.mainApp.keyboard().type() !== 'UIAElementNil') end # dismiss keyboard js = <<-JS if (au.mainApp.keyboard().type() !== "UIAElementNil") { var startY = au.mainApp.keyboard().rect().origin.y - 10; var endY = au.mainWindow.rect().size.height - 10; au.flickApp(0, startY, 0, endY); } JS $driver.execute_script js } end end end
def source_window window_number=0
-
(JSON)
-
Parameters:
-
window_number
(Integer
) -- the int index of the target window
def source_window window_number=0 execute_script "UIATarget.localTarget().frontMostApp().windows()[#{window_number}].getTree()" end
def text text
-
(Element)
- the first matching element
Parameters:
-
text
(String
) -- the text to search for
def text text js = first_ele_js "value contains[c] '#{text}'" execute_script js end
def textfield text
-
(Textfield)
-
Parameters:
-
text
(String, Integer
) -- the text to match exactly. If int then the textfield at that index is returned.
def textfield text # Don't use ele_index because that only works on one element type. # iOS needs to combine textfield and secure to match Android. if text.is_a? Numeric js = textfield_js "r = r.length > 0 ? $(r[#{text}]) : r;" return execute_script(js).first end textfield_include text end
def textfield_exact text
-
(Textfield)
-
Parameters:
-
text
(String
) -- the text the textfield must exactly match
def textfield_exact text # find_ele_by_text :textfield, text js = %Q( var t = au.getElementsByXpath('textfield[@text="#{text}"]').value; var s = au.getElementsByXpath('secure[@text="#{text}"]').value; t.concat(s)[0]; ) execute_script js end
def textfield_include text
-
(Textfield)
-
Parameters:
-
text
(String
) -- the text the textfield must include
def textfield_include text js = %Q( var t = au.getElementsByXpath('textfield[contains(@text, "#{text}")]').value; var s = au.getElementsByXpath('secure[contains(@text, "#{text}")]').value; t.concat(s)[0]; ) execute_script js end
def textfield_js filter=''
- Private: -
def textfield_js filter='' %Q( var t = au.lookup('textfield'); var s = au.lookup('secure'); var r = $(t.concat(s)); #{filter} au._returnElems(r); ) end
def textfields
-
(Array
-)
def textfields find_2_eles_attr :textfield, :secure, :text end
def texts text
-
(Array
- all matching elements)
Parameters:
-
text
(String
) -- the text to search for
def texts text # XPath //* is not implemented on iOS # https://github.com/appium/appium/issues/430 js = all_ele_js "value contains[c] '#{text}'" execute_script js end
def type text
def type text # enter text then tap window to hide the keyboard. he top left corner of the keyboard and move up 10 pixels (origin.y - 10) ipe down until the end of the window - 10 pixels. ensure we're not going outside the window bounds. g inside the keyboard will not dismiss it. # type $driver.execute_script %(au.getElement('#{self.ref}').setValue('#{text}');) $driver.ignore { # wait 5 seconds for keyboard. if the textfield is disabled then # setValue will work, however the keyboard will never display # because users are normally not allowed to type into it. $driver.wait_true(5) do $driver.execute_script %(au.mainApp.keyboard().type() !== 'UIAElementNil') end # dismiss keyboard js = <<-JS if (au.mainApp.keyboard().type() !== "UIAElementNil") { var startY = au.mainApp.keyboard().rect().origin.y - 10; var endY = au.mainWindow.rect().size.height - 10; au.flickApp(0, startY, 0, endY); } JS $driver.execute_script js } end