appium_lib 9.3.8 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/android_tests/lib/android/specs/common/device.rb +2 -2
- data/android_tests/lib/android/specs/common/patch.rb +1 -1
- data/docs/android_docs.md +230 -230
- data/docs/ios_docs.md +383 -249
- data/docs/ios_xcuitest.md +7 -0
- data/ios_tests/lib/ios/specs/ios/xcuitest_gestures.rb +61 -0
- data/lib/appium_lib/android/element/button.rb +18 -34
- data/lib/appium_lib/android/helper.rb +12 -22
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/driver.rb +2 -0
- data/lib/appium_lib/ios/xcuitest_gestures.rb +144 -0
- data/release_notes.md +7 -0
- metadata +4 -2
    
        data/docs/ios_xcuitest.md
    CHANGED
    
    | @@ -79,5 +79,12 @@ finds_exact(value) # Return any elements include `value` as its name attributes. | |
| 79 79 | 
             
            xpaths("//some xpaths")
         | 
| 80 80 | 
             
            ```
         | 
| 81 81 |  | 
| 82 | 
            +
            ## Gesture
         | 
| 83 | 
            +
            - `mobile:` commands are provided by WDA.
         | 
| 84 | 
            +
            - Documentations
         | 
| 85 | 
            +
                - https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/ios-xctest-mobile-gestures.md
         | 
| 86 | 
            +
            - Specs by test code
         | 
| 87 | 
            +
                - https://github.com/appium/appium-xcuitest-driver/blob/master/test/functional/basic/gesture-e2e-specs.js
         | 
| 88 | 
            +
             | 
| 82 89 | 
             
            ## Other actions
         | 
| 83 90 | 
             
            Basically, other actions such as `type` are compatible with `automationName = Appium`.
         | 
| @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            # rake ios[ios/xcuitest_gestures]
         | 
| 2 | 
            +
            describe 'ios/xcuitest_gestures' do
         | 
| 3 | 
            +
              def before_first
         | 
| 4 | 
            +
                screen.must_equal catalog
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def after_last
         | 
| 8 | 
            +
                screen.must_equal catalog
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              t 'before_first' do
         | 
| 12 | 
            +
                before_first
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              t 'tap' do
         | 
| 16 | 
            +
                element = text('controls')
         | 
| 17 | 
            +
                tap(x: 0, y: 0, element: element)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              t 'double_tap' do
         | 
| 21 | 
            +
                element = button('Tinted')
         | 
| 22 | 
            +
                double_tap(element: element)
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              t 'scroll' do
         | 
| 26 | 
            +
                scroll direction: 'down'
         | 
| 27 | 
            +
                text('Style Default').displayed?.must_be true
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              t 'swipe' do
         | 
| 31 | 
            +
                swipe direction: 'down'
         | 
| 32 | 
            +
                swipe direction: 'down'
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                proc { text('Style Default') }.must_raise ::Selenium::WebDriver::Error::NoSuchElementError
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              t 'pinch' do
         | 
| 38 | 
            +
                pinch(scale: 0.5, velocity: -1)
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              t 'back to top' do
         | 
| 42 | 
            +
                back_click
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              t 'select_picker_wheel' do
         | 
| 46 | 
            +
                element = text('pickers')
         | 
| 47 | 
            +
                tap(x: 0, y: 0, element: element)
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                e = find_element :name, 'John Appleseed'
         | 
| 50 | 
            +
                select_picker_wheel(element: e, order: 'next')
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                e.displayed?.must_be false
         | 
| 53 | 
            +
                find_element(:name, 'Serena Auroux').displayed?.must_be true
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                back_click
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              t 'after_last' do
         | 
| 59 | 
            +
                after_last
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| @@ -7,31 +7,20 @@ module Appium | |
| 7 7 | 
             
                private
         | 
| 8 8 |  | 
| 9 9 | 
             
                # @private
         | 
| 10 | 
            -
                def _button_visible_selectors | 
| 11 | 
            -
                   | 
| 12 | 
            -
                  image_button_index = opts.fetch :image_button_index, false
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  if button_index && image_button_index
         | 
| 15 | 
            -
                    "new UiSelector().className(#{Button}).instance(#{button_index});" \
         | 
| 16 | 
            -
                      "new UiSelector().className(#{ImageButton}).instance(#{image_button_index});"
         | 
| 17 | 
            -
                  else
         | 
| 18 | 
            -
                    "new UiSelector().className(#{Button});" \
         | 
| 19 | 
            -
                      "new UiSelector().className(#{ImageButton});"
         | 
| 20 | 
            -
                  end
         | 
| 10 | 
            +
                def _button_visible_selectors
         | 
| 11 | 
            +
                  "//#{Button}|#{ImageButton}"
         | 
| 21 12 | 
             
                end
         | 
| 22 13 |  | 
| 23 14 | 
             
                # @private
         | 
| 24 15 | 
             
                def _button_exact_string(value)
         | 
| 25 | 
            -
                   | 
| 26 | 
            -
             | 
| 27 | 
            -
                  button + image_button
         | 
| 16 | 
            +
                  string_visible_exact(Button, value) +
         | 
| 17 | 
            +
                      string_visible_exact(ImageButton, value).sub(/\A\/\//, '|')
         | 
| 28 18 | 
             
                end
         | 
| 29 19 |  | 
| 30 20 | 
             
                # @private
         | 
| 31 21 | 
             
                def _button_contains_string(value)
         | 
| 32 | 
            -
                   | 
| 33 | 
            -
             | 
| 34 | 
            -
                  button + image_button
         | 
| 22 | 
            +
                  string_visible_contains(Button, value) +
         | 
| 23 | 
            +
                      string_visible_contains(ImageButton, value).sub(/\A\/\//, '|')
         | 
| 35 24 | 
             
                end
         | 
| 36 25 |  | 
| 37 26 | 
             
                public
         | 
| @@ -47,10 +36,12 @@ module Appium | |
| 47 36 | 
             
                    index = value
         | 
| 48 37 | 
             
                    raise "#{index} is not a valid index. Must be >= 1" if index <= 0
         | 
| 49 38 |  | 
| 50 | 
            -
                     | 
| 39 | 
            +
                    result = find_elements(:xpath, _button_visible_selectors)[value - 1]
         | 
| 40 | 
            +
                    raise Selenium::WebDriver::Error::NoSuchElementError unless result
         | 
| 41 | 
            +
                    return result
         | 
| 51 42 | 
             
                  end
         | 
| 52 43 |  | 
| 53 | 
            -
                  find_element : | 
| 44 | 
            +
                  find_element :xpath, _button_contains_string(value)
         | 
| 54 45 | 
             
                end
         | 
| 55 46 |  | 
| 56 47 | 
             
                # Find all buttons containing value.
         | 
| @@ -58,43 +49,36 @@ module Appium | |
| 58 49 | 
             
                # @param value [String] the value to search for
         | 
| 59 50 | 
             
                # @return [Array<Button>]
         | 
| 60 51 | 
             
                def buttons(value = false)
         | 
| 61 | 
            -
                  return find_elements : | 
| 62 | 
            -
                  find_elements : | 
| 52 | 
            +
                  return find_elements :xpath, _button_visible_selectors unless value
         | 
| 53 | 
            +
                  find_elements :xpath, _button_contains_string(value)
         | 
| 63 54 | 
             
                end
         | 
| 64 55 |  | 
| 65 56 | 
             
                # Find the first button.
         | 
| 66 57 | 
             
                # @return [Button]
         | 
| 67 58 | 
             
                def first_button
         | 
| 68 | 
            -
                  find_element : | 
| 59 | 
            +
                  find_element :xpath, _button_visible_selectors
         | 
| 69 60 | 
             
                end
         | 
| 70 61 |  | 
| 71 62 | 
             
                # Find the last button.
         | 
| 72 63 | 
             
                # @return [Button]
         | 
| 73 64 | 
             
                def last_button
         | 
| 74 | 
            -
                   | 
| 75 | 
            -
                   | 
| 76 | 
            -
                   | 
| 77 | 
            -
                  button_index -= 1 if button_index > 0
         | 
| 78 | 
            -
                  image_button_index = tags(ImageButton).length
         | 
| 79 | 
            -
                  image_button_index -= 1 if image_button_index > 0
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                  find_element :uiautomator,
         | 
| 82 | 
            -
                               _button_visible_selectors(button_index: button_index,
         | 
| 83 | 
            -
                                                         image_button_index: image_button_index)
         | 
| 65 | 
            +
                  result = find_elements(:xpath, _button_visible_selectors).last
         | 
| 66 | 
            +
                  raise Selenium::WebDriver::Error::NoSuchElementError unless result
         | 
| 67 | 
            +
                  result
         | 
| 84 68 | 
             
                end
         | 
| 85 69 |  | 
| 86 70 | 
             
                # Find the first button that exactly matches value.
         | 
| 87 71 | 
             
                # @param value [String] the value to match exactly
         | 
| 88 72 | 
             
                # @return [Button]
         | 
| 89 73 | 
             
                def button_exact(value)
         | 
| 90 | 
            -
                  find_element : | 
| 74 | 
            +
                  find_element :xpath, _button_exact_string(value)
         | 
| 91 75 | 
             
                end
         | 
| 92 76 |  | 
| 93 77 | 
             
                # Find all buttons that exactly match value.
         | 
| 94 78 | 
             
                # @param value [String] the value to match exactly
         | 
| 95 79 | 
             
                # @return [Array<Button>]
         | 
| 96 80 | 
             
                def buttons_exact(value)
         | 
| 97 | 
            -
                  find_elements : | 
| 81 | 
            +
                  find_elements :xpath, _button_exact_string(value)
         | 
| 98 82 | 
             
                end
         | 
| 99 83 | 
             
              end # module Android
         | 
| 100 84 | 
             
            end # module Appium
         | 
| @@ -286,19 +286,15 @@ module Appium | |
| 286 286 | 
             
                # @param value [String] the value to search for
         | 
| 287 287 | 
             
                # @return [String]
         | 
| 288 288 | 
             
                def string_visible_contains(class_name, value)
         | 
| 289 | 
            -
                   | 
| 289 | 
            +
                  r_id = resource_id(value, " or @resource-id='#{value}'")
         | 
| 290 290 |  | 
| 291 291 | 
             
                  if class_name == '*'
         | 
| 292 | 
            -
                    return ( | 
| 293 | 
            -
             | 
| 294 | 
            -
                      "new UiSelector().textContains(#{value});")
         | 
| 292 | 
            +
                    return "//*[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
         | 
| 293 | 
            +
                        " or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
         | 
| 295 294 | 
             
                  end
         | 
| 296 295 |  | 
| 297 | 
            -
                  class_name  | 
| 298 | 
            -
             | 
| 299 | 
            -
                  resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
         | 
| 300 | 
            -
                    "new UiSelector().className(#{class_name}).descriptionContains(#{value});" \
         | 
| 301 | 
            -
                    "new UiSelector().className(#{class_name}).textContains(#{value});"
         | 
| 296 | 
            +
                  "//#{class_name}[contains(translate(@text,'#{value.upcase}', '#{value}'), '#{value}')" \
         | 
| 297 | 
            +
                    " or contains(translate(@content-desc,'#{value.upcase}', '#{value}'), '#{value}')" + r_id + ']'
         | 
| 302 298 | 
             
                end
         | 
| 303 299 |  | 
| 304 300 | 
             
                # Find the first element that contains value
         | 
| @@ -306,7 +302,7 @@ module Appium | |
| 306 302 | 
             
                # @param value [String] the value to search for
         | 
| 307 303 | 
             
                # @return [Element]
         | 
| 308 304 | 
             
                def complex_find_contains(element, value)
         | 
| 309 | 
            -
                  find_element : | 
| 305 | 
            +
                  find_element :xpath, string_visible_contains(element, value)
         | 
| 310 306 | 
             
                end
         | 
| 311 307 |  | 
| 312 308 | 
             
                # Find all elements containing value
         | 
| @@ -314,7 +310,7 @@ module Appium | |
| 314 310 | 
             
                # @param value [String] the value to search for
         | 
| 315 311 | 
             
                # @return [Array<Element>]
         | 
| 316 312 | 
             
                def complex_finds_contains(element, value)
         | 
| 317 | 
            -
                  find_elements : | 
| 313 | 
            +
                  find_elements :xpath, string_visible_contains(element, value)
         | 
| 318 314 | 
             
                end
         | 
| 319 315 |  | 
| 320 316 | 
             
                # @private
         | 
| @@ -323,19 +319,13 @@ module Appium | |
| 323 319 | 
             
                # @param value [String] the value to search for
         | 
| 324 320 | 
             
                # @return [String]
         | 
| 325 321 | 
             
                def string_visible_exact(class_name, value)
         | 
| 326 | 
            -
                   | 
| 322 | 
            +
                  r_id = resource_id(value, " or @resource-id='#{value}'")
         | 
| 327 323 |  | 
| 328 324 | 
             
                  if class_name == '*'
         | 
| 329 | 
            -
                    return  | 
| 330 | 
            -
                      "new UiSelector().description(#{value});" \
         | 
| 331 | 
            -
                      "new UiSelector().text(#{value});")
         | 
| 325 | 
            +
                    return "//*[@text='#{value}' or @content-desc='#{value}'" + r_id + ']'
         | 
| 332 326 | 
             
                  end
         | 
| 333 327 |  | 
| 334 | 
            -
                  class_name = | 
| 335 | 
            -
             | 
| 336 | 
            -
                  resource_id(value, "new UiSelector().className(#{class_name}).resourceId(#{value});") +
         | 
| 337 | 
            -
                    "new UiSelector().className(#{class_name}).description(#{value});" \
         | 
| 338 | 
            -
                    "new UiSelector().className(#{class_name}).text(#{value});"
         | 
| 328 | 
            +
                  "//#{class_name}[@text='#{value}' or @content-desc='#{value}'" + r_id + ']'
         | 
| 339 329 | 
             
                end
         | 
| 340 330 |  | 
| 341 331 | 
             
                # Find the first element exactly matching value
         | 
| @@ -343,7 +333,7 @@ module Appium | |
| 343 333 | 
             
                # @param value [String] the value to search for
         | 
| 344 334 | 
             
                # @return [Element]
         | 
| 345 335 | 
             
                def complex_find_exact(class_name, value)
         | 
| 346 | 
            -
                  find_element : | 
| 336 | 
            +
                  find_element :xpath, string_visible_exact(class_name, value)
         | 
| 347 337 | 
             
                end
         | 
| 348 338 |  | 
| 349 339 | 
             
                # Find all elements exactly matching value
         | 
| @@ -351,7 +341,7 @@ module Appium | |
| 351 341 | 
             
                # @param value [String] the value to search for
         | 
| 352 342 | 
             
                # @return [Element]
         | 
| 353 343 | 
             
                def complex_finds_exact(class_name, value)
         | 
| 354 | 
            -
                  find_elements : | 
| 344 | 
            +
                  find_elements :xpath, string_visible_exact(class_name, value)
         | 
| 355 345 | 
             
                end
         | 
| 356 346 |  | 
| 357 347 | 
             
                # Returns XML string for the current page
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            module Appium
         | 
| 2 2 | 
             
              # Version and Date are defined on the 'Appium' module, not 'Appium::Common'
         | 
| 3 | 
            -
              VERSION = '9. | 
| 4 | 
            -
              DATE    = '2017-04- | 
| 3 | 
            +
              VERSION = '9.4.0'.freeze unless defined? ::Appium::VERSION
         | 
| 4 | 
            +
              DATE    = '2017-04-17'.freeze unless defined? ::Appium::DATE
         | 
| 5 5 | 
             
            end
         | 
    
        data/lib/appium_lib/driver.rb
    CHANGED
    
    | @@ -24,6 +24,7 @@ require_relative 'ios/element/generic' | |
| 24 24 | 
             
            require_relative 'ios/element/textfield'
         | 
| 25 25 | 
             
            require_relative 'ios/element/text'
         | 
| 26 26 | 
             
            require_relative 'ios/mobile_methods'
         | 
| 27 | 
            +
            require_relative 'ios/xcuitest_gestures'
         | 
| 27 28 |  | 
| 28 29 | 
             
            # android
         | 
| 29 30 | 
             
            require_relative 'android/helper'
         | 
| @@ -411,6 +412,7 @@ module Appium | |
| 411 412 | 
             
                  else
         | 
| 412 413 | 
             
                    # load iOS specific methods
         | 
| 413 414 | 
             
                    extend Appium::Ios
         | 
| 415 | 
            +
                    extend Appium::Ios::XcuitestGesture if automation_name_is_xcuitest? # Override touch actions
         | 
| 414 416 | 
             
                  end
         | 
| 415 417 |  | 
| 416 418 | 
             
                  # apply os specific patches
         | 
| @@ -0,0 +1,144 @@ | |
| 1 | 
            +
            module Appium
         | 
| 2 | 
            +
              module Ios
         | 
| 3 | 
            +
                module XcuitestGesture
         | 
| 4 | 
            +
                  # @param [string] direction Either 'up', 'down', 'left' or 'right'.
         | 
| 5 | 
            +
                  # @option opts [Element] :element Element to swipe on
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  #   ```ruby
         | 
