module Calabash::Cucumber::UIA

Low-level module for interacting directly with UIA See also {developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAElementClassReference/UIAElement/UIAElement.html} Typically used to interact with System or remote views.

Public Class Methods

redefine_instance_methods_if_necessary(xcode, automator=nil) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 532
def self.redefine_instance_methods_if_necessary(xcode, automator=nil)
  return if Calabash::Cucumber::Environment.xtc?

  if xcode.version_gte_8?
    reason = "UIAutomation is not available in Xcode >= 8.0."
    return self.redefine_instance_methods_to_raise(reason)
  end

  if automator && automator.name == :device_agent
    reason = "UIAutomation is not available when testing with DeviceAgent."
    return self.redefine_instance_methods_to_raise(reason)
  end
end
redefine_instance_methods_to_raise(reason) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 547
  def self.redefine_instance_methods_to_raise(reason)
    methods = Calabash::Cucumber::UIA.instance_methods
    methods.each do |method_name|
      Calabash::Cucumber::UIA.send(:remove_method, method_name)

      Calabash::Cucumber::UIA.send(:define_method, method_name) do |*args|

        case method_name
          when :uia
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

It is not possible to make raw UIAutomation JavaScript calls.

If you are trying to make query, use the DeviceAgent query API.

    device_agent.query({type: "TextField", index:1})
    device_agent.query({marked: "Cancel"})

If you are trying to perform a gesture or enter text, in most cases the normal
Core method will work.  If a normal Core method does work, try the DeviceAgent
Gesture API.

    device_agent.touch({type: "TextField", index:1})
    device_agent.touch({marked: "Button"})

If you cannot find an equivalent DeviceAgent workaround, please create an issue
and include:

1. At a high level, what you are trying to do.
2. The JavaScript you are trying to invoke.

Links:

* http://calabashapi.xamarin.com/ios/Calabash/Cucumber/DeviceAgent.html
* https://github.com/calabash/calabash-ios/issues
]
          when :uia_call, :uia_call_windows, :uia_call_method, :uia_names
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

There is no suggested workaround for this method.  Please review the DeviceAgent
API for a replacement.  If you can find no replacement, please create an issue
and include:

If you are trying to make query, use the DeviceAgent query API.

    device_agent.query({type: "TextField", index:1})
    device_agent.query({marked: "Cancel"})

If you are trying to perform a gesture or enter text, in most cases the normal
Core method will work.  If a normal Core method does work, try the DeviceAgent
Gesture API.

    device_agent.touch({type: "TextField", index:1})
    device_agent.touch({marked: "Button"})

If you cannot find an equivalent DeviceAgent workaround, please create an issue
and include:

1. At a high level, what you are trying to do.
2. The method you are invoking with the arguments.

Links:

* http://calabashapi.xamarin.com/ios/Calabash/Cucumber/DeviceAgent.html
* https://github.com/calabash/calabash-ios/issues
]
          when :uia_element_exists?, :uia_element_does_not_exist?
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

Use the DeviceAgent wait API.

    device_agent.wait_for_view({marked: "Cancel"})
    device_agent.wait_for_no_view({marked: "Cancel"})

]
          when :uia_query, :uia_query_el
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

Use the DeviceAgent query API.

    device_agent.query({marked: "Cancel"})
    device_agent.query({type: "TextField", index:1})

]

          when :uia_query_windows

          raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

Try to use the DeviceAgent query API.

    device_agent.query({marked: "Cancel"})
    device_agent.query({type: "TextField", index:1})

If the DeviceAgent query API does not find the correct views, please create an
issue and include:

1. At a high level, what you are trying to do.
2. The method you are invoking with the arguments.

]
          when :uia_screenshot
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

There is no replacement for this method.

Please create an issue and include:

1. At a high level, what you are trying to do.
2. A screenshot of the view you are trying capture.

]
          when :uia_orientation, :uia_rotate_home_button_to, :uia_rotate
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

You should not be calling this method.  Always call the orientation methods
defined in the Core API.

]
          when :uia_type_string, :uia_type_string_raw, :uia_enter, :uia_set_responder_value
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

