calabash-cucumber 0.10.0.pre1 → 0.10.0.pre2
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/features/step_definitions/calabash_steps.rb +1 -1
- data/lib/calabash-cucumber/actions/instruments_actions.rb +15 -4
- data/lib/calabash-cucumber/actions/playback_actions.rb +12 -3
- data/lib/calabash-cucumber/connection.rb +3 -0
- data/lib/calabash-cucumber/connection_helpers.rb +4 -0
- data/lib/calabash-cucumber/core.rb +637 -83
- data/lib/calabash-cucumber/date_picker.rb +148 -29
- data/lib/calabash-cucumber/device.rb +160 -3
- data/lib/calabash-cucumber/environment_helpers.rb +91 -46
- data/lib/calabash-cucumber/failure_helpers.rb +40 -0
- data/lib/calabash-cucumber/http_helpers.rb +9 -2
- data/lib/calabash-cucumber/ibase.rb +136 -17
- data/lib/calabash-cucumber/ios7_operations.rb +13 -9
- data/lib/calabash-cucumber/ipad_1x_2x.rb +103 -48
- data/lib/calabash-cucumber/keyboard_helpers.rb +253 -144
- data/lib/calabash-cucumber/keychain_helpers.rb +46 -32
- data/lib/calabash-cucumber/launch/simulator_helper.rb +13 -12
- data/lib/calabash-cucumber/launch/simulator_launcher.rb +111 -78
- data/lib/calabash-cucumber/launcher.rb +265 -25
- data/lib/calabash-cucumber/map.rb +24 -22
- data/lib/calabash-cucumber/operations.rb +4 -160
- data/lib/calabash-cucumber/playback_helpers.rb +26 -0
- data/lib/calabash-cucumber/query_helpers.rb +12 -0
- data/lib/calabash-cucumber/rotation_helpers.rb +64 -8
- data/lib/calabash-cucumber/status_bar_helpers.rb +40 -3
- data/lib/calabash-cucumber/tests_helpers.rb +43 -14
- data/lib/calabash-cucumber/uia.rb +93 -9
- data/lib/calabash-cucumber/utils/logging.rb +30 -16
- data/lib/calabash-cucumber/utils/plist_buddy.rb +18 -19
- data/lib/calabash-cucumber/utils/simulator_accessibility.rb +41 -30
- data/lib/calabash-cucumber/utils/xctools.rb +31 -21
- data/lib/calabash-cucumber/version.rb +98 -2
- data/lib/calabash-cucumber/wait_helpers.rb +257 -77
- data/staticlib/calabash.framework.zip +0 -0
- metadata +64 -231
- data/.gitignore +0 -17
- data/CHANGES.txt +0 -1
- data/Gemfile +0 -4
- data/Rakefile +0 -72
- data/calabash-cucumber.gemspec +0 -36
- data/epl-v10.html +0 -261
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +0 -51
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +0 -51
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +0 -74
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +0 -74
- data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +0 -15
- data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +0 -15
- data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +0 -22
- data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +0 -22
- data/lib/calabash-cucumber/resources/pan_ios5_ipad.base64 +0 -199
- data/lib/calabash-cucumber/resources/pan_ios5_iphone.base64 +0 -199
- data/lib/calabash-cucumber/resources/pan_ios6_ipad.base64 +0 -206
- data/lib/calabash-cucumber/resources/pan_ios6_iphone.base64 +0 -206
- data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +0 -104
- data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +0 -104
- data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +0 -144
- data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +0 -144
- data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +0 -70
- data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +0 -70
- data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +0 -207
- data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +0 -207
- data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +0 -96
- data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +0 -96
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +0 -31
- data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +0 -15
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +0 -15
- data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +0 -34
- data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +0 -13
- data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +0 -13
- data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +0 -34
- data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +0 -7
- data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +0 -7
- data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios7_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios7_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +0 -159
- data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +0 -159
- data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +0 -166
- data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +0 -166
- data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +0 -156
- data/scripts/EmptyAppHack.app/Default-568h@2x.png +0 -0
- data/scripts/EmptyAppHack.app/Default.png +0 -0
- data/scripts/EmptyAppHack.app/Default@2x.png +0 -0
- data/scripts/EmptyAppHack.app/EmptyAppHack +0 -0
- data/scripts/EmptyAppHack.app/Info.plist +0 -0
- data/scripts/EmptyAppHack.app/PkgInfo +0 -1
- data/scripts/EmptyAppHack.app/en.lproj/InfoPlist.strings +0 -0
- data/scripts/com.example.plist +0 -0
- data/scripts/data/.GlobalPreferences.plist +0 -0
- data/scripts/reset_simulator.scpt +0 -0
- data/spec/bin/calabash_ios_sim_spec.rb +0 -24
- data/spec/launcher_spec.rb +0 -166
- data/spec/logging_spec.rb +0 -38
- data/spec/plist_buddy_spec.rb +0 -99
- data/spec/resources/enable-accessibility/6.1/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.0.3-64/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.0.3/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.1-64/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.1/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Default-568h@2x.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Info.plist +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/LPSimpleExample-cal +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/PkgInfo +0 -1
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/InfoPlist.strings +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first@2x.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second@2x.png +0 -0
- data/spec/resources/plist_buddy/com.example.plist +0 -0
- data/spec/resources/plist_buddy/com.testing.plist +0 -18
- data/spec/simulator_accessibility_spec.rb +0 -206
- data/spec/spec_helper.rb +0 -31
- data/spec/version_spec.rb +0 -13
- data/spec/xctools_spec.rb +0 -58
| @@ -2,10 +2,32 @@ require 'calabash-cucumber/utils/logging' | |
| 2 2 |  | 
| 3 3 | 
             
            module Calabash
         | 