| 8 | 
            +
                  #   swipe direction: "down"
         | 
| 9 | 
            +
                  #   ```
         | 
| 10 | 
            +
                  def swipe(direction:, element: nil)
         | 
| 11 | 
            +
                    return unless %w(up down left right).include?(direction)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    args = { direction: direction }
         | 
| 14 | 
            +
                    args[:element] = element.ref if element
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    execute_script 'mobile: swipe', args
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  # @param [string] direction Either 'up', 'down', 'left' or 'right'.
         | 
| 20 | 
            +
                  # @option opts [String] :name the accessibility id of the child element, to which scrolling is performed.
         | 
| 21 | 
            +
                  # @option opts [Element] :element Element id to long tap on.
         | 
| 22 | 
            +
                  # @option opts [bool] :to_visible Boolean parameter. If set to true then asks to scroll to the first visible
         | 
| 23 | 
            +
                  #   element in the parent container. Has no effect if element is not set
         | 
| 24 | 
            +
                  # @option opts [String] :predicate_string the NSPredicate locator of the child element,
         | 
| 25 | 
            +
                  #   to which the scrolling should be performed. Has no effect if element is not a container
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  #   ```ruby
         | 
| 28 | 
            +
                  #   scroll direction: "down"
         | 
| 29 | 
            +
                  #   ```
         | 
