Calabash iOS Tutorial

  • Command Line
  • Predefined Steps
  • Custom Steps
  • Resourcess

Command Line

Setup your project for Calabash-iOS

calabash-ios setup

Generate a skeleton features folder for your tests

calabash-ios gen

Enable accessibility in the iOS Simulator

calabash-ios sim acc

Start up the calabash console

calabash-ios console

Run cucumber without launching or closing down the simulator

NO_LAUNCH=1 cucumber

Setting the simulator version

SDK_VERSION=5.0 cucumber

Run a single feature

cucumber features/masthead.feature

Run a feature with a tag

cucumber -t @wip

Run all features without a tag

cucumber -t ~@wip

Output the view in an easy to read format from a step definition

puts query("view").to_yaml 

Reset the app in-between tests

NO_STOP=1 RESET_BETWEEN_SCENARIOS=1 SDK_VERSION=5.1 cucumber -t @wip

Predefined Steps

Things you can do:

  • see
  • fill in
  • enter
  • clear
  • touch
  • toggle
  • swipe
  • scroll
  • pinch
  • wait
  • go back
  • take picture
  • playback recording
  • rotate

Uses the Accessibility Labels (which can be seen using the Accessibility Inspector)

Examples

Step Descripiton Notes
Then I should see "First View" Confirm the presence of some text insert
Then I should not see "foo" insert insert
Then I should see a "login" button insert insert
Then I should see a "Name" input field insert insert
Then I fill in "Name" with "Alistair" insert insert
Then I clear "Name" insert insert
Then I clear input field number 1 insert insert
Then I touch "login" Touch an arbitrary view with the accessibility label "login"
Then I touch the "login" button Touch a button with the accessibility label "login" insert
Then I touch button number 1 Touch the first button insert
Then I touch done insert insert
Then I touch search insert insert
Then I touch the user location insert insert
Then I touch on screen 100 from the left and 250 from the top insert insert
Then I toggle the switch insert insert
Then I toggle the "switch" switch insert insert
Then take picture Take a screenshot This will generate a .png prefixed with the step number
Then I wait to see "text or label" insert insert
Then I wait for "text or label" to appear insert insert
Then I wait until I don't see "text or label" insert insert
Then I wait to not see "text or label" insert insert
Then I wait for the "login" button to appear insert insert
Then I wait to see a navigation bar titled "title" insert insert
Then I wait for the "label" input field insert insert
Then I wait for 2 input fields insert insert
Then I wait Wait for 2 seconds insert
Then I wait and wait Wait for 4 seconds insert
Then I wait and wait and wait... Wait for 10 seconds insert
Then I wait for 2.3 seconds Wait for 2.3 seconds specify any arbitrary number of seconds
Then I go back insert insert
Then I swipe left insert insert
Then I swipe right insert insert
Then I swipe up insert insert
Then I swipe down insert insert
Then I swipe left on number 2 insert insert
Then I swipe left on number 2 at x 20 and y 10 insert insert
Then I swipe left on "accLabel" insert insert
Then I swipe on cell number 2 insert insert
Then I pinch to zoom in insert insert
Then I pinch to zoom in on "accLabel" insert insert
Then I scroll :direction insert insert
Then I scroll :direction on "accLabel" insert insert
Then I playback recording "mytouch" insert insert
Then I playback recording "mytouch on "accLabel" insert insert
Then I playback recording "mytouch on "accLabel" with offset 10,22 insert insert
Then I rotate device left insert insert
Then I rotate device right insert insert
insert insert insert

To see how these have been implement: calabash_steps.rb

Custom Steps

Macro Steps

The simplest way of writing custom steps is to combine one or more existing steps. You do this using the macro function.

Then /^the First page should display the correct components$/ do
  macro 'I should see "First View"'
  macro 'I see 2 input field'
  macro 'I should see a "Name" input field'
  macro 'I should see "switch"'
  macro 'I should see a "login" button'
  macro 'I should see a "Alert" button'
end

If a step fails then you will get a useful error message

Expected at least 2 text/input fields, found 1 (RuntimeError)

Ruby API

Things you can do

  • touch
  • retrieve label
  • query
  • check if something exists in the view
  • use the keyboard
  • rotate the device
  • traverse views (using Directions)

Methods

  • touch()
  • label()
  • query()
  • element_exists()
  • element_does_not_exist()
  • view_with_mark_exists()
  • sleep()
  • wait_for()
  • scroll()
  • scroll_to_row()
  • check_element_exists()
  • keyboard_enter_char()
  • done()
  • rotate()
  • screenshot()