| 4 4 | 
             
              module Cucumber
         | 
| 5 | 
            -
             | 
| 5 | 
            +
             | 
| 6 | 
            +
                # Contains methods for interacting with the status bar.
         | 
| 7 | 
            +
                module StatusBarHelpers
         | 
| 6 8 |  | 
| 7 9 | 
             
                  include Calabash::Cucumber::Logging
         | 
| 8 10 |  | 
| 11 | 
            +
                  # Returns the device orientation as reported by `[[UIDevice currentDevice] orientation]`.
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  # @note This method is not used internally by the gem.  It is provided
         | 
| 14 | 
            +
                  #  as an alternative to `status_bar_orientation`.  We recommend that you
         | 
| 15 | 
            +
                  #  use `status_bar_orientation` whenever possible.
         | 
| 16 | 
            +
                  #
         | 
| 17 | 
            +
                  # @note Devices that are lying on a flat surface will report their
         | 
| 18 | 
            +
                  #  orientation as 'face up' or 'face down'.  In order to translate
         | 
| 19 | 
            +
                  #  gestures based on orientation, Calabash must have left, right, up, or
         | 
| 20 | 
            +
                  #  down orientation. To that end, if a device is lying flat, this method
         | 
| 21 | 
            +
                  #  will ***force*** a down orientation.  This will happen regardless of
         | 
| 22 | 
            +
                  #  the value of the `force_down` optional argument.
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  # @see #status_bar_orientation
         | 
| 25 | 
            +
                  # @see Calabash::Cucumber::RotationHelpers#rotate_home_button_to
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  # @param [Boolean] force_down if true, do rotations until a down
         | 
| 28 | 
            +
                  #  orientation is achieved
         | 
| 29 | 
            +
                  # @return [Symbol] Returns the device orientation as one of
         | 
| 30 | 
            +
                  #  `{:down, :up, :left, :right}`.
         | 
| 9 31 | 
             
                  def device_orientation(force_down=false)
         | 
| 10 32 | 
             
                    res = map(nil, :orientation, :device).first
         | 
| 11 33 |  | 
| @@ -25,17 +47,32 @@ module Calabash | |
| 25 47 | 
             
                    rotate_home_button_to(:down)
         | 
| 26 48 | 
             
                  end
         | 
| 27 49 |  | 
| 50 | 
            +
                  # Returns the home button position relative to the status bar.
         | 
| 51 | 
            +
                  #
         | 
| 52 | 
            +
                  # @note You should always prefer to use this method over
         | 
| 53 | 
            +
                  #  `device_orientation`.
         | 
| 54 | 
            +
                  #
         | 
| 55 | 
            +
                  # @note This method works even if a status bar is not visible.
         | 
| 56 | 
            +
                  #
         | 
| 57 | 
            +
                  # @return [String] Returns the device orientation as one of
         | 
| 58 | 
            +
                  #  `{'down' | 'up' | 'left' | 'right'}`.
         | 
| 28 59 | 
             
                  def status_bar_orientation
         | 
| 29 60 | 
             
                    map(nil, :orientation, :status_bar).first
         | 
| 30 61 | 
             
                  end
         | 
| 31 62 |  | 
| 32 | 
            -
                  #  | 
| 63 | 
            +
                  # Is the device in the portrait orientation?
         | 
| 64 | 
            +
                  #
         | 
| 65 | 
            +
                  # @return [Boolean] Returns true if the device is in the 'up' or 'down'
         | 
| 66 | 
            +
                  #  orientation.
         | 