| 30 | 
            +
                  def scroll(direction:, name: nil, element: nil, to_visible: nil, predicate_string: nil)
         | 
| 31 | 
            +
                    return 'Set "up", "down", "left" or "right" for :direction' unless %w(up down left right).include?(direction)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    args =  { direction: direction }
         | 
| 34 | 
            +
                    args[:element] = element.ref if element
         | 
| 35 | 
            +
                    args[:name] = name if name
         | 
| 36 | 
            +
                    args[:toVisible] = to_visible if to_visible
         | 
| 37 | 
            +
                    args[:predicateString] = predicate_string if predicate_string
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    execute_script 'mobile: scroll', args
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  # @param scale [scale] X tap coordinate of type float. Mandatory parameter
         | 
| 43 | 
            +
                  # @param velocity [float] Y tap coordinate of type float. Mandatory parameter
         | 
| 44 | 
            +
                  # @option opts [Element] :element Element id to long tap on.
         | 
| 45 | 
            +
                  #
         | 
| 46 | 
            +
                  #   ```ruby
         | 
| 47 | 
            +
                  #   pinch scale: 0.5, velocity: -1
         | 
| 48 | 
            +
                  #   ```
         | 
| 49 | 
            +
                  def pinch(scale:, velocity: 1.0, element: nil)
         | 