In general, you should use the the text input methods defined in Core.

In some cases you will need to use the DeviceAgent query and keyboard API.

    device_agent.touch({type: "TextField", index: 1})
    wait_for_keyboard
    keyboard_enter_text("Hello")

It is important to note that the DeviceAgent implementations of:

    * keyboard_enter_text
    * keyboard_enter_char
    * enter_text_in
    * enter_text
    * fast_enter_text

have exactly the same performance.

You should prefer `enter_text` or `enter_text_in` because it matches the
Calabash 2.0 API.

]
          when :uia_set_location
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

This method has been broken for various iOS versions and device combinations
for years.

At the moment, we do not have replacement for location spoofing with DeviceAgent.

]
          when :uia_send_app_to_background
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

You should not use this method.  If the Core send_app_to_background is not
working under UIAutomation, please create a GitHub issue.

https://github.com/calabash/calabash-ios/issues

]
          when :uia_keyboard_visible?, :uia_wait_for_keyboard
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

We have not found a case (yet) where the the Core keyboard_visible? and
wait_for_keyboard methods do not work when using DeviceAgent.  If you find a
case where the Core methods do not work, please create a GitHub issue.

The current DeviceAgent keyboard API is scheduled for removal.  It is crucial
that you report workflows that require the DeviceAgent keyboard API.

    device_agent.keyboard_visible?
    wait_for { device_agent.keyboard_visible? }

https://github.com/calabash/calabash-ios/issues

]
          when :uia_handle_command, :uia_serialize_command,
            :uia_serialize_arguments, :uia_serialize_argument,
            :escape_uia_string, :send_uia_command
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

There is no replacement.

]
          when :uia_tap, :uia_tap_mark, :uia_tap_offset,
            :uia_double_tap, :uia_double_tap_mark, :uia_double_tap_offset,
            :uia_two_finger_tap, :uia_two_finger_tap_offset,
            :uia_touch_hold, :uia_touch_hold_offset,
            :uia_pan, :uia_pan_offset,
            :uia_swipe, :uia_swipe_offset, :uia_flick_offset,
            :uia_drag_inside, :uia_drag_inside_mark,
            :uia_pinch, :uia_pinch_offset, :uia_scroll_to
            raise RuntimeError, %Q[

#{reason}

#{method_name} has been removed from the Calabash API.

DeviceAgent is our replacement for UIAutomation. In most cases, you will not
need to use a special DeviceAgent gesture method like you did with UIAutomation.

If a Core gesture method does not work, there is a DeviceAgent gesture API.

    device_agent.touch({type: "Button", marked: "Back"})

For UIA pan gestures (flick, swipe, pan) use pan_coordinates.

    from_point = device_agent.query_for_coordinate({marked: "From"})
    to_point = device_agent.query_for_coordinate({marked: "To"})
    pan_coordinates(from_point, to_point)

]
          else
            raise ArgumentError, "This #{method_name} has not been handled"
        end
      end
    end
    true
  end

Public Instance Methods

escape_uia_string(string) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 485
def escape_uia_string(string)
  escape_string string
end
send_uia_command(opts ={}) click to toggle source

DEPRECATED: Use uia("...javascript..", options) instead. deprecated because the method signature is poor @!visibility private

# File lib/calabash-cucumber/uia.rb, line 492
def send_uia_command(opts ={})

  # TODO formally deprecate send_uia_command with _deprecated function
  #cmd = opts[:command]
  #new_opts = cmd.select{|x| x != :command}
  #RunLoop.deprecated("0.9.163", "Use 'uia(#{cmd}, #{new_opts})' instead")

  uia(opts[:command], opts)
end
uia(command, options={}) click to toggle source