| 33 67 | 
             
                  def portrait?
         | 
| 34 68 | 
             
                    o = status_bar_orientation
         | 
| 35 69 | 
             
                    o.eql?('up') or o.eql?('down')
         | 
| 36 70 | 
             
                  end
         | 
| 37 71 |  | 
| 38 | 
            -
                  #  | 
| 72 | 
            +
                  # Is the device in the landscape orientation?
         | 
| 73 | 
            +
                  #
         | 
| 74 | 
            +
                  # @return [Boolean] Returns true if the device is in the 'left' or 'right'
         | 
| 75 | 
            +
                  #  orientation.
         | 
| 39 76 | 
             
                  def landscape?
         | 
| 40 77 | 
             
                    o = status_bar_orientation
         | 
| 41 78 | 
             
                    o.eql?('right') or o.eql?('left')
         | 
| @@ -2,55 +2,78 @@ require 'calabash-cucumber/failure_helpers' | |
| 2 2 |  | 
| 3 3 | 
             
            module Calabash
         | 
| 4 4 | 
             
              module Cucumber
         | 
| 5 | 
            -
                module TestsHelpers #=> http
         | 
| 6 | 
            -
                  include Calabash::Cucumber::FailureHelpers
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                  def navigation_path(*args)
         | 
| 9 5 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
                    #    [""],
         | 
| 13 | 
            -
                    #)
         | 
| 6 | 
            +
                # A collection of methods to help you write tests.
         | 
| 7 | 
            +
                module TestsHelpers
         | 
| 14 8 |  | 
| 9 | 
            +
                  include Calabash::Cucumber::FailureHelpers
         | 
| 15 10 |  | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
             | 
| 11 | 
            +
                  # Returns the classes of all views matching `uiquery`
         | 
| 12 | 
            +
                  # @param {String} uiquery the query to execute
         | 
| 13 | 
            +
                  # @param {Array} args optional args to pass to `query`.
         | 
| 14 | 
            +
                  # @return {Array<String>} class names of views matching `uiquery`
         | 
| 22 15 | 
             
                  def classes(uiquery,*args)
         | 
| 23 16 | 
             
                    query_map(uiquery,:class,*args)
         | 
| 24 17 | 
             
                  end
         | 
| 25 18 |  | 
| 19 | 
            +
                  # Returns true if no element matches query `uiquery`.
         | 
| 20 | 
            +
                  # @param {String} uiquery the query to execute
         | 
| 21 | 
            +
                  # @return {Boolean} `true` if no element matches query `uiquery`. `false` otherwise.
         | 
| 26 22 | 
             
                  def element_does_not_exist(uiquery)
         | 
| 27 23 | 
             
                    query(uiquery).empty?
         | 
| 28 24 | 
             
                  end
         | 
| 29 25 |  | 
| 26 | 
            +
                  # Returns true if at least one element matches query `uiquery`.
         | 
| 27 | 
            +
                  # @param {String} uiquery the query to execute
         | 
| 28 | 
            +
                  # @return {Boolean} `true` if at least one element matches query `uiquery`. `false` otherwise.
         | 
| 30 29 | 
             
                  def element_exists(uiquery)
         | 
| 31 30 | 
             
                    not element_does_not_exist(uiquery)
         | 
| 32 31 | 
             
                  end
         | 
| 33 32 |  | 
| 33 | 
            +
                  # Returns true if at least one element matches query `"* marked:'#{expected_mark}'"`
         | 
| 34 | 
            +
                  # @param {String} expected_mark the mark to search for
         | 
| 35 | 
            +
                  # @return {Boolean} `true` if at least one element matches query
         | 
| 36 | 
            +
                  #  `"* marked:'#{expected_mark}'". `false` otherwise.
         | 
| 34 37 | 
             
                  def view_with_mark_exists(expected_mark)
         | 
| 35 38 | 
             
                    element_exists("view marked:'#{expected_mark}'")
         | 
| 36 39 | 
             
                  end
         | 
| 37 40 |  | 
| 41 | 
            +
                  # raises a Runtime error (and generates a screenshot) unless at least one element matches query `query`.
         | 
| 42 | 
            +
                  # @param {String} query the query to execute
         | 
| 43 | 
            +
                  # @return {nil} Returns nil if there is a match.
         | 
| 44 | 
            +
                  # @raise [RuntimeError] if no element matches `query`.
         | 
| 38 45 | 
             
                  def check_element_exists(query)
         | 
| 39 46 | 
             
                    if not element_exists(query)
         | 
| 40 47 | 
             
                      screenshot_and_raise "No element found for query: #{query}"
         | 
| 41 48 | 
             
                    end
         | 
