lib/appium_lib/ios/common/helper.rb in appium_lib-9.15.1 vs lib/appium_lib/ios/common/helper.rb in appium_lib-9.15.2

- old
+ new

@@ -4,32 +4,31 @@ class UITestElementsPrinter < Nokogiri::XML::SAX::Document attr_accessor :filter def start_element(type, attrs = []) return if filter && !filter.eql?(type) + page = attrs.inject({}) do |hash, attr| hash[attr[0]] = attr[1] if %w(name label value hint visible).include?(attr[0]) hash end _print_attr(type, page['name'], page['label'], page['value'], page['hint'], page['visible']) end # @private def _print_attr(type, name, label, value, hint, visible) # rubocop:disable Metrics/ParameterLists + puts type.to_s if name || label || value || hint || visible + if name == label && name == value - puts type.to_s if name || label || value || hint || visible puts " name, label, value: #{name}" if name elsif name == label - puts type.to_s if name || label || value || hint || visible puts " name, label: #{name}" if name puts " value: #{value}" if value elsif name == value - puts type.to_s if name || label || value || hint || visible puts " name, value: #{name}" if name puts " label: #{label}" if label else - puts type.to_s if name || label || value || hint || visible puts " name: #{name}" if name puts " label: #{label}" if label puts " value: #{value}" if value end puts " hint: #{hint}" if hint @@ -58,27 +57,27 @@ # # @return [void] def page(opts = {}) class_name = opts.is_a?(Hash) ? opts.fetch(:class, nil) : opts + source = get_source + # current_context may be nil which breaks start_with if current_context && current_context.start_with?('WEBVIEW') - s = get_source parser = @android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Appium::Common::HTMLElements.new) parser.document.reset parser.document.filter = class_name - parser.parse s + parser.parse source result = parser.document.result puts result result else - s = get_source parser = Nokogiri::XML::SAX::Parser.new(UITestElementsPrinter.new) if class_name parser.document.filter = class_name.is_a?(Symbol) ? class_name.to_s : class_name end - parser.parse s + parser.parse source nil end end # Find by id @@ -92,10 +91,11 @@ # @param class_name [String] the class name to find # @param index [Integer] the index # @return [Element] def ele_index(class_name, index) raise 'Index must be >= 1' unless index == 'last()' || (index.is_a?(Integer) && index >= 1) + elements = tags(class_name) if index == 'last()' result = elements.last else @@ -103,10 +103,11 @@ index -= 1 result = elements[index] end raise _no_such_element if result.nil? + result end # @private def string_attr_exact(class_name, attr, value) @@ -145,25 +146,26 @@ # @param value [String] the expected value of the attribute # @return [Element] def find_ele_by_predicate(class_name: '*', value:) elements = find_eles_by_predicate(class_name: class_name, value: value) raise _no_such_element if elements.empty? + elements.first end # Find all elements exactly matching attribute case insensitive value. # Note: Uses Predicate # @param value [String] the value of the attribute that the element must have # @param class_name [String] the tag name to match # @return [Array<Element>] def find_eles_by_predicate(class_name: '*', value:) - predicate = if class_name == '*' - %(name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}") - else - %(type == "#{class_name}" && ) + - %((name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}")) - end + predicate = if class_name == '*' + %(name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}") + else + %(type == "#{class_name}" && ) + + %((name ==[c] "#{value}" || label ==[c] "#{value}" || value ==[c] "#{value}")) + end @driver.find_elements :predicate, predicate end # Get the first tag by attribute that exactly matches value. # Note: Uses XPath @@ -190,10 +192,11 @@ # @param value [String] the value of the attribute that the element must include # @return [Element] the element of type tag who's attribute includes value def find_ele_by_predicate_include(class_name: '*', value:) elements = find_eles_by_predicate_include(class_name: class_name, value: value) raise _no_such_element if elements.empty? + elements.first end # Get elements that include case insensitive value. # Note: Uses Predicate @@ -278,21 +281,21 @@ # @param element [String] the class name for the element # @param value [String] the value to search for # @return [String] def string_visible_contains(element, value) contains = { - target: value, - substring: true, + target: value, + substring: true, insensitive: true } { - typeArray: [element], + typeArray: [element], onlyVisible: true, - name: contains, - label: contains, - value: contains + name: contains, + label: contains, + value: contains } end # Find the first element that contains value. # For Appium(automation name), not XCUITest @@ -317,21 +320,21 @@ # @param element [String] the class name for the element # @param value [String] the value to search for # @return [String] def string_visible_exact(element, value) exact = { - target: value, - substring: false, + target: value, + substring: false, insensitive: false } { - typeArray: [element], + typeArray: [element], onlyVisible: true, - name: exact, - label: exact, - value: exact + name: exact, + label: exact, + value: exact } end # Find the first element exactly matching value # For Appium(automation name), not XCUITest @@ -357,10 +360,11 @@ # visible - if true, only visible elements are returned. default true # def _all_pred(opts) predicate = opts[:predicate] raise 'predicate must be provided' unless predicate + visible = opts.fetch :visible, true %($.mainApp().getAllWithPredicate("#{predicate}", #{visible});) end # returns element matching predicate contained in the main app @@ -384,14 +388,15 @@ find_elements(:uiautomation, _all_pred(opts)) end def _validate_object(*objects) raise 'objects must be an array' unless objects.is_a? Array + objects.each do |obj| next unless obj # obj may be nil. if so, ignore. - valid_keys = [:target, :substring, :insensitive] + valid_keys = %i[target substring insensitive] unknown_keys = obj.keys - valid_keys raise "Unknown keys: #{unknown_keys}" unless unknown_keys.empty? target = obj[:target] raise 'target must be a string' unless target.is_a? String @@ -432,11 +437,11 @@ # insensitive: false, # } # } # def _by_json(opts) - valid_keys = [:typeArray, :onlyFirst, :onlyVisible, :name, :label, :value] + valid_keys = %i(typeArray onlyFirst onlyVisible name label value) unknown_keys = opts.keys - valid_keys raise "Unknown keys: #{unknown_keys}" unless unknown_keys.empty? type_array = opts[:typeArray] raise 'typeArray must be an array' unless type_array.is_a? Array @@ -466,11 +471,11 @@ return result; })(); JS res = execute_script element_or_elements_by_type - res ? res : raise(Appium::Ios::CommandError, 'mainWindow is nil') + res || raise(Appium::Ios::CommandError, 'mainWindow is nil') end # For Appium(automation name), not XCUITest # example usage: # @@ -489,11 +494,12 @@ end # see eles_by_json def ele_by_json(opts) opts[:onlyFirst] = true - result = _by_json(opts).first + result = _by_json(opts).first raise _no_such_element if result.nil? + result end end # module Ios end # module Appium