Skip to content

In the past few blogs about Calabash for Android and iOS, we’ve covered how to set up and get started with both platforms and define some of the fundamental things in Calabash. This time we’ll take a look at Calabash steps, step definitions and predefined steps that are set by default with Calabash installations. There are few tips and tricks that can be extremely handy and useful when it comes to using additional tools to help to create Calabash test scripts for your mobile app – and inspecting what should be put in Ruby code.


Steps, Step Definitions and Predefined Steps

In mobile test automation user interactions are in the epicenter and drive the behavior and progress of the app execution. Users naturally interacts with UI components, visual assets, that enable the control of the app. To get a better understanding of how Calabash drives user interactions on these we’ll take a look at a few different methods to interact with an application. For instance, gestures on regular UI elements and interactions on those (e.g. pinch, zoom, swipe).

The UI hierarchy is pretty trivial for developers who build the app, but for testers, there are some inspection tools that can be very useful to further inspect on which types of characteristics these UI elements contain. For instance, what layers, fragments and other implementations may be difficult to inspect, but there are good tools that can be used to identify regular native UI components (e.g. Appium Inspector and uiautomatorviewer).

These types of inspection tools can help to find the name, description, value other useful attributes about the UI elements and objects. Let’s look at some basics of the step definitions and how those would be described in Ruby code. Meanwhile, you can download our free Calabash 101 to get a full understanding of steps and other tips.

1. Button Interactions

First of all, pressing a button (both on Android or iOS) is a basic procedure that test script and implementation must handle. For example, when a user presses a back button the script and implementation could look something as follows

Then I go back

Naturally, there are some reserved buttons for both Android and iOS (e.g. Back, Home, Enter) that can then use perform_action function call to send the keypress details:

For Android:
Then /^I go back$/ do
Then /^I press the enter button$/ do
For iOS:
Then /^I go back$/ do
  touch("navigationItemButtonView first")

Another example with Radio buttons would be very similar, despite that the nature of Radio button is different (on/off) and it contains information whether the button is already checked. In this example, we could use the same syntax but the implementation part would use another Ruby call:

Then I press view with id "radio0"

The “radio0” is an ID of the Android UI component that test must tap on. The implementation using tap_when_element_exists would click the UI element when it is available/ready for a click, and the implementation would go as follows:

Then /^I press view with id "([^\"]*)"$/ do |id|
  tap_when_element_exists("* id:'#{id}'")

Now, it’s slightly different how you do (implementation) this with iOS. The script itself would look the same, but the implementation part would be different:

Then /^I (?:press|touch) the "([^\"]*)" button$/ do |name|
  touch("Button touched: '#{name}'")

With iOS press/tap is called ‘touch’ but this would still use the name as a definition of which button is going to get pressed.

Other possible scenarios for touch would be a swipe where coordinates are given:

Then /^I (?:press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |x, y|
  touch(nil, { offset: { x: x.to_i, y: y.to_i } })

For more information on specific tap/click/press/touch variants and how to configure those can be found in Calabash step definitions.

2. Entering Text into Text Field

For any use case where the test script needs to enter text into text fields (e.g. login credentials or regular EditText elements) Calabash provides predefined steps out of the box. However, these can be easily tweaked to fit with your app. For instance:

Then I enter "Testing text input..." as "EditText1"

The script would enter “Testing text input…” as content into ‘EditText1’ UI element, and the implementation would go as follows:

Then /^I enter "([^\"]*)" as "([^\"]*)"$/ do |text, field|
  enter_text("android.widget.EditText {field LIKE[c] '#{field}'}", text)

The same could be applied to IDs of UI elements:

Then /^I enter text "([^\"]*)" into field with id "([^\"]*)"$/ do |text, id|
  enter_text("android.widget.EditText id:'#{id}'", text)

If you are interested to find out more about UI elements and inspect those – for example with Android – you can use uiautomatorviewer to get quickly all relevant information for your script. By default, uiautomatorviewer is installed with Android Studio.

3. Gestures

Gestures are natural for users with mobile devices and Calabash supports those as well. Let’s take a swipe as an example. The test would call it as follows:

Then I swipe right

The implementation part is slightly different for Android and iOS, and there are few other navigation/gesture implementation differences between these two platforms:

For Android:
Then /^I swipe right$/ do
  perform_action('swipe', 'right')
For iOS:
Then /^I swipe (left|right|up|down)$/ do |dir|

The implementation for a swipe with iOS looks more flexible as you only need one function to set the swipe direction. However, another example with scroll would be vice-versa when it comes to implementation:

Then I scroll up
For Android:
Then /^I scroll down$/ do
For iOS:
Then /^I scroll (left|right|up|down)$/ do |dir|
  scroll("scrollView index:0", dir)

4. Waiting and Asserts

First, the classic example with waiting/delaying test execution on Calabash:

Then I wait

This basically gives 2 seconds of delay as stated in implementation:

Then /^I wait$/ do
  sleep 2

The second example makes the test execution to wait until certain label/text is shown on the screen:

Then I wait to see "Hello!"

The same method can be also used to track if certain UI element (e.g. button) is visible on the screen. The implementation goes as follows:

For Android:
Then /^I wait to see "([^\"]*)"$/ do |text|
For iOS:
Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
  wait_for(TIMEOUT) { view_with_mark_exists( expected_mark ) }

The Wait-To-See calls are definitely better than regular sleep as this can synchronize the test execution. As said, Waits can be also applied to certain elements, and here is an example of waiting implementation until Android button is visible:

Then /^I wait for the "([^\"]*)" button to appear$/ do |identifier|
  wait_for_element_exists("android.widget.Button marked:'#{identifier}'");

Asserting is very similar to waiting and cucumber language changes from “to see” to “should see”. For example:

Then I should see "Hello!"

This step checks the view for the provided text on the screen. If Calabash cannot find the identified text on the screen, the test step will fail.

For Android:
Then /^I should see "([^\"]*)"$/ do |text|
  wait_for_text(text, timeout: 5)
For iOS:
Then /^I should see "([^\"]*)"$/ do |expected_mark|
  res = (element_exists( "view marked:'#{expected_mark}'" ) or element_exists( "view text:'#{expected_mark}'"))
  if not res
     screenshot_and_raise "No element found with mark or text: #{expected_mark}"

How Test Steps and Step Definitions Show Up

The beauty of Calabash is that it really works well for both Android and iOS and despite minor differences in Ruby implementations and sometimes with Calabash versions, we’re here to help you to run your Calabash tests smoothly on our devices. When you log in to Bitbar Testing and upload your application plus tests, you’ll see the project overview of your test runs:

test steps

If you run a Calabash test on Bitbar Testing, you’ll get all the fine-grained details of Calabash steps under each test run. Just click the specific device run open (click the device name or anything on that line) and you’ll get the very same steps shown in the device run view:

calabash test steps on a device

The UI shows your Calabash test steps and by clicking “Show screenshots” you’ll be able to see what happened with the test execution during each step with the app. Furthermore, you’ll also get the specific CPU and memory consumption details of the test run which provides an excellent glance at what should be focused on performance optimization as well as memory allocations/deallocations.

Finally, Calabash test runs done on Bitbar Testing also provide you Calabash log which can be used to further investigate the behavior of test script and what happened in execution.

calabash steps log

Happy Calabash Testing folks!

Ville-Veikko Helppi

Mobile Testing Product Expert