| 42 49 | 
             
                  end
         | 
| 43 50 |  | 
| 51 | 
            +
                  # raises a Runtime error (and generates a screenshot) if at least one element matches query `query`.
         | 
| 52 | 
            +
                  # @param {String} query the query to execute
         | 
| 53 | 
            +
                  # @return {nil} Returns nil if there is no match.
         | 
| 54 | 
            +
                  # @raise [RuntimeError] if an element matches `query`.
         | 
| 44 55 | 
             
                  def check_element_does_not_exist(query)
         | 
| 45 56 | 
             
                    if element_exists(query)
         | 
| 46 57 | 
             
                      screenshot_and_raise "Expected no elements to match query: #{query}"
         | 
| 47 58 | 
             
                    end
         | 
| 48 59 | 
             
                  end
         | 
| 49 60 |  | 
| 61 | 
            +
                  # raises a Runtime error (and generates a screenshot) unless at least one element matches mark `expected_mark`.
         | 
| 62 | 
            +
                  # @param {String} expected_mark the mark to check for.
         | 
| 63 | 
            +
                  # @return {nil} Returns nil if there is a match.
         | 
| 64 | 
            +
                  # @raise [RuntimeError] if no element matches `view marked:'#{expected_mark}'`.
         | 
| 50 65 | 
             
                  def check_view_with_mark_exists(expected_mark)
         | 
| 51 66 | 
             
                    check_element_exists("view marked:'#{expected_mark}'")
         | 
| 52 67 | 
             
                  end
         | 
| 53 68 |  | 
| 69 | 
            +
                  # Calls given block with each row and section (`yield(row, sec)`). Alternates between scrolling to each cell and
         | 
| 70 | 
            +
                  # yielding.
         | 
| 71 | 
            +
                  #
         | 
| 72 | 
            +
                  # @param {Hash} opts specifies details of the scroll
         | 
| 73 | 
            +
                  # @option opts {String} :query ('tableView') query specifying which table view to use
         | 
| 74 | 
            +
                  # @option opts {Numeric} :post_scroll (0.3) wait to be done after each scroll
         | 
| 75 | 
            +
                  # @option opts {Boolean} :animated (true) animate or not
         | 
| 76 | 
            +
                  #
         | 
| 54 77 | 
             
                  def each_cell(opts={:query => "tableView", :post_scroll => 0.3, :animate => true}, &block)
         | 
| 55 78 | 
             
                    uiquery = opts[:query] || "tableView"
         | 
| 56 79 | 
             
                    skip = opts[:skip_if]
         | 
| @@ -68,6 +91,7 @@ module Calabash | |
| 68 91 | 
             
                    end
         | 
| 69 92 | 
             
                  end
         | 
| 70 93 |  | 
| 94 | 
            +
                  # @!visibility private
         | 