Executes raw JavaScript in the UIAutomation environment (using ‘eval`). @param {String} command the JavaScript snippet to execute @return {Object} the result returned by the UIA process

# File lib/calabash-cucumber/uia.rb, line 14
def uia(command, options={})
  raise ArgumentError, "Please supply :command" unless command

  # UIA only makes sense if there is a run loop
  launcher = Calabash::Cucumber::Launcher.launcher_if_used
  run_loop = launcher && launcher.attached_to_automator? && launcher.run_loop

  # Automatically attach in the calabash console
  if !run_loop && defined?(IRB)
    RunLoop.log_debug("Attaching to current instruments process...")
    launcher = Calabash::Cucumber::Launcher.new
    Calabash::Cucumber::Launcher.attach
    run_loop = launcher.run_loop
    RunLoop.log_debug("Attached!")
  end

  strategy = run_loop[:uia_strategy]
  case strategy
    when :preferences, :shared_element
      path = strategy == :preferences ? 'uia' : 'uia-shared'
      res = http({:method => :post, :path => path}, {:command => command}.merge(options))

      begin
        res = JSON.parse(res)
      rescue TypeError, JSON::ParserError => _
        raise "Could not parse response '#{res}'; the app has probably crashed"
      end

      if res['outcome'] != 'SUCCESS'
        raise "uia action failed because: #{res['reason']}\n#{res['details']}"
      end
      res['results'].first
    when :host
      res = RunLoop.send_command(run_loop, command)
      status = res['status']
      case status
        when 'success'
          res
        when 'error'
          value = res['value']
          if value
            msg = "uia action failed because: #{res['value']}"
          else
            msg = 'uia action failed for an unknown reason'
          end
          raise msg
        else
          candidates = ['success', 'error']
          raise RuntimeError, "expected '#{status}' to be one of #{candidates}"
      end
    else
      candidates = [:preferences, :shared_element, :host]
      raise ArgumentError, "expected '#{run_loop[:uia_strategy]}' to be one of #{candidates}"
  end
end
uia_call(args_arr, *opts) click to toggle source

Advanced method used to invoke UIAutomation JavaScript methods on objects found via Calabash queries @see uia_query @example Calling UIAButton.isVisible() - {developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAElementClassReference/UIAElement/UIAElement.html}

uia_call [:button, {marked:'New Post'}], :isVisible

@example Advanced example that chains calls and uses arguments

uia_call [:view, marked:'New Post'], {withName:"New Post"}, :toString, {charAt:0}

@param {Array} args_arr array describing the query, e.g., ‘[:button, {marked:’foo’}]‘ @param {Array} opts optional arguments specifying a chained sequence of method calls (see example)

# File lib/calabash-cucumber/uia.rb, line 133
def uia_call(args_arr, *opts)
  uia_call_method(:queryEl, [args_arr], *opts)
end
uia_call_method(cmd, args_arr, *opts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 415
def uia_call_method(cmd, args_arr, *opts)
  if opts.empty?
    return uia_handle_command(cmd, *args_arr)
  end
  js_cmd = uia_serialize_command(cmd, *args_arr)

  js_args = []
  opts.each do |invocation|
    js_args << case invocation
                 when Symbol
                   "#{invocation}()"
                 when Hash
                   m = invocation.keys.first
                   args = invocation[m]

                   if args.is_a?(Array)
                     serialized_args = (args.map &:to_json).join(',')
                   else
                     serialized_args = args.to_json
                   end


                   "#{m}(#{serialized_args})"
                 else
                   raise "Invalid invocation spec #{invocation}"
               end
  end
  command = "#{js_cmd}.#{js_args.join('.')}"
  if RunLoop::Environment.debug?
    puts 'Sending UIA command'
    puts command
  end

  uia_result(uia(command))
end
uia_call_windows(args_arr, *opts) click to toggle source

Similar to ‘uia_call` but searches all windows @see uia_call

# File lib/calabash-cucumber/uia.rb, line 139
def uia_call_windows(args_arr, *opts)
  uia_call_method(:queryElWindows, [args_arr], *opts)
end
uia_double_tap(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 168
def uia_double_tap(*queryparts)
  uia_handle_command(:doubleTap, queryparts)
end
uia_double_tap_mark(mark) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 173
def uia_double_tap_mark(mark)
  uia_double_tap(:view, {:marked => mark})
end
uia_double_tap_offset(offset) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 178
def uia_double_tap_offset(offset)
  uia_handle_command(:doubleTapOffset, offset)
end
uia_drag_inside(dir, queryparts, options={}) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 228
def uia_drag_inside(dir, queryparts, options={})
  uia_call_method(:swipe, [dir, queryparts, options])
end
uia_drag_inside_mark(dir, mark, options={}) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 233
def uia_drag_inside_mark(dir, mark, options={})
  uia_call_method(:swipeMark, [dir, "\"#{mark}\"", options])
end
uia_element_does_not_exist?(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 258
def uia_element_does_not_exist?(*queryparts)
  uia_handle_command(:elementDoesNotExist, queryparts)
end
uia_element_exists?(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 253
def uia_element_exists?(*queryparts)
  uia_handle_command(:elementExists, queryparts)
end
uia_enter() click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 387
def uia_enter
  uia_handle_command(:enter)
end
uia_flick_offset(from, to) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 193
def uia_flick_offset(from, to)
  uia_handle_command(:flickOffset, from, to)
end
uia_handle_command(cmd, *query_args) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 452
def uia_handle_command(cmd, *query_args)
  command = uia_serialize_command(cmd, *query_args)
  if RunLoop::Environment.debug?
    puts 'Sending UIA command'
    puts command
  end
  s = uia(command)
  uia_result(s)
end
uia_keyboard_visible?() click to toggle source

Used for detecting keyboards that are not normally visible to calabash; e.g. the keyboard on the ‘MFMailComposeViewController`

@note

IMPORTANT this should only be used when the app does not respond to
`keyboard_visible?` and UIAutomation is being used.

@see keyboard_visible?

@raise [RuntimeError] If the app was not launched with instruments

# File lib/calabash-cucumber/uia.rb, line 320
def uia_keyboard_visible?
  res = uia_query_windows(:keyboard)
  res != ":nil"
end
uia_names(*queryparts) click to toggle source

Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows. Note that this traverses the UIA (accessibility) hierarchy. @example uia equivalent of ‘identifier “button”`

uia_names :button
# returns
[
  "Browse",
  "UINavigationBarBackIndicatorDefault.png",
  "16h",
  "reader postaction comment blue",
  "16h",
  "52",
  "17h",
  "10",
  "Reader",
  "Notifications",
  "Me",
  "New Post"
]

@param {Array} queryparts array of segments in the query, e.g., ‘:button, {marked:’Hello’}‘ @return {Array<String>} “names” (accessibilityIdentifier) of UIAElements matching the query.

# File lib/calabash-cucumber/uia.rb, line 119
def uia_names(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:names, queryparts)
end
uia_orientation() click to toggle source

Gets the current orientation of the device @return {String} the current orientation of the device

one of `{'portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right', 'faceup', 'facedown' }`
# File lib/calabash-cucumber/uia.rb, line 278
def uia_orientation
  o = uia_handle_command(:orientation).to_s
  o[1..o.length]
end
uia_pan(from_q, to_q) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 208
def uia_pan(from_q, to_q)
  uia_handle_command(:pan, from_q, to_q)
end
uia_pan_offset(from, to, options) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 213
def uia_pan_offset(from, to, options)
  uia_handle_command(:panOffset, from, to, options)
end
uia_pinch(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 238
def uia_pinch(*queryparts)
  uia_handle_command(:pinch, queryparts)
end
uia_pinch_offset(in_or_out, offset, duration) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 243
def uia_pinch_offset(in_or_out, offset, duration)
  uia_handle_command(:pinchOffset, in_or_out, offset, duration)
end
uia_query(*queryparts) click to toggle source

Invoke a Calabash query inside the UIAutomation Calabash engine Note that this traverses the UIA (accessibility) hierarchy. @example uia query equivalent of “button marked:‘Hello’”

uia_query :button, marked:'Hello'

@param {Array} queryparts array of segments in the query, e.g., ‘:button, {marked:’Hello’}‘ @return {Array<Hash>} UIAElements matching the query in serialized form.

# File lib/calabash-cucumber/uia.rb, line 76
def uia_query(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:query, queryparts)
end
uia_query_el(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 82
def uia_query_el(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:queryEl, queryparts)
end
uia_query_windows(*queryparts) click to toggle source

Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows. Note that this traverses the UIA (accessibility) hierarchy. @example uia query equivalent of “button marked:‘Hello’”

uia_query_windows :button

@param {Array} queryparts array of segments in the query, e.g., ‘:button, {marked:’Hello’}‘ @return {Array<Hash>} UIAElements matching the query in serialized form.

# File lib/calabash-cucumber/uia.rb, line 93
def uia_query_windows(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:queryWindows, queryparts)
end
uia_rotate(dir) click to toggle source

Simulates Rotation of the device @param [String|Symbol] dir The position of the home button after the rotation.

Can be one of `{'clockwise' | 'counter-clockwise'| :left | :right}`.
# File lib/calabash-cucumber/uia.rb, line 271
def uia_rotate(dir)
  uia_handle_command(:rotate, dir)
end
uia_rotate_home_button_to(dir) click to toggle source

Rotates the home button position to the position indicated by ‘dir`. @note Refer to Apple’s documentation for clarification about left vs.

right landscape orientations.

@param [Symbol|String] dir The position of the home button after the rotation.

Can be one of `{:down, :left, :right, :up }`.
# File lib/calabash-cucumber/uia.rb, line 288
def uia_rotate_home_button_to(dir)
  dir = dir.to_sym
  if dir == :top
    dir = :up
  elsif dir == :bottom
    dir = :down
  end
  uia_orientation = case dir
                     when :left then
                       'UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT'
                     when :right then
                       'UIA_DEVICE_ORIENTATION_LANDSCAPELEFT'
                     when :up then
                       'UIA_DEVICE_ORIENTATION_PORTRAIT_UPSIDEDOWN'
                     when :down then
                       'UIA_DEVICE_ORIENTATION_PORTRAIT'
                     else
                       raise "Unexpected direction #{dir}"
                    end
  uia("target.setDeviceOrientation(#{uia_orientation})")
end
uia_screenshot(name) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 263
def uia_screenshot(name)
  uia_handle_command(:screenshot, name)
end
uia_scroll_to(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 248
def uia_scroll_to(*queryparts)
  uia_handle_command(:scrollTo, queryparts)
end
uia_send_app_to_background(secs) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 407
def uia_send_app_to_background(secs)
  #uia_handle_command(:deactivate, secs)
  #Temporary workaround: https://github.com/calabash/calabash-ios/issues/556
  js_deactivate = %Q[var x = target.deactivateAppForDuration(#{secs}); var MAX_RETRY=5, retry_count = 0; while (!x && retry_count < MAX_RETRY) { x = target.deactivateAppForDuration(#{secs}); retry_count += 1}; x]
  uia(js_deactivate)
end
uia_serialize_argument(part) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 476
def uia_serialize_argument(part)
  if part.is_a?(String)
    "'#{escape_uia_string(part)}'"
  else
    "'#{escape_uia_string(part.to_edn)}'"
  end
end
uia_serialize_arguments(args) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 469
def uia_serialize_arguments(args)
  args.map do |part|
    uia_serialize_argument(part)
  end
end
uia_serialize_command(cmd, *query_args) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 463
def uia_serialize_command(cmd, *query_args)
  args = uia_serialize_arguments(query_args)
  %Q[uia.#{cmd}(#{args.join(', ')})]
end
uia_set_location(options) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 392
def uia_set_location(options)
  validate_hash_is_location!(options)
  if options[:place]
    place = options[:place]
    search_results = Geocoder.search(place)
    raise "Got no results for #{place}" if search_results.empty?
    loc = search_results.first
    loc_data = {'latitude' => loc.latitude, 'longitude' => loc.longitude}
  elsif options.is_a?(Hash)
    loc_data = options
  end
  uia_handle_command(:setLocation, loc_data)
end
uia_set_responder_value(value) click to toggle source

Advanced method used for fast keyboard entry by calling the setValue method on the input with current keyboard focus. This is an alternative to calling ‘keyboard_enter_text`

@param {String} value the value to set

# File lib/calabash-cucumber/uia.rb, line 148
def uia_set_responder_value(value)
  uia_call_method(:elementWithKeyboardFocus, [], setValue: value)
end
uia_swipe(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 218
def uia_swipe(*queryparts)
  uia_handle_command(:swipe, queryparts)
end
uia_swipe_offset(offset, options) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 223
def uia_swipe_offset(offset, options)
  uia_handle_command(:swipeOffset, offset, options)
end
uia_tap(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 153
def uia_tap(*queryparts)
  uia_handle_command(:tap, queryparts)
end
uia_tap_mark(mark) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 158
def uia_tap_mark(mark)
  uia_handle_command(:tapMark, mark)
end
uia_tap_offset(offset) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 163
def uia_tap_offset(offset)
  uia_handle_command(:tapOffset, offset)
end
uia_touch_hold(duration, *queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 198
def uia_touch_hold(duration, *queryparts)
  uia_handle_command(:touchHold, duration, queryparts)
end
uia_touch_hold_offset(duration, offset) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 203
def uia_touch_hold_offset(duration, offset)
  uia_handle_command(:touchHoldOffset, duration, offset)
end
uia_two_finger_tap(*queryparts) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 183
def uia_two_finger_tap(*queryparts)
  uia_handle_command(:twoFingerTap, queryparts)
end
uia_two_finger_tap_offset(offset) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 188
def uia_two_finger_tap_offset(offset)
  uia_handle_command(:twoFingerTapOffset, offset)
end
uia_type_string(string, opt_text_before='', escape=true) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 352
def uia_type_string(string, opt_text_before='', escape=true)
  result = uia_handle_command(:typeString, string, opt_text_before)

  # When 'status' == 'success', we get back result['value'].  Sometimes,
  # the 'value' key is not present in the result - in which case we assume
  # success without error.
  return if result.nil?

  # Typing on UIWebViews returns result['value'] => ':nil'.  There might
  # be other cases where result is _not_ a Hash.
  return unless result.is_a? Hash

  # If there is no 'status' key, then we assume success.  Syntax errors
  # should be caught upstream.
  # https://github.com/calabash/calabash-ios/issues/374
  return unless result.has_key? 'status'

  status = result['status']

  # If status is not 'error' we punt.  Should never happen.
  return if status != 'error'

  if result.has_key? 'value'
    raise "Could not type '#{string}' - UIAutomation returned an error: '#{result['value']}'"
  else
    raise "Could not type '#{string}' - UIAutomation returned '#{result}'"
  end
end
uia_type_string_raw(str) click to toggle source

@!visibility private

# File lib/calabash-cucumber/uia.rb, line 382
def uia_type_string_raw(str)
  uia("uia.keyboard().typeString('#{str}')")
end
uia_wait_for_keyboard(options={}) click to toggle source

Waits for a keyboard that is not normally visible to calabash; e.g. the keyboard on ‘MFMailComposeViewController`.

@note

IMPORTANT this should only be used when the app does not respond to
`keyboard_visible?` and UIAutomation is being used.

@see keyboard_visible?

@raise [RuntimeError] if the app was not launched with instruments

# File lib/calabash-cucumber/uia.rb, line 335
def uia_wait_for_keyboard(options={})
  default_opts = {
    :timeout => 10,
    :retry_frequency => 0.1,
    :post_timeout => 0.5,
    :timeout_message => "Keyboard did not appear"
  }

  options = default_opts.merge(options)

  wait_for(options) do
    uia_keyboard_visible?
  end
  true
end

Private Instance Methods

uia_result(s) click to toggle source
# File lib/calabash-cucumber/uia.rb, line 514
def uia_result(s)
  if RunLoop::Environment.debug?
    puts 'Result'
    p s
  end
  if s['status'] == 'success'
    s['value']
  else
    s
  end
end
validate_hash_is_location!(options) click to toggle source
# File lib/calabash-cucumber/uia.rb, line 504
def validate_hash_is_location!(options)
  return if options[:latitude] and options[:longitude]
  if (options[:latitude] and not options[:longitude]) ||
      (options[:longitude] and not options[:latitude])
    raise 'Both latitude and longitude must be specified if either is.'
  elsif not options[:place]
    raise 'Either :place or :latitude and :longitude must be specified.'
  end
end