diff --git a/ios_tests/lib/ios/specs/ios/helper.rb b/ios_tests/lib/ios/specs/ios/helper.rb index 8f92c31a..7005552e 100644 --- a/ios_tests/lib/ios/specs/ios/helper.rb +++ b/ios_tests/lib/ios/specs/ios/helper.rb @@ -13,10 +13,6 @@ def before_first ios_password(2).must_equal 8226.chr('UTF-8') * 2 end - t 'get_page' do - get_page # writes to std out - end - t 'page' do page # writes to std out end @@ -31,8 +27,8 @@ def before_first id 'Buttons' # 'Various uses of UIButton' end - t 'ios_version' do - ios_version.wont_be_empty + t 'platform_version' do + platform_version.wont_be_empty end t 'tags_include' do diff --git a/lib/appium_lib/android/android.rb b/lib/appium_lib/android/android.rb index e832b2a1..53d86daf 100644 --- a/lib/appium_lib/android/android.rb +++ b/lib/appium_lib/android/android.rb @@ -3,8 +3,6 @@ require_relative 'device' require_relative 'common/helper' -require_relative 'common/patch' -require_relative 'common/client_xpath' require_relative 'element/alert' require_relative 'element/button' diff --git a/lib/appium_lib/android/common/client_xpath.rb b/lib/appium_lib/android/common/client_xpath.rb deleted file mode 100644 index df3f9be7..00000000 --- a/lib/appium_lib/android/common/client_xpath.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'nokogiri' - -module Appium - module Android - def _nodeset_to_uiselector(opts = {}) - results = '' - - nodes = opts[:nodes] - first = opts[:first] - - nodes = [nodes[0]] if first - - nodes.each do |node| - results += %(new UiSelector().className("#{node.name}").instance(#{node.attr('instance')});) - end - - results.strip - end - - def _client_xpath(opts = {}) - root_node = Nokogiri::XML(get_source).children.first - - instance = Hash.new(-1) - - root_node.traverse do |node| - number = instance[node.name] += 1 - node.set_attribute 'instance', number - end - - nodes = root_node.xpath(opts[:xpath]) - first = opts[:first] - - _nodeset_to_uiselector nodes: nodes, first: first - end - - # @deprecated Please use :uiautomator or :xpath strategy directly - def client_xpath(xpath) - warn '[DEPRECATION] client_xpath will be removed. Please use :uiautomator or :xpath strategy directly.' - find_element :uiautomator, _client_xpath(xpath: xpath, first: true) - end - - # @deprecated Please use :uiautomator or :xpath strategy directly - def client_xpaths(xpath) - warn '[DEPRECATION] client_xpaths will be removed. Please use :uiautomator or :xpath strategy directly.' - find_elements :uiautomator, _client_xpath(xpath: xpath, first: false) - end - end -end - -# http://stackoverflow.com/questions/9199415/getting-first-node-in-xpath-result-set -# '(//android.widget.TextView)[1]' not '//android.widget.TextView[1]' diff --git a/lib/appium_lib/android/common/patch.rb b/lib/appium_lib/android/common/patch.rb deleted file mode 100644 index 53459f00..00000000 --- a/lib/appium_lib/android/common/patch.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Appium - module Android - # @private - # class_eval inside a method because class Selenium::WebDriver::Element - # will trigger as soon as the file is required. in contrast a method - # will trigger only when invoked. - def patch_webdriver_element - Selenium::WebDriver::Element.class_eval do - # Cross platform way of entering text into a textfield - def type(text) - send_keys text - end - end - end - end # Android -end # Appium diff --git a/lib/appium_lib/common/wait.rb b/lib/appium_lib/common/wait.rb index c98f43a5..32178aa3 100644 --- a/lib/appium_lib/common/wait.rb +++ b/lib/appium_lib/common/wait.rb @@ -1,4 +1,4 @@ -require_relative '../core/wait' +require_relative '../core/common/wait' module Appium module Common diff --git a/lib/appium_lib/core/command.rb b/lib/appium_lib/core/command.rb index 68f1fd72..a3477f5c 100644 --- a/lib/appium_lib/core/command.rb +++ b/lib/appium_lib/core/command.rb @@ -2,7 +2,6 @@ module Appium module Core module Commands COMMAND_NO_ARG = { - # core shake: [:post, 'session/:session_id/appium/device/shake'.freeze], launch_app: [:post, 'session/:session_id/appium/app/launch'.freeze], close_app: [:post, 'session/:session_id/appium/app/close'.freeze], @@ -13,7 +12,6 @@ module Commands }.freeze COMMAND = { - # core available_contexts: [:get, 'session/:session_id/contexts'.freeze], set_context: [:post, 'session/:session_id/context'.freeze], app_strings: [:post, 'session/:session_id/appium/app/strings'.freeze], diff --git a/lib/appium_lib/core/error.rb b/lib/appium_lib/core/common/error.rb similarity index 100% rename from lib/appium_lib/core/error.rb rename to lib/appium_lib/core/common/error.rb diff --git a/lib/appium_lib/core/wait.rb b/lib/appium_lib/core/common/wait.rb similarity index 100% rename from lib/appium_lib/core/wait.rb rename to lib/appium_lib/core/common/wait.rb diff --git a/lib/appium_lib/core/core.rb b/lib/appium_lib/core/core.rb index 2012f73b..c0eb2ed2 100644 --- a/lib/appium_lib/core/core.rb +++ b/lib/appium_lib/core/core.rb @@ -1,13 +1,13 @@ require_relative 'command' -require_relative 'error' require_relative 'patch' require_relative 'search_context' -require_relative 'wait' require_relative 'device' require_relative 'capabilities' require_relative 'driver' +require_relative 'common/error' require_relative 'common/log' +require_relative 'common/wait' require_relative 'element/window' diff --git a/lib/appium_lib/core/driver.rb b/lib/appium_lib/core/driver.rb index 1e7c3856..005b29f7 100644 --- a/lib/appium_lib/core/driver.rb +++ b/lib/appium_lib/core/driver.rb @@ -145,6 +145,24 @@ def appium_server_version {} end + # Return the platform version as an array of integers + # @return [Array] + def platform_version + p_version = @driver.capabilities['platformVersion'] + p_version.split('.').map(&:to_i) + end + + # Takes a png screenshot and saves to the target path. + # + # Example: screenshot '/tmp/hi.png' + # + # @param png_save_path [String] the full path to save the png + # @return [nil] + def screenshot(png_save_path) + @driver.save_screenshot png_save_path + nil + end + private # @private diff --git a/lib/appium_lib/core/patch.rb b/lib/appium_lib/core/patch.rb index 49f8be6d..e1cd15ee 100644 --- a/lib/appium_lib/core/patch.rb +++ b/lib/appium_lib/core/patch.rb @@ -20,6 +20,15 @@ def name attribute :name end + # Enable access to iOS accessibility label + # accessibility identifier is supported as 'name' + def label + attribute :label + end + + # Alias for type + alias type send_keys + # For use with mobile tap. # # ```ruby diff --git a/lib/appium_lib/driver.rb b/lib/appium_lib/driver.rb index 1ae2d505..12264f23 100644 --- a/lib/appium_lib/driver.rb +++ b/lib/appium_lib/driver.rb @@ -155,9 +155,6 @@ def initialize(opts = {}, global_driver = nil) # Extend each driver's methods extend_for(device: @core.device, automation_name: @core.automation_name) - # apply os specific patches - patch_webdriver_element - # for command patch_remote_driver_core_commands(bridge: :oss) patch_remote_driver_core_commands(bridge: :w3c) @@ -197,7 +194,7 @@ def extend_for(device:, automation_name:) extend Appium::Android::Device end when :ios - case driver + case automation_name when :xcuitest extend Appium::Ios extend Appium::Ios::SearchContext @@ -213,6 +210,7 @@ def extend_for(device:, automation_name:) extend Appium::Ios extend Appium::Ios::SearchContext extend Appium::Ios::Device + patch_webdriver_element end when :mac # no Mac specific extentions @@ -325,6 +323,18 @@ def appium_server_version {} end + # Return the platform version as an array of integers + # @return [Array] + def platform_version + @core.platform_version + end + + # @private + def ios_version + warn '[DEPRECATION] ios_version will be removed. Please use platform_version instead.' + platform_version + end + # Returns the client's version info # # ```ruby @@ -399,8 +409,7 @@ def restart # @param png_save_path [String] the full path to save the png # @return [nil] def screenshot(png_save_path) - @driver.save_screenshot png_save_path - nil + @core.screenshot png_save_path end # Quits the driver diff --git a/lib/appium_lib/ios/common/helper.rb b/lib/appium_lib/ios/common/helper.rb index 3e2b4240..24ccd54e 100644 --- a/lib/appium_lib/ios/common/helper.rb +++ b/lib/appium_lib/ios/common/helper.rb @@ -12,6 +12,7 @@ def start_element(type, attrs = []) _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 if name == label && name == value puts type.to_s if name || label || value || hint || visible @@ -43,89 +44,6 @@ def ios_password(length = 1) 8226.chr('UTF-8') * length end - # Returns a string of interesting elements. iOS only. - # - # Defaults to inspecting the 1st windows source only. - # use get_page(get_source) for all window sources - # - # @option element [Object] the element to search. omit to search everything - # @option class_name [String,Symbol] the class name to filter on. case insensitive include match. - # @return [String] - # @deprecated - def get_page(element = source_window(0), class_name = nil) - warn '[DEPRECATION] get_page will be removed. Please use page or source instead.' - - lazy_load_strings # populate @strings_xml - class_name = class_name.to_s.downcase - - # @private - def empty(ele) - (ele['name'] || ele['label'] || ele['value']).nil? - end - - # @private - def fix_space(s) - # if s is an int, we can't call .empty - return nil if s.nil? || (s.respond_to?(:empty) && s.empty?) - # ints don't respond to force encoding - # ensure we're converting to a string - unless s.respond_to? :force_encoding - s_s = s.to_s - return s_s.empty? ? nil : s_s - end - # char code 160 (name, label) vs 32 (value) will break comparison. - # convert string to binary and remove 160. - # \xC2\xA0 - s = s.force_encoding('binary').gsub("\xC2\xA0".force_encoding('binary'), ' ') if s - s.empty? ? nil : s.force_encoding('UTF-8') - end - - unless empty(element) || element['visible'] == false - name = fix_space element['name'] - label = fix_space element['label'] - value = fix_space element['value'] - hint = fix_space element['hint'] - visible = fix_space element['visible'] - type = fix_space element['type'] - - # if class_name is set, mark non-matches as invisible - visible = (type.downcase.include? class_name).to_s if class_name - if visible && visible == 'true' - - UITestElementsPrinter.new._print_attr(type, name, label, value, hint, visible) - - # there may be many ids with the same value. - # output all exact matches. - attributes = [name, label, value, hint].select { |attr| !attr.nil? } - partial = {} - id_matches = @strings_xml.select do |key, val| - next if val.nil? || val.empty? - partial[key] = val if attributes.detect { |attr| attr.include?(val) } - attributes.detect { |attr| val == attr } - end - - # If there are no exact matches, display partial matches. - id_matches = partial if id_matches.empty? - - unless id_matches.empty? - match_str = '' - max_len = id_matches.keys.max_by(&:length).length - - # [0] = key, [1] = val - id_matches.each do |key, val| - arrow_space = ' ' * (max_len - key.length).to_i - match_str += ' ' * 7 + "#{key} #{arrow_space}=> #{val}\n" - end - puts " id: #{match_str.strip}\n" - end - end - end - - children = element['children'] - children.each { |c| get_page c, class_name } if children - nil - end - # Prints a string of interesting elements to the console. # # Example @@ -163,20 +81,20 @@ def page(opts = {}) # Gets the JSON source of window number # @return [JSON] - def source_window(window_number = nil) - warn '[DEPRECATION] The argument window_number will be removed. Plesse remove window_number' unless window_number + def source_window(_window_number = nil) + warn '[DEPRECATION] source_window will be removed. Please use source instead.' get_source end + # @private # Prints parsed page source to console. # # example: page_window 0 # # @param window_number [Integer] the int index of the target window # @return [void] - def page_window(window_number = 0) - get_page source_window window_number - nil + def page_window(_window_number = 0) + warn '[DEPRECATION] page_window will be removed. Please use source instead.' end # Find by id @@ -186,13 +104,6 @@ def id(id) find_element(:id, id) end - # Return the iOS version as an array of integers - # @return [Array] - def ios_version - ios_version = execute_script 'UIATarget.localTarget().systemVersion()' - ios_version.split('.').map(&:to_i) - end - # Get the element of type class_name at matching index. # @param class_name [String] the class name to find # @param index [Integer] the index diff --git a/lib/appium_lib/ios/common/patch.rb b/lib/appium_lib/ios/common/patch.rb index ec06f96b..d118e0e0 100644 --- a/lib/appium_lib/ios/common/patch.rb +++ b/lib/appium_lib/ios/common/patch.rb @@ -6,12 +6,6 @@ module Ios # will trigger only when invoked. def patch_webdriver_element Selenium::WebDriver::Element.class_eval do - # Enable access to iOS accessibility label - # accessibility identifier is supported as 'name' - def label - attribute('label') - end - # Cross platform way of entering text into a textfield def type(text, driver = $driver) driver.execute_script %(au.getElement('#{ref}').setValue('#{text}');) diff --git a/lib/appium_lib/ios/xcuitest/element.rb b/lib/appium_lib/ios/xcuitest/element.rb index 49cbb6f4..b04aeef2 100644 --- a/lib/appium_lib/ios/xcuitest/element.rb +++ b/lib/appium_lib/ios/xcuitest/element.rb @@ -7,24 +7,7 @@ module Appium module Ios module Xcuitest module Element - # @private - # class_eval inside a method because class Selenium::WebDriver::Element - # will trigger as soon as the file is required. in contrast a method - # will trigger only when invoked. - def patch_webdriver_element - Selenium::WebDriver::Element.class_eval do - # Enable access to iOS accessibility label - # accessibility identifier is supported as 'name' - def label - attribute('label') - end - - # Cross platform way of entering text into a textfield - def type(text) - send_keys text - end # def type - end # Selenium::WebDriver::Element.class_eval - end # def patch_webdriver_element + # no end # module Element end # module Xcuitest end # module Ios diff --git a/lib/appium_lib/ios/xcuitest/helper.rb b/lib/appium_lib/ios/xcuitest/helper.rb index 9fdc9cc7..a6899837 100644 --- a/lib/appium_lib/ios/xcuitest/helper.rb +++ b/lib/appium_lib/ios/xcuitest/helper.rb @@ -2,12 +2,6 @@ module Appium module Ios module Xcuitest module Helper - # Return the iOS version as an array of integers - # @return [Array] - def ios_version - @driver.capabilities['platformVersion'] - end - # @private def string_attr_exact(class_name, attr, value) if attr == '*' diff --git a/lib/appium_lib/sauce_labs.rb b/lib/appium_lib/sauce_labs.rb index d6cb5944..4e34d968 100644 --- a/lib/appium_lib/sauce_labs.rb +++ b/lib/appium_lib/sauce_labs.rb @@ -15,8 +15,7 @@ def initialize(appium_lib_opts) @access_key = nil if !@access_key || (@access_key.is_a?(String) && @access_key.empty?) @endpoint = appium_lib_opts.fetch :sauce_endpoint, ENV['SAUCE_ENDPOINT'] - @endpoint = 'ondemand.saucelabs.com:443/wd/hub' if - !@endpoint || (@endpoint.is_a?(String) && @endpoint.empty?) + @endpoint = 'ondemand.saucelabs.com:443/wd/hub' if !@endpoint || (@endpoint.is_a?(String) && @endpoint.empty?) end def sauce_server_url?