| 50 | 
            +
                    return unless automation_name_is_xcuitest?
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    args = { scale: scale, velocity: velocity }
         | 
| 53 | 
            +
                    args[:element] = element.ref if element
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    execute_script 'mobile: pinch', args
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  # @param x [float] X Screen x tap coordinate of type float. Mandatory parameter only if element is not set
         | 
| 59 | 
            +
                  # @param y [float] Y Screen y tap coordinate of type float. Mandatory parameter only if element is not set
         | 
| 60 | 
            +
                  # @option opts [Element] :element Element to long tap on.
         | 
| 61 | 
            +
                  #
         | 
| 62 | 
            +
                  #   ```ruby
         | 
| 63 | 
            +
                  #   double_tap x: 100, y: 100
         | 
| 64 | 
            +
                  #   double_tap element: find_element(:accessibility_id, "some item")
         | 
| 65 | 
            +
                  #   ```
         | 
| 66 | 
            +
                  def double_tap(x: nil, y: nil, element: nil)
         | 
| 67 | 
            +
                    return 'require XCUITest(WDA)' unless automation_name_is_xcuitest?
         | 
| 68 | 
            +
                    return 'Set x, y or element' if (x.nil? || y.nil?) && element.nil?
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    args = element.nil? ? { x: x, y: y } : { element: element.ref }
         | 
