Module: Calabash::Cucumber::Core

Overview

A collection of methods that provide the core calabash behaviors.

Instance Method Summary collapse

Methods included from PlaybackHelpers

#interpolate, #playback, #record_begin, #record_end

Methods included from Logging

#calabash_info, #calabash_warn

Methods included from RotationHelpers

#rotate, #rotate_home_button_to

Methods included from StatusBarHelpers

#device_orientation, #landscape?, #portrait?, #status_bar_orientation

Methods included from UIA

#uia, #uia_call, #uia_call_windows, #uia_names, #uia_query, #uia_query_windows

Methods included from FailureHelpers

#fail, #screenshot, #screenshot_and_raise, #screenshot_embed

Methods included from QueryHelpers

#escape_quotes

Methods included from EnvironmentHelpers

#default_device, #device_family_iphone?, #ios5?, #ios6?, #ios7?, #ios8?, #ipad?, #iphone?, #iphone_4in?, #iphone_5?, #iphone_app_emulated_on_ipad?, #ipod?, #simulator?, #uia_available?, #uia_not_available?, #xamarin_test_cloud?

Instance Method Details

#await_page(clz, *args) ⇒ Object

Instantiates a page using ‘page` and calls the page’s ‘await` method.

Examples:

Instantiating and waiting a ‘LoginPage` from a step definition

Given(/^I am about to login to a self-hosted site$/) do
    @current_page = await_page(LoginPage)
    @current_page.self_hosted_site
end

Parameters:

  • clz (Class)

    the page object class to instantiate (passing the cucumber world and ‘args`)

  • args (Array)

    optional additional arguments to pass to the page object constructor

Returns:

  • (Object)

    a fresh instance of ‘Class clz` which has been passed a reference to the cucumber World object. Calls await on the page object.

See Also:



875
876
877
# File 'lib/calabash-cucumber/core.rb', line 875

def await_page(clz,*args)
  clz.new(self,*args).await
end

#backdoor(sel, arg) ⇒ Object

Calls a method on the app’s AppDelegate object.

This is an escape hatch for calling an arbitrary hook inside (the test build) of your app. Commonly used to “go around” the UI for speed purposes or reset the app to a good known state.

You must create a method on you app delegate of the form:

- (NSString *) calabashBackdoor:(NSString *)aIgnorable;

or if you want to pass parameters

- (NSString *) calabashBackdoor:(NSDictionary *)params;

Examples:

backdoor("calabashBackdoor:", '')
backdoor("calabashBackdoor:", {example:'param'})

Parameters:

  • sel (String)

    the selector to perform on the app delegate

  • arg (Object)

    the argument to pass to the selector

Returns:

  • (Object)

    the result of performing the selector with the argument (serialized)



751
752
753
754
755
756
757
758
759
760
761
762
# File 'lib/calabash-cucumber/core.rb', line 751

def backdoor(sel, arg)
  json = {
        :selector => sel,
        :arg => arg
  }
  res = http({:method => :post, :path => 'backdoor'}, json)
  res = JSON.parse(res)
  if res['outcome'] != 'SUCCESS'
    screenshot_and_raise "backdoor #{json} failed because: #{res['reason']}\n#{res['details']}"
  end
  res['result']
end

#calabash_exit(opts = {}) ⇒ Object

TODO:

Shutdown the CalabashServer and close connections.

Attempts to shut the app down gracefully by simulating the transition to closed steps. The server will attempt to ensure that the following UIApplicationDelegate methods methods are called (in order).

“‘

- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationWillTerminate:(UIApplication *)application

“‘

Parameters:

  • opts (Hash) (defaults to: {})

    Options for controlling the app shutdown process.

Options Hash (opts):

  • :post_resign_active_delay (Float) — default: 0.4

    How long to wait after calling ‘application will resign active’ before calling ‘app will terminate’.

  • :post_will_terminate_delay (Float) — default: 0.4

    How long to wait after calling ‘application will resign active’ before calling ‘exit’.

  • :exit_code (Integer)

    What code should the application exit with? This exit code may or may not be used! If the UIApplication responds to ‘terminateWithSuccess`, then that method will be called. The exit code for `terminateWithSuccess` is undefined.



785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
# File 'lib/calabash-cucumber/core.rb', line 785

def calabash_exit(opts={})
  default_opts = {:post_resign_active_delay => 0.4,
                  :post_will_terminate_delay => 0.4,
                  :exit_code => 0}
  merged_opts = default_opts.merge(opts)
  # Exiting the app shuts down the HTTP connection and generates ECONNREFUSED,
  # or HTTPClient::KeepAliveDisconnected
  # which needs to be suppressed.
  begin
    http({
               :method => :post,
               :path => 'exit',
               :retryable_errors => Calabash::Cucumber::HTTPHelpers::RETRYABLE_ERRORS - [Errno::ECONNREFUSED, HTTPClient::KeepAliveDisconnected]
         },  {
               :post_resign_active_delay => merged_opts[:post_resign_active_delay],
               :post_will_terminate_delay => merged_opts[:post_will_terminate_delay],
               :exit_code => merged_opts[:exit_code]
         }
    )
  rescue Errno::ECONNREFUSED, HTTPClient::KeepAliveDisconnected
    []
  end
