Module: Calabash::Cucumber::UIA

Includes:
Logging
Included in:
Core
Defined in:
lib/calabash-cucumber/uia.rb

Overview

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

Instance Method Summary collapse

Methods included from Logging

#calabash_info, #calabash_warn

Instance Method Details

#uia(command, options = {}) ⇒ Object

Executes raw JavaScript in the UIAutomation environment (using ‘eval`).

Parameters:

  • command (String)

    the JavaScript snippet to execute

Returns:

  • (Object)

    the result returned by the UIA process

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/calabash-cucumber/uia.rb', line 17

def uia(command, options={})
  # UIA only makes sense if there is a run loop
  launcher = Calabash::Cucumber::Launcher.launcher_if_used
  run_loop = launcher && launcher.active? && launcher.run_loop
  raise ArgumentError, 'the current launcher must be active and be attached to a run_loop' unless run_loop
  raise ArgumentError, 'please supply :command' unless command

  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) ⇒ Object

Advanced method used to invoke UIAutomation JavaScript methods on objects found via Calabash queries

Examples:

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

Advanced example that chains calls and uses arguments

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

Parameters:

  • args_arr (Array)

    array describing the query, e.g., ‘[:button, marked:’foo’]‘

  • opts (Array)

    optional arguments specifying a chained sequence of method calls (see example)

See Also:



170
171
172
# File 'lib/calabash-cucumber/uia.rb', line 170

def uia_call(args_arr, *opts)
  uia_call_method(:queryEl, [args_arr], *opts)
end

#uia_call_windows(args_arr, *opts) ⇒ Object

Similar to ‘uia_call` but searches all windows

See Also:



176
177
178
# File 'lib/calabash-cucumber/uia.rb', line 176

def uia_call_windows(args_arr, *opts)
  uia_call_method(:queryElWindows, [args_arr], *opts)
end

#uia_names(*queryparts) ⇒ Array<String>

Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows. Note that this traverses the UIA (accessibility) hierarchy.

Examples:

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"
]

Parameters:

  • queryparts (Array)

    array of segments in the query, e.g., ‘:button, marked:’Hello’‘

Returns:

  • (Array<String>)

    “names” (accessibilityIdentifier) of UIAElements matching the query.



156
157
158
159
# File 'lib/calabash-cucumber/uia.rb', line 156

def uia_names(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:names, queryparts)
end

#uia_orientationString

Gets the current orientation of the device

Returns:

  • (String)

    the current orientation of the device one of ‘{’portrait’, ‘portrait-upside-down’, ‘landscape-left’, ‘landscape-right’, ‘faceup’, ‘facedown’ }‘



315
316
317
318
# File 'lib/calabash-cucumber/uia.rb', line 315

def uia_orientation
  o = uia_handle_command(:orientation).to_s
  o[1..o.length]
end

#uia_query(*queryparts) ⇒ Array<Hash>

Invoke a Calabash query inside the UIAutomation Calabash engine Note that this traverses the UIA (accessibility) hierarchy.

Examples:

uia query equivalent of “button marked:‘Hello’”

uia_query :button, marked:'Hello'

Parameters:

  • queryparts (Array)

    array of segments in the query, e.g., ‘:button, marked:’Hello’‘

Returns:

  • (Array<Hash>)

    UIAElements matching the query in serialized form.



113
114
115
116
# File 'lib/calabash-cucumber/uia.rb', line 113

def uia_query(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:query, queryparts)
end

#uia_query_windows(*queryparts) ⇒ Array<Hash>

Invoke a Calabash query inside the UIAutomation Calabash engine - includes all UIAWindows. Note that this traverses the UIA (accessibility) hierarchy.

Examples:

uia query equivalent of “button marked:‘Hello’”

uia_query_windows :button

Parameters:

  • queryparts (Array)

    array of segments in the query, e.g., ‘:button, marked:’Hello’‘

Returns:

  • (Array<Hash>)

    UIAElements matching the query in serialized form.



130
131
132
133
# File 'lib/calabash-cucumber/uia.rb', line 130

def uia_query_windows(*queryparts)
  #TODO escape '\n etc in query
  uia_handle_command(:queryWindows, queryparts)
end

#uia_rotate(dir) ⇒ Object

Simulates Rotation of the device

Parameters:

  • dir (String|Symbol)

    The position of the home button after the rotation. Can be one of ‘| ‘counter-clockwise’| :left | :right‘.



308
309
310
# File 'lib/calabash-cucumber/uia.rb', line 308

def uia_rotate(dir)
  uia_handle_command(:rotate, dir)
end

#uia_rotate_home_button_to(dir) ⇒ Object

Note:

Refer to Apple’s documentation for clarification about left vs. right landscape orientations.

Rotates the home button position to the position indicated by ‘dir`.

Parameters:

  • dir (Symbol|String)

    The position of the home button after the rotation. Can be one of ‘{:down, :left, :right, :up }`.



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/calabash-cucumber/uia.rb', line 325

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_set_responder_value(value) ⇒ Object

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`

Parameters:

  • value (String)

    the value to set



185
186
187
# File 'lib/calabash-cucumber/uia.rb', line 185

def uia_set_responder_value(value)
  uia_call_method(:elementWithKeyboardFocus, [], setValue: value)
end

#uia_type_string_raw(str) ⇒ Object



377
378
379
# File 'lib/calabash-cucumber/uia.rb', line 377

def uia_type_string_raw(str)
  uia("uia.keyboard().typeString('#{str}')")
end