| 71 | 
            +
                    execute_script 'mobile: doubleTap', args
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  # @param [Element] :element Element to long tap on.
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  #   ```ruby
         | 
| 77 | 
            +
                  #   two_finger_tap element: find_element(:accessibility_id, "some item")
         | 
| 78 | 
            +
                  #   ```
         | 
| 79 | 
            +
                  def two_finger_tap(element:)
         | 
| 80 | 
            +
                    return 'require XCUITest(WDA)' unless automation_name_is_xcuitest?
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    args = { element: element.ref }
         | 
| 83 | 
            +
                    execute_script 'mobile: twoFingerTap', args
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  # @param x [float] X tap coordinate of type float. Mandatory parameter
         | 
| 87 | 
            +
                  # @param y [float] Y tap coordinate of type float. Mandatory parameter
         | 
| 88 | 
            +
                  # @option opts [Element] :element Element id to long tap on. x and y tap coordinates will be calculated
         | 
| 89 | 
            +
                  #   relatively to the current element position on the screen if this argument is provided.
         | 
| 90 | 
            +
                  #   Otherwise they should be calculated relatively to screen borders.
         | 
| 91 | 
            +
                  #
         | 
| 92 | 
            +
                  #   ```ruby
         | 
| 93 | 
            +
                  #   tap x: 100, y: 100
         | 
