From 118262a94c2e04e601c5338250610a2cdb87b8d2 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Tue, 18 Apr 2017 08:26:57 +0900 Subject: [PATCH 1/5] separate find_element/s for uiautomator and xpath --- lib/appium_lib/android/element/button.rb | 8 +-- lib/appium_lib/android/helper.rb | 69 +++++++++++++++++++++--- lib/appium_lib/driver.rb | 6 +++ 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/lib/appium_lib/android/element/button.rb b/lib/appium_lib/android/element/button.rb index a25b95ba..013f8484 100644 --- a/lib/appium_lib/android/element/button.rb +++ b/lib/appium_lib/android/element/button.rb @@ -13,14 +13,14 @@ def _button_visible_selectors # @private def _button_exact_string(value) - string_visible_exact(Button, value) + - string_visible_exact(ImageButton, value).sub(/\A\/\//, '|') + string_visible_exact_xpath(Button, value) + + string_visible_exact_xpath(ImageButton, value).sub(/\A\/\//, '|') end # @private def _button_contains_string(value) - string_visible_contains(Button, value) + - string_visible_contains(ImageButton, value).sub(/\A\/\//, '|') + string_visible_contains_xpath(Button, value) + + string_visible_contains_xpath(ImageButton, value).sub(/\A\/\//, '|') end public diff --git a/lib/appium_lib/android/helper.rb b/lib/appium_lib/android/helper.rb index 5b2486cd..fe661c9e 100644 --- a/lib/appium_lib/android/helper.rb +++ b/lib/appium_lib/android/helper.rb @@ -285,7 +285,7 @@ def resource_id(string, on_match) # @param class_name [String] the class name for the element # @param value [String] the value to search for # @return [String] - def string_visible_contains(class_name, value) + def string_visible_contains_xpath(class_name, value) r_id = resource_id(value, " or @resource-id='#{value}'") if class_name == '*' @@ -297,12 +297,37 @@ def string_visible_contains(class_name, value) " or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']' end + # Returns a string that matches the first element that contains value + # + # example: complex_find_contains 'UIATextField', 'sign in' + # + # @param class_name [String] the class name for the element + # @param value [String] the value to search for + # @return [String] + def string_visible_contains(class_name, value) + value = %("#{value}") + if class_name == '*' + return (resource_id(value, "new UiSelector().resourceId(#{value});") + + "new UiSelector().descriptionContains(#{value});" \ + "new UiSelector().textContains(#{value});") + end + + class_name = %("#{class_name}") + resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") + + "new UiSelector().className(#{class_name}).descriptionContains(#{value});" \ + "new UiSelector().className(#{class_name}).textContains(#{value});" + end + # Find the first element that contains value # @param element [String] the class name for the element # @param value [String] the value to search for # @return [Element] def complex_find_contains(element, value) - find_element :xpath, string_visible_contains(element, value) + if automation_name_is_uiautomator2? + find_element :xpath, string_visible_contains_xpath(element, value) + else + find_element :uiautomator, string_visible_contains(element, value) + end end # Find all elements containing value @@ -310,7 +335,11 @@ def complex_find_contains(element, value) # @param value [String] the value to search for # @return [Array] def complex_finds_contains(element, value) - find_elements :xpath, string_visible_contains(element, value) + if automation_name_is_uiautomator2? + find_elements :xpath, string_visible_contains_xpath(element, value) + else + find_elements :uiautomator, string_visible_contains(element, value) + end end # @private @@ -318,7 +347,7 @@ def complex_finds_contains(element, value) # @param class_name [String] the class name for the element # @param value [String] the value to search for # @return [String] - def string_visible_exact(class_name, value) + def string_visible_exact_xpath(class_name, value) r_id = resource_id(value, " or @resource-id='#{value}'") if class_name == '*' @@ -328,12 +357,36 @@ def string_visible_exact(class_name, value) "//#{class_name}[@text='#{value}' or @content-desc='#{value}'" + r_id + ']' end + # @private + # Create an string to exactly match the first element with target value + # @param class_name [String] the class name for the element + # @param value [String] the value to search for + # @return [String] + def string_visible_exact(class_name, value) + value = %("#{value}") + + if class_name == '*' + return (resource_id(value, "new UiSelector().resourceId(#{value});") + + "new UiSelector().description(#{value});" \ + "new UiSelector().text(#{value});") + end + + class_name = %("#{class_name}") + resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") + + "new UiSelector().className(#{class_name}).description(#{value});" \ + "new UiSelector().className(#{class_name}).text(#{value});" + end + # Find the first element exactly matching value # @param class_name [String] the class name for the element # @param value [String] the value to search for # @return [Element] def complex_find_exact(class_name, value) - find_element :xpath, string_visible_exact(class_name, value) + if automation_name_is_uiautomator2? + find_element :xpath, string_visible_exact_xpath(class_name, value) + else + find_element :uiautomator, string_visible_exact(class_name, value) + end end # Find all elements exactly matching value @@ -341,7 +394,11 @@ def complex_find_exact(class_name, value) # @param value [String] the value to search for # @return [Element] def complex_finds_exact(class_name, value) - find_elements :xpath, string_visible_exact(class_name, value) + if automation_name_is_uiautomator2? + find_elements :xpath, string_visible_exact_xpath(class_name, value) + else + find_elements :uiautomator, string_visible_exact(class_name, value) + end end # Returns XML string for the current page diff --git a/lib/appium_lib/driver.rb b/lib/appium_lib/driver.rb index a06ad0c8..8cf4ee66 100644 --- a/lib/appium_lib/driver.rb +++ b/lib/appium_lib/driver.rb @@ -474,6 +474,12 @@ def automation_name_is_xcuitest? !@automation_name.nil? && 'xcuitest'.casecmp(@automation_name).zero? end + # Return true if automationName is 'uiautomator2' + # @return [Boolean] + def automation_name_is_uiautomator2? + !@automation_name.nil? && 'uiautomator2'.casecmp(@automation_name).zero? + end + # Return true if the target Appium server is over REQUIRED_VERSION_XCUITEST. # If the Appium server is under REQUIRED_VERSION_XCUITEST, then error is raised. # @return [Boolean] From f4b18d229509eb9c7fdde2a98316063202c90cb8 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Tue, 18 Apr 2017 08:59:44 +0900 Subject: [PATCH 2/5] fix button methods --- lib/appium_lib/android/element/button.rb | 90 ++++++++++++++++++++---- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/lib/appium_lib/android/element/button.rb b/lib/appium_lib/android/element/button.rb index 013f8484..18147a8e 100644 --- a/lib/appium_lib/android/element/button.rb +++ b/lib/appium_lib/android/element/button.rb @@ -7,22 +7,47 @@ module Android private # @private - def _button_visible_selectors + def _button_visible_selectors_xpath "//#{Button}|#{ImageButton}" end + def _button_visible_selectors(opts = {}) + button_index = opts.fetch :button_index, false + image_button_index = opts.fetch :image_button_index, false + + if button_index && image_button_index + "new UiSelector().className(#{Button}).instance(#{button_index});" \ + "new UiSelector().className(#{ImageButton}).instance(#{image_button_index});" + else + "new UiSelector().className(#{Button});" \ + "new UiSelector().className(#{ImageButton});" + end + end + # @private - def _button_exact_string(value) + def _button_exact_string_xpath(value) string_visible_exact_xpath(Button, value) + string_visible_exact_xpath(ImageButton, value).sub(/\A\/\//, '|') end + def _button_exact_string(value) + button = string_visible_exact Button, value + image_button = string_visible_exact ImageButton, value + button + image_button + end + # @private - def _button_contains_string(value) + def _button_contains_string_xpath(value) string_visible_contains_xpath(Button, value) + string_visible_contains_xpath(ImageButton, value).sub(/\A\/\//, '|') end + def _button_contains_string(value) + button = string_visible_contains Button, value + image_button = string_visible_contains ImageButton, value + button + image_button + end + public # Find the first button that contains value or by index. @@ -36,12 +61,17 @@ def button(value) index = value raise "#{index} is not a valid index. Must be >= 1" if index <= 0 - result = find_elements(:xpath, _button_visible_selectors)[value - 1] - raise Selenium::WebDriver::Error::NoSuchElementError unless result + if automation_name_is_uiautomator2? + result = find_elements(:xpath, _button_visible_selectors_xpath)[value - 1] + raise Selenium::WebDriver::Error::NoSuchElementError unless result + else + result = find_element :uiautomator, _button_visible_selectors(index: index) + end + return result end - find_element :xpath, _button_contains_string(value) + find_element :xpath, _button_contains_string_xpath(value) end # Find all buttons containing value. @@ -49,36 +79,68 @@ def button(value) # @param value [String] the value to search for # @return [Array