UI Elements

  • view
  • label
  • textField
  • button

Selectors

  • index:0
  • marked:'London'
  • placeholder:'username'
  • accessibilityIdentifier:'location_name'
  • accessibilityLabel:'London'
  • isEnabled:1
  • text:'Hello'
  • view:'MyClassName'
  • webView css:'#header'
NSPredicate examples
  • {text LIKE 'Hel*'}

Arguments

  • numberOfRowsInSection:0
  • :up
  • :down
  • :right
  • :left

Directions / Traversal

  • parent
  • child

Properties

  • :accessibilityLabel
  • :accessibilityIdentifier
  • :placeholder
  • :text

query("button", :titleLabel, :text) query("button buttonLabel text:'Foo Bar')

Examples

2 ways to check if an element exists with an specific accessibilityIdentifier

element_exists("view marked:'location_name'")
element_exists("view accessibilityIdentifier:'location_name'")

2 ways to retrieve the text of a view with a specific accessibilityIdentifier

query("view marked:'location_name'", :text)[0]
query("view accessibilityIdentifier:'location_name'", :text)[0]

Ways to output properties in the IRC

classes "view" 
label "view"
Example Descripiton Notes
touch("button index:0") touch the first button insert
touch("tabBarButton index:1") touch the second tabBarButton insert
touch("tabBarButton marked:'Second'") though the tabBarButton with the accessibility id or label 'Second' insert
touch("webView css:'a'") insert insert
label "tableViewCell index:0" insert insert
query("tabBarButton") Returns an array of all the tabBarButtons insert
query("tabBarButton", :accessibilityLabel) Returns an array of all the tabBarButton accessibility labels insert
query("tabBarButton index:0", :accessibilityLabel) insert insert
query("tabBarButton index:0 label", :text) Returns all the labels inside the first tabBarButton insert
query("TabBar", :selectedItem, "title")[0] insert insert
query("button marked:'Player play icon'", :isSelected) insert insert
query "label index:0" Returns the first label insert
query "label text:'Hello'" insert insert
query "label marked:'Map'" Returns the label with the accessibility label 'Map' insert
query "label {text LIKE 'Cell 1*'}" Returns the labels that start with 'Cell 1' * Uses a NSPredicate
query("imageView {accessibilityLabel LIKE '*.png'}") Returns the images with an accessibility label that contains '.png' insert
query("webView css:'*'") Get all the HTML associated with the webview insert
query("webView css:'a'").first['html'] insert insert
query "button isEnabled:1" insert insert
query("view marked:'switch'") Returns a view with accessibility id or label 'switch' insert
query("button")[0]["class"] Returns the class of the first button insert
query("tableView",numberOfRowsInSection:0) insert insert
query("webView css:'#header'") insert insert
query("view:'MKMapView'") matches a view based on the className 'MKMapView'
query "webView", :request Get the page url insert
element_exists("view") insert insert
element_exists("button marked:'#{name}'") insert insert
element_does_not_exist("button marked:'#{name}'") insert insert
view_with_mark_exists("Logout") insert insert
sleep(STEP_PAUSE) insert insert
wait_for(WAIT_TIMEOUT) insert insert
wait_for(5) insert insert
scroll_to_row "tableView", 3 insert insert
set_text "webView css:'input.login'", "ruk" insert insert
scroll "webView", :up insert insert
scroll "webView", :down insert insert
scroll "webView", :left insert insert
scroll "webView", :right insert insert
scroll_to_row "tableView", 2 insert insert
check_element_exists("view marked:'#{expected_mark}'") insert insert
keyboard_enter_char "a" insert insert
keyboard_enter_char "Dictation" insert insert
keyboard_enter_char "Shift" insert insert
keyboard_enter_char "Delete" insert insert
keyboard_enter_char "Return" insert insert
keyboard_enter_char "International" insert insert
keyboard_enter_char "More" insert insert
keyboard_enter_text "The Quick Brown Fox" insert insert
done Enters "Done" or "Search" or "Return" insert
rotate :left insert insert
rotate :right insert insert
screenshot "/Users/krukow/tmp", "my.png" insert insert
screenshot_embed( :label => 'Foo bar') insert insert
insert insert insert
  • In general you use a NSPredicate by writing a filter: {selector OP comp}, where selector is the name of a selector you want to perform on the object and OP and comp are an operation and something to compare with. See also Predicate Programming Guide

Resources

Docs

Tutorials

Videos

Related