| 94 | 
            +
                  #   tap x: 100, y: 100, element: find_element(:accessibility_id, "some item")
         | 
| 95 | 
            +
                  #   ```
         | 
| 96 | 
            +
                  def tap(x:, y:, element: nil)
         | 
| 97 | 
            +
                    return 'require XCUITest(WDA)' unless automation_name_is_xcuitest?
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    args = { x: x, y: y }
         | 
| 100 | 
            +
                    args[:element] = element.ref
         | 
| 101 | 
            +
                    execute_script 'mobile: tap', args
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  # rubocop:disable Metrics/ParameterLists
         | 
| 105 | 
            +
                  # @param duration [float] Float number of seconds in range [0.5, 60]. How long the tap gesture at starting
         | 
| 106 | 
            +
                  #   drag point should be before to start dragging. Mandatory parameter
         | 
| 107 | 
            +
                  # @param from_x [float] The x coordinate of starting drag point (type float). Mandatory parameter
         | 
| 108 | 
            +
                  # @param from_y [float] The y coordinate of starting drag point (type float). Mandatory parameter
         | 
| 109 | 
            +
                  # @param to_x [float] The x coordinate of ending drag point (type float). Mandatory parameter
         | 
| 110 | 
            +
                  # @param to_y [float] The y coordinate of ending drag point (type float). Mandatory parameter
         | 
| 111 | 
            +
                  # @option opts [Element] :element  Element id to perform drag on. All the coordinates will be calculated
         | 
| 112 | 
            +
                  #   relatively this this element position on the screen. Absolute screen coordinates are expected
         | 
| 113 | 
            +
                  #   if this argument is not set
         | 
| 114 | 
            +
                  #
         | 
| 115 | 
            +
                  #   ```ruby
         | 
| 116 | 
            +
                  #   drag_from_to_for_duration from_x: 100, from_y: 100, to_x: 150, to_y: 150
         | 
| 117 | 
            +
                  #   ```
         | 
| 118 | 
            +
                  def drag_from_to_for_duration(from_x:, from_y:, to_x:, to_y:, duration: 1.0, element: nil)
         | 
| 119 | 
            +
                    return 'require XCUITest(WDA)' unless automation_name_is_xcuitest?
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                    args = { from_x: from_x, from_y: from_y, to_x: to_x, to_y: to_y, duration: duration }
         | 
| 122 | 
            +
                    args[:element] = element if element
         | 