end

#clear_text(uiquery) ⇒ Object

sets the text value of the views matched by uiquery to '' (the empty string)

using this sparingly and with caution

it is recommended that you instead do some combination of the following

  • use queries and touches to replicate with the user would

    • for text fields, implement a clear text button and touch it

    • for text views, use touches to reveal text editing popup

    see github.com/calabash/calabash-ios/issues/151

https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API

raises an error if the uiquery finds no matching queries or finds a single view that does not respond to the objc selector ‘setText’

IMPORTANT calling:

> clear_text("view")

will clear the text on all visible views that respond to ‘setText’



999
1000
1001
1002
1003
1004
# File 'lib/calabash-cucumber/core.rb', line 999

def clear_text(uiquery)
  views_modified = map(uiquery, :setText, '')
  msg = "query '#{uiquery}' returned no matching views that respond to 'setText'"
  assert_map_results(views_modified, msg)
  views_modified
end

#client_versionString

Returns the version of the loaded Calabash library.

Returns:

  • (String)

    the version of the loaded Calabash library.

See Also:



145
146
147
# File 'lib/calabash-cucumber/core.rb', line 145

def client_version
  Calabash::Cucumber::VERSION
end

#console_attachCalabash::Cucumber::Launcher?

Attach the current calabash launcher to a console.

Examples:

You have encountered a failing cucumber Scenario.
You open the console and want to start investigating the cause of the failure.

Use

> console_attach

to connect to the current launcher

Returns:



1075
1076
1077
1078
# File 'lib/calabash-cucumber/core.rb', line 1075

def console_attach
  # setting the @calabash_launcher here for backward compatibility
  @calabash_launcher = launcher.attach
end

#double_tap(uiquery, options = {}) ⇒ Array<Hash>

Note:

This assumes the view is visible and not animating.

Performs the “double tap” gesture on the (first) view that matches query ‘uiquery`.

If the view is not visible it will fail with an error. If the view is animating it will silently fail.

By default, taps the center of the view.

Examples:

double_tap "view marked:'Third'", offset:{x:100}

Parameters:

  • uiquery (String)

    query describing view to touch.

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

Returns:

  • (Array<Hash>)

    array containing the serialized version of the tapped view.



230
231
232
# File 'lib/calabash-cucumber/core.rb', line 230

def double_tap(uiquery, options={})
  query_action_with_options(:double_tap, uiquery, options)
end

#flash(uiquery, *args) ⇒ Array

Causes all views matched by the ‘uiquery` to briefly change colors making them visually identifiable.

Parameters:

  • uiquery (String)

    a query specifying which objects to flash

  • args (Array)

    argument is ignored and should be deprecated

Returns:

  • (Array)

    an array of that contains the result of calling the objc selector ‘description` on each matching view.



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

def flash(uiquery, *args)
  # todo deprecate the *args argument in the flash method
  # todo :flash operation should return views as JSON objects
  map(uiquery, :flash, *args).compact
end

#flick(uiquery, delta, options = {}) ⇒ Array<Hash>

Note:

This assumes the view is visible and not animating.

Performs the “flick” gesture on the (first) view that matches query ‘uiquery`.

If the view is not visible it will fail with an error. If the view is animating it will silently fail.

By default, the gesture starts at the center of the view and “flicks” according to ‘delta`.

A flick is similar to a swipe.

Examples:

flick("MKMapView", {x:100,y:50})

Parameters:

  • uiquery (String)

    query describing view to touch.

  • delta (Hash)

    coordinate describing the direction to flick

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch.

Options Hash (delta):

  • :x (Numeric) — default: 0

    optional. The force and direction of the flick on the ‘x`-axis

  • :y (Numeric) — default: 0

    optional. The force and direction of the flick on the ‘y`-axis

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

Returns:

  • (Array<Hash>)

    array containing the serialized version of the touched view.



277
278
279
280
281
282
283
284
285
# File 'lib/calabash-cucumber/core.rb', line 277

def flick(uiquery, delta, options={})
  uiquery, options = extract_query_and_options(uiquery, options)
  options[:delta] = delta
  views_touched = launcher.actions.flick(options)
  unless uiquery.nil?
    screenshot_and_raise "flick could not find view: '#{uiquery}', args: #{options}" if views_touched.empty?
  end
  views_touched
end

#html(q) ⇒ Array<String>

returns the ‘html’ property of all objects matching the query ‘q`

Parameters:

  • q (String)

    the query to execute (should be a webView query)

Returns:

  • (Array<String>)

    array containing html of all elements matching the query



932
933
934
# File 'lib/calabash-cucumber/core.rb', line 932

def html(q)
  query(q).map { |e| e['html'] }
end

#identifier(uiquery) ⇒ Array<String>