| 71 95 | 
             
                  def each_cell_and_back(opts={:query => "tableView",
         | 
| 72 96 | 
             
                                               :post_scroll => 0.3,
         | 
| 73 97 | 
             
                                               :post_back => 0.5,
         | 
| @@ -92,6 +116,11 @@ module Calabash | |
| 92 116 | 
             
                    end
         | 
| 93 117 | 
             
                  end
         | 
| 94 118 |  | 
| 119 | 
            +
                  # @!visibility private
         | 
| 120 | 
            +
                  def query_map(uiquery,prop, *args)
         | 
| 121 | 
            +
                    query(uiquery,*args).map {|o| o[prop.to_s]}
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
             | 
| 95 124 | 
             
                end
         | 
| 96 125 | 
             
              end
         | 
| 97 126 | 
             
            end
         | 
| @@ -6,10 +6,16 @@ require 'calabash-cucumber/utils/logging' | |
| 6 6 |  | 
| 7 7 | 
             
            module Calabash
         | 
| 8 8 | 
             
              module Cucumber
         | 
| 9 | 
            +
                # Low-level module for interacting directly with UIA
         | 
| 10 | 
            +
                # See also {https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAElementClassReference/UIAElement/UIAElement.html}
         | 
| 11 | 
            +
                # Typically used to interact with System or remote views.
         | 
| 9 12 | 
             
                module UIA
         | 
| 10 13 |  | 
| 11 14 | 
             
                  include Calabash::Cucumber::Logging
         | 
| 12 15 |  | 
| 16 | 
            +
                  # executes raw JavaScript in the UIAutomation environment (using `eval`).
         | 
| 17 | 
            +
                  # @param {String} command the JavaScript snipplet to execute
         | 
| 18 | 
            +
                  # @return {Object} the result returned by the UIA process
         | 
| 13 19 | 
             
                  def uia(command,options={})
         | 
| 14 20 | 
             
                    res = http({:method => :post, :path => 'uia'}, {:command => command}.merge(options))
         | 
| 15 21 | 
             
                    res = JSON.parse(res)
         | 
| @@ -19,119 +25,195 @@ module Calabash | |
| 19 25 | 
             
                    res['results'].first
         | 
| 20 26 | 
             
                  end
         | 
| 21 27 |  | 
| 28 | 
            +
                  # @!visibility private
         | 
| 22 29 | 
             
                  def uia_wait_tap(query, options={})
         | 
| 23 30 | 
             
                    res = http({:method => :post, :path => 'uia-tap'}, {:query => query}.merge(options))
         | 
| 24 31 | 
             
                    res = JSON.parse(res)
         | 
| 25 32 | 
             
                    if res['outcome'] != 'SUCCESS'
         | 
| 26 33 | 
             
                      raise "uia-tap action failed because: #{res['reason']}\n#{res['details']}"
         | 
| 27 34 | 
             
                    end
         | 
| 28 | 
            -
                    res['results'] | 
| 35 | 
            +
                    res['results']
         | 
| 29 36 | 
             
                  end
         | 
| 30 37 |  | 
| 38 | 
            +
                  # Invoke a Calabash query inside the UIAutomation Calabash engine
         | 
| 39 | 
            +
                  # Note that this traverses the UIA (accessibility) hierarchy.
         | 
| 40 | 
            +
                  # @example uia query equivalent of "button marked:'Hello'"
         | 
| 41 | 
            +
                  #   uia_query :button, marked:'Hello'
         | 
| 42 | 
            +
                  # @param {Array} queryparts array of segments in the query, e.g., `:button, {marked:'Hello'}`
         | 
| 43 | 
            +
                  # @return {Array<Hash>} UIAElements matching the query in serialized form.
         | 
| 31 44 | 
             
                  def uia_query(*queryparts)
         | 
| 32 45 | 
             
                    #TODO escape '\n etc in query
         | 
| 33 46 | 
             
                    uia_handle_command(:query, queryparts)
         | 
| 34 47 | 
             
                  end
         | 
| 35 48 |  | 
| 49 | 
            +
                  # @!visibility private
         | 
| 36 50 | 
             
                  def uia_query_el(*queryparts)
         | 
| 37 51 | 
             
                    #TODO escape '\n etc in query
         | 
| 38 52 | 
             
                    uia_handle_command(:queryEl, queryparts)
         | 
| 39 53 | 
             
                  end
         | 
| 40 54 |  | 
| 55 | 
            +
                  # Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows.
         | 
| 56 | 
            +
                  # Note that this traverses the UIA (accessibility) hierarchy.
         | 
| 57 | 
            +
                  # @example uia query equivalent of "button marked:'Hello'"
         | 
| 58 | 
            +
                  #   uia_query_windows :button
         | 
| 59 | 
            +
                  # @param {Array} queryparts array of segments in the query, e.g., `:button, {marked:'Hello'}`
         | 
| 60 | 
            +
                  # @return {Array<Hash>} UIAElements matching the query in serialized form.
         | 
| 41 61 | 
             
                  def uia_query_windows(*queryparts)
         | 
| 42 62 | 
             
                    #TODO escape '\n etc in query
         | 
| 43 63 | 
             
                    uia_handle_command(:queryWindows, queryparts)
         | 
| 44 64 | 
             
                  end
         | 
| 45 65 |  | 
| 66 | 
            +
                  # Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows.
         | 
| 67 | 
            +
                  # Note that this traverses the UIA (accessibility) hierarchy.
         | 
| 68 | 
            +
                  # @example uia equivalent of `identifier "button"`
         | 
| 69 | 
            +
                  #   uia_names :button
         | 
| 70 | 
            +
                  #   # returns
         | 
| 71 | 
            +
                  #   [
         | 
| 72 | 
            +
                  #     "Browse",
         | 
| 73 | 
            +
                  #     "UINavigationBarBackIndicatorDefault.png",
         | 
| 74 | 
            +
                  #     "16h",
         | 
| 75 | 
            +
                  #     "reader postaction comment blue",
         | 
| 76 | 
            +
                  #     "16h",
         | 
| 77 | 
            +
                  #     "52",
         | 
| 78 | 
            +
                  #     "17h",
         | 
| 79 | 
            +
                  #     "10",
         | 
| 80 | 
            +
                  #     "Reader",
         | 
| 81 | 
            +
                  #     "Notifications",
         | 
| 82 | 
            +
                  #     "Me",
         | 
| 83 | 
            +
                  #     "New Post"
         | 
| 84 | 
            +
                  #   ]
         | 
| 85 | 
            +
                  # @param {Array} queryparts array of segments in the query, e.g., `:button, {marked:'Hello'}`
         | 
| 86 | 
            +
                  # @return {Array<String>} "names" (accessibilityIdentifier) of UIAElements matching the query.
         | 
| 46 87 | 
             
                  def uia_names(*queryparts)
         | 
| 47 88 | 
             
                    #TODO escape '\n etc in query
         | 
| 48 89 | 
             
                    uia_handle_command(:names, queryparts)
         | 
| 49 90 | 
             
                  end
         | 
| 50 91 |  | 
| 92 | 
            +
                  # Advanced method used to invoke UIAutomation JavaScript methods on objects found via Calabash queries
         | 
| 93 | 
            +
                  # @see #uia_query
         | 
| 94 | 
            +
                  # @example Calling UIAButton.isVisible() - {https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAElementClassReference/UIAElement/UIAElement.html}
         | 
| 95 | 
            +
                  #   uia_call [:button, {marked:'New Post'}], :isVisible
         | 
| 96 | 
            +
                  # @example Advanced example that chains calls and uses arguments
         | 
| 97 | 
            +
                  #   uia_call [:view, marked:'New Post'], {withName:"New Post"}, :toString, {charAt:0}
         | 
| 98 | 
            +
                  #
         | 
| 99 | 
            +
                  # @param {Array} args_arr array describing the query, e.g., `[:button, {marked:'foo'}]`
         | 
| 100 | 
            +
                  # @param {Array} opts optional arguments specifying a chained sequence of method calls (see example)
         | 
| 101 | 
            +
                  def uia_call(args_arr, *opts)
         | 
| 102 | 
            +
                    uia_call_method(:queryEl, args_arr, *opts)
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  # Similar to `uia_call` but searches all windows
         | 
| 106 | 
            +
                  # @see #uia_call
         | 
| 107 | 
            +
                  def uia_call_windows(args_arr, *opts)
         | 
| 108 | 
            +
                    uia_call_method(:queryElWindows, args_arr, *opts)
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  # @!visibility private
         | 
| 51 112 | 
             
                  def uia_tap(*queryparts)
         | 
| 52 113 | 
             
                    uia_handle_command(:tap, queryparts)
         | 
| 53 114 | 
             
                  end
         | 
| 54 115 |  | 
| 116 | 
            +
                  # @!visibility private
         | 
| 55 117 | 
             
                  def uia_tap_mark(mark)
         | 
| 56 118 | 
             
                    uia_handle_command(:tapMark, mark)
         | 
| 57 119 | 
             
                  end
         | 
| 58 120 |  | 
| 121 | 
            +
                  # @!visibility private
         | 
| 59 122 | 
             
                  def uia_tap_offset(offset)
         | 
| 60 123 | 
             
                    uia_handle_command(:tapOffset, offset)
         | 
| 61 124 | 
             
                  end
         | 
| 62 125 |  | 
| 126 | 
            +
                  # @!visibility private
         | 
| 63 127 | 
             
                  def uia_double_tap(*queryparts)
         | 
| 64 128 | 
             
                    uia_handle_command(:doubleTap, queryparts)
         | 
| 65 129 | 
             
                  end
         | 
| 66 130 |  | 
| 131 | 
            +
                  # @!visibility private
         | 
| 67 132 | 
             
                  def uia_double_tap_mark(mark)
         | 
| 68 133 | 
             
                    uia_double_tap(:view, {:marked => mark})
         | 
| 69 134 | 
             
                  end
         | 
| 70 135 |  | 
| 136 | 
            +
                  # @!visibility private
         | 
| 71 137 | 
             
                  def uia_double_tap_offset(offset)
         | 
| 72 138 | 
             
                    uia_handle_command(:doubleTapOffset, offset)
         | 
| 73 139 | 
             
                  end
         | 
| 74 140 |  | 
| 141 | 
            +
                  # @!visibility private
         | 
| 75 142 | 
             
                  def uia_two_finger_tap(*queryparts)
         | 
| 76 143 | 
             
                    uia_handle_command(:twoFingerTap, queryparts)
         | 
| 77 144 | 
             
                  end
         | 
| 78 145 |  | 
| 146 | 
            +
                  # @!visibility private
         | 
| 79 147 | 
             
                  def uia_two_finger_tap_offset(offset)
         | 
| 80 148 | 
             
                    uia_handle_command(:twoFingerTapOffset, offset)
         | 
| 81 149 | 
             
                  end
         | 
| 82 150 |  | 
| 151 | 
            +
                  # @!visibility private
         | 
| 83 152 | 
             
                  def uia_flick_offset(from, to)
         | 
| 84 153 | 
             
                    uia_handle_command(:flickOffset, from, to)
         | 
| 85 154 | 
             
                  end
         | 
| 86 155 |  | 
| 156 | 
            +
                  # @!visibility private
         | 
| 87 157 | 
             
                  def uia_touch_hold(duration, *queryparts)
         | 
| 88 158 | 
             
                    uia_handle_command(:touchHold, duration, queryparts)
         | 
| 89 159 | 
             
                  end
         | 
| 90 160 |  | 
| 161 | 
            +
                  # @!visibility private
         | 
| 91 162 | 
             
                  def uia_touch_hold_offset(duration, offset)
         | 
| 92 163 | 
             
                    uia_handle_command(:touchHoldOffset, duration, offset)
         | 
| 93 164 | 
             
                  end
         | 
| 94 165 |  | 
| 166 | 
            +
                  # @!visibility private
         | 
| 95 167 | 
             
                  def uia_pan(from_q, to_q)
         | 
| 96 168 | 
             
                    uia_handle_command(:pan, from_q, to_q)
         | 
| 97 169 | 
             
                  end
         | 
| 98 170 |  | 
| 171 | 
            +
                  # @!visibility private
         | 
| 99 172 | 
             
                  def uia_pan_offset(from, to, options)
         | 
| 100 173 | 
             
                    uia_handle_command(:panOffset, from, to, options)
         | 
| 101 174 | 
             
                  end
         | 
| 102 175 |  | 
| 176 | 
            +
                  # @!visibility private
         | 
| 103 177 | 
             
                  def uia_swipe(*queryparts)
         | 
| 104 178 | 
             
                    uia_handle_command(:swipe, queryparts)
         | 
| 105 179 | 
             
                  end
         | 
| 106 180 |  | 
| 181 | 
            +
                  # @!visibility private
         | 
| 107 182 | 
             
                  def uia_swipe_offset(offset, options)
         | 
| 108 183 | 
             
                    uia_handle_command(:swipeOffset, offset, options)
         | 
| 109 184 | 
             
                  end
         | 
| 110 185 |  | 
| 186 | 
            +
                  # @!visibility private
         | 
| 111 187 | 
             
                  def uia_pinch(*queryparts)
         | 
| 112 188 | 
             
                    uia_handle_command(:pinch, queryparts)
         | 
| 113 189 | 
             
                  end
         | 
| 114 190 |  | 
| 191 | 
            +
                  # @!visibility private
         | 
| 115 192 | 
             
                  def uia_pinch_offset(in_or_out, offset, duration)
         | 
| 116 193 | 
             
                    uia_handle_command(:pinchOffset, in_or_out, offset, duration)
         | 
| 117 194 | 
             
                  end
         | 
| 118 195 |  | 
| 196 | 
            +
                  # @!visibility private
         | 
| 119 197 | 
             
                  def uia_scroll_to(*queryparts)
         | 
| 120 198 | 
             
                    uia_handle_command(:scrollTo, queryparts)
         | 
| 121 199 | 
             
                  end
         | 
| 122 200 |  | 
| 201 | 
            +
                  # @!visibility private
         | 
| 123 202 | 
             
                  def uia_element_exists?(*queryparts)
         | 
| 124 203 | 
             
                    uia_handle_command(:elementExists, queryparts)
         | 
| 125 204 | 
             
                  end
         | 
| 126 205 |  | 
| 206 | 
            +
                  # @!visibility private
         | 
| 127 207 | 
             
                  def uia_element_does_not_exist?(*queryparts)
         | 
| 128 208 | 
             
                    uia_handle_command(:elementDoesNotExist, queryparts)
         | 
| 129 209 | 
             
                  end
         | 
| 130 210 |  | 
| 211 | 
            +
                  # @!visibility private
         | 
| 131 212 | 
             
                  def uia_screenshot(name)
         | 
| 132 213 | 
             
                    uia_handle_command(:screenshot, name)
         | 
| 133 214 | 
             
                  end
         | 
| 134 215 |  | 
| 216 | 
            +
                  # @!visibility private
         | 
| 135 217 | 
             
                  def uia_type_string(string, opt_text_before='', escape=true)
         | 
| 136 218 | 
             
                    if escape && string.index(/\\/)
         | 
| 137 219 | 
             
                      indexes = string.enum_for(:scan,/\\/).map { Regexp.last_match.begin(0) }
         | 
| @@ -146,10 +228,12 @@ module Calabash | |
| 146 228 | 
             
                    status
         | 
| 147 229 | 
             
                  end
         | 
| 148 230 |  | 
| 231 | 
            +
                  # @!visibility private
         | 
| 149 232 | 
             
                  def uia_enter
         | 
| 150 233 | 
             
                    uia_handle_command(:enter)
         | 
| 151 234 | 
             
                  end
         | 
| 152 235 |  | 
| 236 | 
            +
                  # @!visibility private
         | 
| 153 237 | 
             
                  def uia_set_location(options)
         | 
| 154 238 | 
             
                    validate_hash_is_location!(options)
         | 
| 155 239 | 
             
                    if options[:place]
         | 
| @@ -164,18 +248,12 @@ module Calabash | |
| 164 248 | 
             
                    uia_handle_command(:setLocation, loc_data)
         | 
| 165 249 | 
             
                  end
         | 
| 166 250 |  | 
| 251 | 
            +
                  # @!visibility private
         | 
| 167 252 | 
             
                  def uia_send_app_to_background(secs)
         | 
| 168 253 | 
             
                    uia_handle_command(:deactivate, secs)
         | 
| 169 254 | 
             
                  end
         | 
| 170 255 |  | 
| 171 | 
            -
                   | 
| 172 | 
            -
                    uia_call_method(:queryEl, args_arr, *opts)
         | 
| 173 | 
            -
                  end
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                  def uia_call_windows(args_arr, *opts)
         | 
| 176 | 
            -
                    uia_call_method(:queryElWindows, args_arr, *opts)
         | 
| 177 | 
            -
                  end
         | 
| 178 | 
            -
             | 
| 256 | 
            +
                  # @!visibility private
         | 
| 179 257 | 
             
                  def uia_call_method(cmd, args_arr, *opts)
         | 
| 180 258 | 
             
                    if opts.empty?
         | 
| 181 259 | 
             
                      return uia_handle_command(cmd, args_arr)
         | 
| @@ -213,6 +291,7 @@ module Calabash | |
| 213 291 |  | 
| 214 292 | 
             
                  end
         | 
| 215 293 |  | 
| 294 | 
            +
                  # @!visibility private
         | 
| 216 295 | 
             
                  def uia_handle_command(cmd, *query_args)
         | 
| 217 296 | 
             
                    command = uia_serialize_command(cmd, *query_args)
         | 
| 218 297 | 
             
                    if debug_logging?
         | 
| @@ -223,17 +302,20 @@ module Calabash | |
| 223 302 | 
             
                    uia_result(s)
         | 
| 224 303 | 
             
                  end
         | 
| 225 304 |  | 
| 305 | 
            +
                  # @!visibility private
         | 
| 226 306 | 
             
                  def uia_serialize_command(cmd, *query_args)
         | 
| 227 307 | 
             
                    args = uia_serialize_arguments(query_args)
         | 
| 228 308 | 
             
                    %Q[uia.#{cmd}(#{args.join(', ')})]
         | 
| 229 309 | 
             
                  end
         | 
| 230 310 |  | 
| 311 | 
            +
                  # @!visibility private
         | 
| 231 312 | 
             
                  def uia_serialize_arguments(args)
         | 
| 232 313 | 
             
                    args.map do |part|
         | 
| 233 314 | 
             
                      uia_serialize_argument(part)
         | 
| 234 315 | 
             
                    end
         | 
| 235 316 | 
             
                  end
         | 
| 236 317 |  | 
| 318 | 
            +
                  # @!visibility private
         | 
| 237 319 | 
             
                  def uia_serialize_argument(part)
         | 
| 238 320 | 
             
                    if part.is_a?(String)
         | 
| 239 321 | 
             
                      "'#{escape_uia_string(part)}'"
         | 
| @@ -242,6 +324,7 @@ module Calabash | |
| 242 324 | 
             
                    end
         | 
| 243 325 | 
             
                  end
         | 
| 244 326 |  | 
| 327 | 
            +
                  # @!visibility private
         | 
| 245 328 | 
             
                  def escape_uia_string(string)
         | 
| 246 329 | 
             
                    #TODO escape '\n in query
         | 
| 247 330 | 
             
                    escape_quotes string
         | 
| @@ -249,6 +332,7 @@ module Calabash | |
| 249 332 |  | 
| 250 333 | 
             
                  # <b>DEPRECATED:</b> Use <tt>uia("...javascript..", options)</tt> instead.
         | 
| 251 334 | 
             
                  # deprecated because the method signature is poor
         | 
| 335 | 
            +
                  # @!visibility private
         | 
| 252 336 | 
             
                  def send_uia_command(opts ={})
         | 
| 253 337 |  | 
| 254 338 | 
             
                    # TODO formally deprecate send_uia_command with _deprecated function
         |