| 123 | 
            +
                    execute_script 'mobile: dragFromToForDuration', args
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                  # rubocop:enable Metrics/ParameterLists
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  # https://github.com/facebook/WebDriverAgent/pull/523
         | 
| 128 | 
            +
                  # https://github.com/appium/appium-xcuitest-driver/pull/420
         | 
| 129 | 
            +
                  # @param order [String] The order to move picker to. "next" or "previous".
         | 
| 130 | 
            +
                  # @param element [Element]  Element id to perform select picker wheel on.
         | 
| 131 | 
            +
                  #
         | 
| 132 | 
            +
                  #   ```ruby
         | 
| 133 | 
            +
                  #   select_picker_wheel order: "next", element: find_element(:accessibility_id, "some picker")
         | 
| 134 | 
            +
                  #   ```
         | 
| 135 | 
            +
                  def select_picker_wheel(element:, order:)
         | 
| 136 | 
            +
                    return 'require XCUITest(WDA)' unless automation_name_is_xcuitest?
         | 
| 137 | 
            +
                    return 'Set "next" or "previous" for :order' unless %w(next previous).include?(order)
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    args = { element: element.ref, order: order }
         | 
| 140 | 
            +
                    execute_script 'mobile: selectPickerWheelValue', args
         | 
| 141 | 
            +
                  end
         | 
| 142 | 
            +
                end # module XcuitestGesture
         | 
| 143 | 
            +
              end # module Ios
         | 
| 144 | 
            +
            end # module Appium
         | 
    
        data/release_notes.md
    CHANGED
    
    | @@ -1,3 +1,10 @@ | |
| 1 | 
            +
            #### v9.3.8 2017-04-13
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - [7a7cf44](https://github.com/appium/ruby_lib/commit/7a7cf44c3cb11a90142285b8e8d731dc452b89eb) Release 9 3 8 (#540)
         | 
| 4 | 
            +
            - [5e67b88](https://github.com/appium/ruby_lib/commit/5e67b8813950148661bc4491811a696edeffc63c) allow using TestObject server (#538)
         | 
| 5 | 
            +
            - [9fdf89f](https://github.com/appium/ruby_lib/commit/9fdf89f9c3993730aabf1b8e25f03a773e565d98) add link to mobile gesture for XCUITets (#536)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
             | 
| 1 8 | 
             
            #### v9.3.7 2017-04-09
         | 
| 2 9 |  | 
| 3 10 | 
             
            - [8daf6f7](https://github.com/appium/ruby_lib/commit/8daf6f773c9b8acd7a89e2a9225fd834de5b4e2e) Release 9 3 7 (#535)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: appium_lib
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 9. | 
| 4 | 
            +
              version: 9.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - code@bootstraponline.com
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017-04- | 
| 11 | 
            +
            date: 2017-04-17 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: selenium-webdriver
         | 
| @@ -333,6 +333,7 @@ files: | |
| 333 333 | 
             
            - ios_tests/lib/ios/specs/ios/helper.rb
         | 
| 334 334 | 
             
            - ios_tests/lib/ios/specs/ios/mobile_methods.rb
         | 
| 335 335 | 
             
            - ios_tests/lib/ios/specs/ios/patch.rb
         | 
| 336 | 
            +
            - ios_tests/lib/ios/specs/ios/xcuitest_gestures.rb
         | 
| 336 337 | 
             
            - ios_tests/lib/run.rb
         | 
| 337 338 | 
             
            - ios_tests/readme.md
         | 
| 338 339 | 
             
            - ios_tests/upload/sauce_storage.rb
         | 
| @@ -368,6 +369,7 @@ files: | |
| 368 369 | 
             
            - lib/appium_lib/ios/helper.rb
         | 
| 369 370 | 
             
            - lib/appium_lib/ios/mobile_methods.rb
         | 
| 370 371 | 
             
            - lib/appium_lib/ios/patch.rb
         | 
| 372 | 
            +
            - lib/appium_lib/ios/xcuitest_gestures.rb
         | 
| 371 373 | 
             
            - lib/appium_lib/logger.rb
         | 
| 372 374 | 
             
            - lib/appium_lib/rails/duplicable.rb
         | 
| 373 375 | 
             
            - readme.md
         |