Returns all accessibilityIdentifiers of objects matching ‘uiquery`.

Parameters:

  • uiquery (String)

    query to match

Returns:

  • (Array<String>)

    Returns all accessibilityIdentifiers of objects matching ‘uiquery`.



894
895
896
# File 'lib/calabash-cucumber/core.rb', line 894

def identifier(uiquery)
  query(uiquery, :accessibilityIdentifier)
end

#label(uiquery) ⇒ Array<String>

Returns all accessibilityLabels of objects matching ‘uiquery`.

Parameters:

  • uiquery (String)

    query to match

Returns:

  • (Array<String>)

    Returns all accessibilityLabels of objects matching ‘uiquery`.



887
888
889
# File 'lib/calabash-cucumber/core.rb', line 887

def label(uiquery)
  query(uiquery, :accessibilityLabel)
end

#location_for_place(place) ⇒ Geocoder::Result::Google

Returns a geo-location search result (via Google). Requires internet.

Parameters:

  • place (String)

    a description of the place to search for

Returns:

  • (Geocoder::Result::Google)

    result of the search - see /.



667
668
669
670
671
# File 'lib/calabash-cucumber/core.rb', line 667

def location_for_place(place)
  search_results = locations_for_place(place)
  raise "Got no results for #{place}" if search_results.empty?
  search_results.first
end

#page(clz, *args) ⇒ Object

Helper method to easily create page object instances from a cucumber execution context. The advantage of using ‘page` to instantiate a page object class is that it will automatically store a reference to the current Cucumber world which is needed in the page object methods to call Cucumber-specific methods like puts or embed.

Examples:

Instantiating a ‘LoginPage` from a step definition

Given(/^I am about to login to a self-hosted site$/) do
    @current_page = page(LoginPage).await(timeout: 30)
    @current_page.self_hosted_site
end

Parameters:

  • clz (Class)

    the page object class to instantiate (passing the cucumber world and ‘args`)

  • args (Array)

    optional additional arguments to pass to the page object constructor

Returns:

  • (Object)

    a fresh instance of ‘Class clz` which has been passed a reference to the cucumber World object.

See Also:



857
858
859
# File 'lib/calabash-cucumber/core.rb', line 857

def page(clz,*args)
  clz.new(self,*args)
end

#pan(from, to, options = {}) ⇒ Array<Hash>

Performs the “pan” or “drag-n-drop” gesture on from the ‘from` parameter to the `to` parameter (both are queries).

Examples:

q1="* marked:'Cell 3' parent tableViewCell descendant tableViewCellReorderControl"
q2="* marked:'Cell 6' parent tableViewCell descendant tableViewCellReorderControl"
pan q1, q2, duration:4

Parameters:

  • from (String)

    query describing view to start the gesture

  • to (String)

    query describing view to end the gesture

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

  • :duration (Numeric) — default: 1

    duration of the ‘pan’.

Returns:

  • (Array<Hash>)

    array containing the serialized version of the touched view.



349
350
351
# File 'lib/calabash-cucumber/core.rb', line 349

def pan(from, to, options={})
  launcher.actions.pan(from, to, options)
end

#pinch(in_out, options = {}) ⇒ Array<Hash>, String

TODO:

‘pinch` is an old style API which doesn’t take a query as its first argument. We should migrate this.

Performs a “pinch” gesture. By default, the gesture starts at the center of the screen.

Examples:

pinch :out
pinch :in, query:"MKMapView", offset:{x:42}

Parameters:

  • in_out (String)

    the direction to pinch (‘in’ or ‘out’) (symbols can also be used).

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch.

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

  • :query (String) — default: nil

    if specified, the pinch will be made relative to this query.

Returns:

  • (Array<Hash>, String)

    array containing the serialized version of the touched view if ‘options` is given.



366
367
368
# File 'lib/calabash-cucumber/core.rb', line 366

def pinch(in_out, options={})
  launcher.actions.pinch(in_out.to_sym,options)
end

#query(uiquery, *args) ⇒ Object

The core method for querying into the current visible view of the app under test. The query method takes as first parameter a String ‘:uiquery`. This string must follow the query syntax described in: / Query Syntax.

Optionally ‘query` takes a variable number of “invocation” arguments (`args` below). # If called with an empty list of `*args`, `query` will find the views specified by `uiquery` and return a serialized view (see Examples below).

If ‘*args` are given, then they should describe a valid selector invocation on the queried views. For example `query(’UILabel’, :text)‘ would perform the `:text` selector on all visible `UILabel` objects and return those as an Array of Strings.

The ‘query` method provide a powerful mechanism for `querying` app view state and can be used to reflectively call arbitrary methods on objects reachable from the view. For a full specification of `*args` see / Query Syntax.

Examples:

Basic view query

irb(main):009:0> query("UITabBarButton index:0")
[
    [0] {
          "class" => "UITabBarButton",
    "id" => nil,
    "rect" => {
        "center_x" => 40,
        "y" => 520,
        "width" => 76,
        "x" => 2,
        "center_y" => 544,
        "height" => 48
   },
    "frame" => {
        "y" => 1,
        "width" => 76,
        "x" => 2,
        "height" => 48
    },
    "label" => "Reader",
    "description" => "<UITabBarButton: 0xdabb510; frame = (2 1; 76 48); opaque = NO; layer = <CALayer: 0xdabd8e0>>"
  }
]

Simple selector

irb(main):010:0> query("UILabel", :text)
[
    [0] "The Ugly Volvo",
    [1] "Why Having a Baby Reminds me of Garfield Minus Garfield",
    [2] "I love the site Garfield Minus Garfield. If you don’t know the site Garfield minus Garfield  it’s a website run by a guy named Dan Walsh who takes Garfield comic strips and digitally erases Garfield from them.   more",
    [3] "Freshly Pressed",
    [4] "Reader",
    [5] "Notifications",
    [6] "Me"
]

Parameters:

  • uiquery (String)

    the query to perform. Must follow the query syntax: / Query Syntax.

  • args (Array)

    optional var-args list describing a chain of method selectors. Full details / Query Syntax.



111
112
113
# File 'lib/calabash-cucumber/core.rb', line 111

def query(uiquery, *args)
  map(uiquery, :query, *args)
end

#query_all(uiquery, *args) ⇒ Object

Deprecated.

use the ‘all’ or ‘visible’ modifier in query syntax

Queries all views in view hierarchy, even if not visible.



151
152
153
154
155
156
157
# File 'lib/calabash-cucumber/core.rb', line 151

def query_all(uiquery, *args)
  msg0 = "use the 'all' or 'visible' query language feature"
  msg1 = 'see: https://github.com/calabash/calabash-ios/wiki/05-Query-syntax'
  msg = "#{msg0}\n#{msg1}"
  _deprecated('0.9.133', msg, :warn)
  map("all #{uiquery}", :query, *args)
end

#scroll(uiquery, direction) ⇒ Object

Note:

this is implemented by calling the Obj-C ‘setContentOffset:animated:` method and can do things users cant.

Scroll a scroll view in a direction. By default scrolls half the frame size.

Examples:

scroll("UITableView", :down)

Parameters:

  • uiquery (String)

    query describing view scroll (should be UIScrollView or a web view).



385
386
387
388
389
390
# File 'lib/calabash-cucumber/core.rb', line 385

def scroll(uiquery, direction)
  views_touched=map(uiquery, :scroll, direction)
  msg = "could not find view to scroll: '#{uiquery}', args: #{direction}"
  assert_map_results(views_touched, msg)
  views_touched
end

#scroll_to_cell(options = {:query => 'tableView', :row => 0, :section => 0, :scroll_position => :top, :animate => true}) ⇒ Object

TODO:

should expose a non-option first argument query and required parameters ‘section`, `row`

Note:

this is implemented by calling the Obj-C ‘scrollToRowAtIndexPath:atScrollPosition:animated:` method and can do things users cant.

Scroll a table view to a section and row. Table view can have multiple sections.

Examples:

scroll_to_cell query:"UITableView", row:4, section:0, animate: false

Parameters:

  • options (Hash) (defaults to: {:query => 'tableView', :row => 0, :section => 0, :scroll_position => :top, :animate => true})

    specifies details of the scroll

Options Hash (options):

  • :query (String) — default: 'tableView'

    query specifying which table view to scroll

  • :section (Fixnum)

    section to scroll to

  • :row (Fixnum)

    row to scroll to

  • :scroll_position (String)

    position to scroll to

  • :animated (Boolean) — default: true

    animate or not

See Also:



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/calabash-cucumber/core.rb', line 423

def scroll_to_cell(options={:query => 'tableView',
                            :row => 0,
                            :section => 0,
                            :scroll_position => :top,
                            :animate => true})
  uiquery = options[:query] || 'tableView'
  row = options[:row]
  sec = options[:section]
  if row.nil? or sec.nil?
    raise 'You must supply both :row and :section keys to scroll_to_cell'
  end

  args = []
  if options.has_key?(:scroll_position)
    args << options[:scroll_position]
  else
    args << 'top'
  end
  if options.has_key?(:animate)
    args << options[:animate]
  end
  views_touched=map(uiquery, :scrollToRow, row.to_i, sec.to_i, *args)
  msg = "unable to scroll: '#{uiquery}' to '#{options}'"
  assert_map_results(views_touched, msg)
  views_touched
end

#scroll_to_collection_view_item(item, section, opts = {}) ⇒ Object

Note:

item and section are zero-indexed

Scrolls to an item in a section of a UICollectionView.

Examples:

Scroll to item 0 in section 2 to top.

scroll_to_collection_view_item(0, 2, {:scroll_position => :top})

Scroll to item 5 in section 0 to bottom.

scroll_to_collection_view_item(5, 0, {:scroll_position => :bottom})

The following are the allowed :scroll_position values.

{:top | :center_vertical | :bottom | :left | :center_horizontal | :right}

Parameters:

  • item (Integer)

    the index of the item to scroll to

  • section (Integer)

    the section of the item to scroll to

  • opts (Hash) (defaults to: {})

    options for controlling the collection view query and scroll behavior

Options Hash (opts):

  • :query (String) — default: 'collectionView'

    the query that is used to identify which collection view to scroll

  • :scroll_position (Symbol) — default: top

    the position in the collection view to scroll the item to

  • :animate (Boolean) — default: true

    should the scrolling be animated

  • :failed_message (String) — default: nil

    a custom error message to display if the scrolling fails - if not specified, a generic failure will be displayed

Raises:

  • (RuntimeException)

    if the scroll cannot be performed

  • (RuntimeException)

    :query finds no collection view

  • (RuntimeException)

    the collection view does not contain a cell at item/section

  • (RuntimeException)

    :scroll_position is invalid



534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/calabash-cucumber/core.rb', line 534

def scroll_to_collection_view_item(item, section, opts={})
  default_options = {:query => 'collectionView',
                     :scroll_position => :top,
                     :animate => true,
                     :failed_message => nil}
  opts = default_options.merge(opts)
  uiquery = opts[:query]

  scroll_position = opts[:scroll_position]
  candidates = [:top, :center_vertical, :bottom, :left, :center_horizontal, :right]
  unless candidates.include?(scroll_position)
    raise "scroll_position '#{scroll_position}' is not one of '#{candidates}'"
  end

  animate = opts[:animate]

  views_touched=map(uiquery, :collectionViewScroll, item.to_i, section.to_i, scroll_position, animate)

  if opts[:failed_message]
    msg = opts[:failed_message]
  else
    msg = "unable to scroll: '#{uiquery}' to item '#{item}' in section '#{section}'"
  end

  assert_map_results(views_touched, msg)
  views_touched
end

#scroll_to_collection_view_item_with_mark(mark, opts = {}) ⇒ Object

Scrolls to mark in a UICollectionView.

Examples:

Scroll to the top of the item with the given mark.

scroll_to_collection_view_item_with_mark('cat', {:scroll_position => :top})

Scroll to the bottom of the item with the given mark.

scroll_to_collection_view_item_with_mark('dog', {:scroll_position => :bottom})

The following are the allowed :scroll_position values.

{:top | :center_vertical | :bottom | :left | :center_horizontal | :right}

Parameters:

  • mark (String)

    an accessibility ‘| identifier` or text in or on the item

  • opts (Hash) (defaults to: {})

    options for controlling the collection view query and scroll behavior

Options Hash (opts):

  • :query (String) — default: 'collectionView'

    the query that is used to identify which collection view to scroll

  • :scroll_position (Symbol) — default: :top

    the position in the collection view to scroll the item to

  • :animate (Boolean) — default: true

    should the scroll be animated

  • :failed_message (String) — default: nil

    a custom error message to display if the scrolling fails - if not specified, a generic failure will be displayed

Raises:

  • (RuntimeException)

    if the scroll cannot be performed

  • (RuntimeException)

    if the mark is nil

  • (RuntimeException)

    :query finds no collection view

  • (RuntimeException)

    the collection view does not contain a cell with the mark

  • (RuntimeException)

    :scroll_position is invalid



594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/calabash-cucumber/core.rb', line 594

def scroll_to_collection_view_item_with_mark(mark, opts={})
  default_options = {:query => 'collectionView',
                     :scroll_position => :top,
                     :animate => true,
                     :failed_message => nil}
  opts = default_options.merge(opts)
  uiquery = opts[:query]

  if mark.nil?
    raise 'mark argument cannot be nil'
  end

  args = []
  scroll_position = opts[:scroll_position]
  candidates = [:top, :center_vertical, :bottom, :left, :center_horizontal, :right]
  unless candidates.include?(scroll_position)
    raise "scroll_position '#{scroll_position}' is not one of '#{candidates}'"
  end

  args << scroll_position
  args << opts[:animate]

  views_touched=map(uiquery, :collectionViewScrollToItemWithMark, mark, *args)
  msg = opts[:failed_message] || "Unable to scroll: '#{uiquery}' to cell with mark: '#{mark}' with #{opts}"
  assert_map_results(views_touched, msg)
  views_touched
end

#scroll_to_row(uiquery, number) ⇒ Object

Note:

this is implemented by calling the Obj-C ‘scrollToRowAtIndexPath:atScrollPosition:animated:` method and can do things users cant.

Scroll a table view to a row. Table view should have only one section.

Examples:

scroll_to_row "UITableView", 2

Parameters:

  • uiquery (String)

    query describing view scroll (should be UIScrollView or a web view).

See Also:



400
401
402
403
404
405
# File 'lib/calabash-cucumber/core.rb', line 400

def scroll_to_row(uiquery, number)
  views_touched=map(uiquery, :scrollToRow, number)
  msg = "unable to scroll: '#{uiquery}' to: #{number}"
  assert_map_results(views_touched, msg)
  views_touched
end

#scroll_to_row_with_mark(mark, options = {:query => 'tableView', :scroll_position => :middle, :animate => true}) ⇒ Object

Scrolls to a mark in a UITableView.

Examples:

Scroll to the top of the item with the given mark.

scroll_to_row_with_mark('settings', {:scroll_position => :top})

Scroll to the bottom of the item with the given mark.

scroll_to_row_with_mark('about', {:scroll_position => :bottom})

Parameters:

  • mark (String)

    an accessibility ‘| identifier` or text in or on the row

  • options (Hash) (defaults to: {:query => 'tableView', :scroll_position => :middle, :animate => true})

    controls the query and and scroll behavior

Options Hash (options):

  • :query (String) — default: 'tableView'

    the query that should be used to location the table

  • :scroll_position (Symbol) — default: :middle

    the table position to scroll the row to - allowed values ‘| :top | :bottom`

  • :animate (Boolean) — default: true

    should the scrolling be animated

Raises:

  • (RuntimeError)

    if the scroll cannot be performed

  • (RuntimeError)

    if the mark is nil

  • (RuntimeError)

    if the table query finds no table view

  • (RuntimeError)

    if the scroll position is invalid



474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'lib/calabash-cucumber/core.rb', line 474

def scroll_to_row_with_mark(mark, options={:query => 'tableView',
                                           :scroll_position => :middle,
                                           :animate => true})
  if mark.nil?
    screenshot_and_raise 'mark argument cannot be nil'
  end

  uiquery = options[:query] || 'tableView'

  args = []
  if options.has_key?(:scroll_position)
    args << options[:scroll_position]
  else
    args << 'middle'
  end
  if options.has_key?(:animate)
    args << options[:animate]
  end

  views_touched=map(uiquery, :scrollToRowWithMark, mark, *args)
  msg = options[:failed_message] || "Unable to scroll: '#{uiquery}' to: #{options}"
  assert_map_results(views_touched, msg)
  views_touched
end

#send_app_to_background(secs) ⇒ Object

Sends app to background. Simulates pressing the home button.

Parameters:

  • secs (Fixnum)

    number of seconds to be in the background ‘should not be more than 60 secs`



625
626
627
# File 'lib/calabash-cucumber/core.rb', line 625

def send_app_to_background(secs)
  launcher.actions.send_app_to_background(secs)
end

#server_log_levelString

Get the Calabash server log level.

Returns:

  • (String)

    the current log level



811
812
813
# File 'lib/calabash-cucumber/core.rb', line 811

def server_log_level
  _debug_level_response(http(:method => :get, :path => 'debug'))
end

#server_versionString

Returns the version of the running calabash server.

Returns:

  • (String)

    version of the running calabash server.



138
139
140
# File 'lib/calabash-cucumber/core.rb', line 138

def server_version
  JSON.parse(http(:path => 'version'))
end

#set_location(options) ⇒ Object

Note:

Seems UIAutomation is broken here on physical devices on iOS 7.1

Simulates gps location of the device/simulator.

Examples:

set_location place:'Tower of London'

Parameters:

  • options (Hash)

    specifies which location to simulate

Options Hash (options):

  • :place (String)

    a description of a place (resolved via Google maps api), e.g. “Tower of London”

  • :latitude (Numeric)

    latitude of a gps coordinate (same coordinate system as Google maps)

  • :longitude (Numeric)

    longitude of a gps coordinate (same coordinate system as Google maps)



637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/calabash-cucumber/core.rb', line 637

def set_location(options)
  if uia_available?
    uia_set_location(options)
  else
    if options[:place]
      res = location_for_place(options[:place])
      lat = res.latitude
      lon = res.longitude
    else
      lat = options[:latitude]
      lon = options[:longitude]
    end
    body_data = {:action => :change_location,
                 :latitude => lat,
                 :longitude => lon}

    body = http({:method => :post, :path => 'location'}, body_data)

    res = JSON.parse(body)
    if res['outcome'] != 'SUCCESS'
      screenshot_and_raise "Set location change failed, for #{lat}, #{lon} (#{body})."
    end
    res['results']

  end
end

#set_server_log_level(level) ⇒ Object

Set the Calabash server log level.

Parameters:

  • level (String)

    the log level to set (debug, info, warn, error)



817
818
819
# File 'lib/calabash-cucumber/core.rb', line 817

def set_server_log_level(level)
  _debug_level_response(http({:method => :post, :path => 'debug'}, {:level => level}))
end

#set_text(uiquery, txt) ⇒ Object

Deprecated.

since 0.9.145

sets the text value of the views matched by uiquery to txt

we have stopped testing this method. you have been warned.

  • to enter text using the native keyboard use ‘keyboard_enter_text’

  • to delete text use ‘keyboard_enter_text(’Delete’)“

  • to clear a text field or text view:

    • RECOMMENDED: use queries and touches to replicate what the user would do

    • use ‘clear_text’

https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API

raises an error if the uiquery finds no matching queries or finds a view that does not respond to the objc selector ‘setText’



954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
# File 'lib/calabash-cucumber/core.rb', line 954

def set_text(uiquery, txt)
  msgs = ["'set_text' is deprecated and its behavior is now unpredictable",
          "* to enter text using the native keyboard use 'keyboard_enter_text'",
          "* to delete text use 'keyboard_enter_text('Delete')",
          '* to clear a text field or text view:',
          '  - RECOMMENDED: use queries and touches to replicate what the user would do',
          '    * for text fields, implement a clear text button and touch it',
          '    * for text views, use touches to reveal text editing popup',
          '    see https://github.com/calabash/calabash-ios/issues/151',
          "  - use 'clear_text'",
          'https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API']
  msg = msgs.join("\n")
  _deprecated('0.9.145', msg, :warn)

  text_fields_modified = map(uiquery, :setText, txt)

  msg = "query '#{uiquery}' returned no matching views that respond to 'setText'"
  assert_map_results(text_fields_modified, msg)
  text_fields_modified
end

#set_user_pref(key, val) ⇒ Object

Sets user preference (NSUserDefaults) value of key ‘key` to `val`.

Examples:

set_user_pref 'foo', {lastname: "Krukow"}
# returns
[
    {
    "lastname" => "Krukow"
    },
   {
    "firstname" => "Karl"
   }
]

Parameters:

  • key (String)

    the set to set

  • val (Object)

    the (JSON_ serializable) value to set

Returns:

  • (Object)

    the current user preferences



1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
# File 'lib/calabash-cucumber/core.rb', line 1023

def set_user_pref(key, val)
  res = http({:method => :post, :path => 'userprefs'},
             {:key=> key, :value => val})
  res = JSON.parse(res)
  if res['outcome'] != 'SUCCESS'
    screenshot_and_raise "set_user_pref #{key} = #{val} failed because: #{res['reason']}\n#{res['details']}"
  end

  res['results']
end

#start_test_server_in_background(args = {}) ⇒ Calabash::Cucumber::Launcher

Note:

It is not recommended to call this method outside of the calabash console. Call ‘Calabash::Cucumber::Launcher#relaunch instead.

Starts the app and Calabash test server in the console.

Returns:

See Also:



835
836
837
838
839
840
# File 'lib/calabash-cucumber/core.rb', line 835

def start_test_server_in_background(args={})
  stop_test_server
  @calabash_launcher = Calabash::Cucumber::Launcher.new()
  @calabash_launcher.relaunch(args)
  @calabash_launcher
end

#swipe(dir, options = {}) ⇒ Array<Hash>, String

TODO:

‘swipe` is an old style API which doesn’t take a query as its first argument. We should migrate this.

Note:

Due to a bug in Apple’s UIAutomation, swipe is broken on certain views in the iOS Simulator. Swiping works on devices. https://github.com/calabash/calabash-ios/issues/253

Performs a “swipe” gesture. By default, the gesture starts at the center of the screen.

Examples:

swipe :left
swipe :down, offset:{x:10,y:50}, query:"MKMapView"

Parameters:

  • dir (String)

    the direction to swipe (symbols can also be used).

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch.

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

  • :query (String) — default: nil

    if specified, the swipe will be made relative to this query.

Returns:

  • (Array<Hash>, String)

    array containing the serialized version of the touched view if ‘options` is given.



329
330
331
332
333
334
# File 'lib/calabash-cucumber/core.rb', line 329

def swipe(dir, options={})
  unless uia_available?
    options = options.merge(:status_bar_orientation => status_bar_orientation)
  end
  launcher.actions.swipe(dir.to_sym, options)
end

#tap(hash_or_string, *args) ⇒ Array<Hash>

Deprecated.

In later Calabash versions we will change the semantics of ‘tap` to take a general query (instead of a ’mark’ now). We’re deprecating this now to prepare people for a breaking change.

taps a view with mark ‘hash_or_string`

Parameters:

  • hash_or_string (String)

    mark to pass to call ‘tap_mark(hash_or_string)`.

Returns:

  • (Array<Hash>)

    array containing the serialized version of the tapped view.



909
910
911
912
913
914
915
916
917
918
919
# File 'lib/calabash-cucumber/core.rb', line 909

def tap(hash_or_string, *args)
  deprecation_msg = 'Use tap_mark instead. In later Calabash versions we will change the semantics of `tap` to take a general query.'
  _deprecated('0.10.0', deprecation_msg, :warn)
  if hash_or_string.is_a?(String)
    tap_mark(hash_or_string, *args)
  elsif hash_or_string.respond_to?(:[])
    wait_tap(hash_or_string[:query], hash_or_string)
  else
    raise(ArgumentError, "first parameter to tap must be a string or a hash. Was: #{hash_or_string.class}, #{hash_or_string}")
  end
end

#tap_mark(label, *args) ⇒ Array<Hash>

taps a view with mark ‘label`. Equivalent to `touch(“* marked:’##label‘”)`

Parameters:

  • label (String)

    the mark of the view to tap

  • args (Array)

    optional additional arguments to pass to ‘touch`.

Returns:

  • (Array<Hash>)

    array containing the serialized version of the tapped view.



925
926
927
# File 'lib/calabash-cucumber/core.rb', line 925

def tap_mark(label, *args)
  touch("view marked:'#{label}'", *args)
end

#tap_point(x, y) ⇒ Boolean

Performs the ‘tap` gesture on an absolute coordinate.

Parameters:

  • x (Numeric)

    x-coordinate to tap

  • y (Numeric)

    y-coordinate to tap

Returns:

  • (Boolean)

    ‘true`

See Also:



184
185
186
# File 'lib/calabash-cucumber/core.rb', line 184

def tap_point(x,y)
  touch(nil, offset: {x:x, y:y})
end

#touch(uiquery, options = {}) ⇒ Array<Hash>

Performs the ‘tap` gesture on the (first) view that matches query `uiquery`. Note that `touch` assumes the view is visible and not animating. If the view is not visible `touch` will fail. If the view is animating `touch` will silently fail. By default, taps the center of the view.

Parameters:

  • uiquery (String)

    query describing view to tap. Note ‘nil` is allowed and is interpreted as `tap_point(options[:x],options[:y])`

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

Returns:

  • (Array<Hash>)

    array containing the serialized version of the tapped view.

See Also:



173
174
175
# File 'lib/calabash-cucumber/core.rb', line 173

def touch(uiquery, options={})
  query_action_with_options(:touch, uiquery, options)
end

#touch_hold(uiquery, options = {}) ⇒ Array<Hash>

Note:

This assumes the view is visible and not animating.

Performs the “long press” or “touch and hold” gesture on the (first) view that matches query ‘uiquery`.

If the view is not visible it will fail with an error. If the view is animating it will silently fail.

By default, the gesture starts at the center of the view.

Examples:

touch_hold "webView css:'input'", duration:10, offset:{x: -40}

Parameters:

  • uiquery (String)

    query describing view to touch.

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch.

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

  • :duration (Numeric) — default: 3

    duration of the ‘hold’.

Returns:

  • (Array<Hash>)

    array containing the serialized version of the touched view.



305
306
307
# File 'lib/calabash-cucumber/core.rb', line 305

def touch_hold(uiquery, options={})
  query_action_with_options(:touch_hold, uiquery, options)
end

#two_finger_tap(uiquery, options = {}) ⇒ Array<Hash>

Note:

This assumes the view is visible and not animating.

Performs the “two-finger tap” gesture on the (first) view that matches query ‘uiquery`.

If the view is not visible it will fail with an error. If the view is animating it will silently fail.

By default, taps the center of the view.

Examples:

two_finger_tap "view marked:'Third'", offset:{x:100}

Parameters:

  • uiquery (String)

    query describing view to touch.

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch.

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to touch point. Offset supports an ‘:x` and `:y` key and causes the touch to be offset with `(x,y)` relative to the center (`center + (offset, offset)`).

Returns:

  • (Array<Hash>)

    array containing the serialized version of the tapped view.



251
252
253
# File 'lib/calabash-cucumber/core.rb', line 251

def two_finger_tap(uiquery,options={})
  query_action_with_options(:two_finger_tap, uiquery, options)
end

#user_pref(key) ⇒ Object

Gets the user preference (NSUserDefaults) value for a key.

Parameters:

  • key (String)

    the read

Returns:

  • (Object)

    the current user preferences value for ‘key`



1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
# File 'lib/calabash-cucumber/core.rb', line 1037

def user_pref(key)
  res = http({:method => :get, :raw => true, :path => 'userprefs'},
             {:key=> key})
  res = JSON.parse(res)
  if res['outcome'] != 'SUCCESS'
    screenshot_and_raise "get user_pref #{key} failed because: #{res['reason']}\n#{res['details']}"
  end

  res['results'].first
end

#wait_tap(uiquery, options = {}) ⇒ Array<Hash>

Performs the ‘tap` gesture on the (first) view that matches query `uiquery`.

As opposed to ‘touch`, `wait_tap` is a high-level method that combines:

  1. waiting for the view to appear,

  2. waiting for animations to complete on the view (and it’s parents) and

  3. actually tapping the view.

This removes the common boiler-plate trio: ‘wait_for_element_exists`, `wait_for_none_animating`, `touch`.

By default, taps the center of the view.

Parameters:

  • uiquery (String)

    query describing view to tap. Note ‘nil` is not allowed.

  • options (Hash) (defaults to: {})

    option for modifying the details of the touch

Options Hash (options):

  • :offset (Hash) — default: nil

    optional offset to tap point. Offset has an ‘:x` and `:y` key the tap will be performed on the center of the view plus the offset.

  • :timeout (Hash) — default: 30

    maximum number of seconds to wait for the view to appear

  • :frequency (Hash) — default: 0.2

    polling frequency to for checking if the view is present (>= 0.1)

Returns:

  • (Array<Hash>)

    serialized version of the tapped view

See Also:



209
210
211
212
213
# File 'lib/calabash-cucumber/core.rb', line 209

def wait_tap(uiquery, options={})
  # noinspection RubyUnusedLocalVariable
  _uiquery, options = extract_query_and_options(uiquery, options)
  launcher.actions.wait_tap(options)
end