*This may or may not happen, no new news for a while now
Feature: Login
@invalid
Scenario: Add site - Invalid login
Given I am about to login
When I enter invalid credentials
Then I am prompted to correct credentials
@valid
Scenario: Add site
Given I am about to login
When I enter valid credentials
Then I am successfully authenticated
And I can see posts for the site
Feature
Feature
Scenarios
steps
Contains
Contains
Step Definition
Which
call the
iOS Specific Page
Object
Android Specific
Page Object
iOS Unique
Code
Android Unique
Code
Platform Dependent
Which
call the
Feature: Login
Scenario: Add site
Given I am about to login
When I enter valid credentials
Then I am successfully authenticated
And I can see posts for the siteGiven(/^I am about to login$/) do
@current_page = page(LoginPage).await(timeout: 30)
@current_page.self_hosted_site
end
When(/^I can see posts for the site$/) do
@current_page.to_posts
end
Feature File (Gherkin)
Step Definitions (Ruby)
Given(/^I am about to login$/) do
@current_page = page(LoginPage).await(timeout: 30)
@current_page.self_hosted_site
end
Step Definition
require 'calabash-android/abase'
class LoginPage < Calabash::ABase
def trait
"android.widget.TextView text:'Sign in'"
end
def self_hosted_site
hide_soft_keyboard
tap_when_element_exists(add_self_hosted_site_button)
end
def add_self_hosted_site_button
"android.widget.TextView text:'Add self-hosted site'"
end
endPage File (Android)
await is inherited from ABase
(LoginPage's superclass)
function trait
is called by await
Unique element to our app
Given(/^I am about to login$/) do
@current_page = page(LoginPage).await(timeout: 30)
@current_page.self_hosted_site
end
Step Definition
require 'calabash-cucumber/ibase'
class LoginPage < Calabash::IBase
def trait
"button marked:'Sign In'"
end
def self_hosted_site
touch("* marked:'Add Self-Hosted Site'")
wait_for_none_animating
end
endPage File (iOS)
await is inherited from IBase
(LoginPage's superclass)
function trait
is called by await
iOS app specific implementations of same functions
Feature: Login
@invalid
Scenario: Add site - Invalid login # features/login.feature:4
Given I am about to login # features/step_definitions/login_steps.rb:1
When I enter invalid credentials # features/step_definitions/login_steps.rb:8
Then I am prompted to correct credentials # features/step_definitions/login_steps.rb:15
@valid
Scenario: Add site # features/login.feature:10
Given I am about to login # features/step_definitions/login_steps.rb:1
When I enter valid credentials # features/step_definitions/login_steps.rb:19
Then I am successfully authenticated # features/step_definitions/login_steps.rb:26
And I can see posts for the site # features/step_definitions/login_steps.rb:32
2 scenarios (2 passed)
7 steps (7 passed)
0m36.587s
Feature: Help
Scenario: Help Buttons are visible
Given I am about to login
When I tap the question mark
Then I see the "Help Center" Button
And I see the button to open the logs*And, Or, and But can also be used to make the steps more readable. (The truth is that all these labels are ignored by the test runners and are there simply to make your tests more readable. Use them.)
*Run individual scenarios by specifying the file and line number
bundle exec calabash-android run prebuilt/Android-debug.apk -p android features/help.feature:10You can implement step definitions for undefined steps with these snippets:
When(/^I tap the question mark$/) do
pending # express the regexp above with the code you wish you had
end
Then(/^I see the "(.*?)" Button$/) do |arg1|
pending # express the regexp above with the code you wish you had
end
Then(/^I see the button to open the logs$/) do
pending # express the regexp above with the code you wish you had
end
calabash-ios console
calabash-android console <path-to-apk>
>>query("*")
...
>>query("* marked:'Help'")
...
>>query("UIButton marked:'Help'")
[
[0] {
"class" => "UIButton",
"id" => nil,
"rect" => {
"center_x" => 294,
"y" => 27,
"width" => 22,
"x" => 283,
"center_y" => 48,
"height" => 42
},
"frame" => {
"y" => 27,
"width" => 22,
"x" => 283,
"height" => 42
},
"label" => "Help",
"description" => "<UIButton: 0xd8a5d10; frame = (283 27; 22 42); opaque = NO; autoresize = LM+RM; layer = <CALayer: 0xd8a59b0>>"
}
]
require 'calabash-cucumber/ibase'
class HelpPage < Calabash::IBase
def trait
"UILabel marked:'Support'"
end
def help_center
"UISwitch marked:'WordPress Help Center'"
end
def activity_logs_button
"UILabel marked:'Activity Logs'"
end
def has_log_button
wait_for_elements_exist([activity_logs_button])
end
def check_button(button_name)
if button_name == "Help Center"
wait_for_elements_exist([help_center])
end
end
endrequire 'calabash-android/abase'
class HelpPage < Calabash::ABase
def trait
"* marked:'Help'"
end
def help_center
"WPTextView marked:'Help center'"
end
def application_logs_button
"WPTextView marked:'applog_button'"
end
def has_log_button
wait_for_element_exists(application_logs_button)
end
def check_button(button_name)
if button_name == "Help Center"
wait_for_element_exists(help_center)
end
end
endrequire 'calabash-android/abase'
class HelpPage < Calabash::ABase
def trait
"* marked:'Help'"
end
def help_center
"WPTextView marked:'Help center'"
end
def application_logs_button
"WPTextView marked:'applog_button'"
end
def has_log_button
wait_for_element_exists(application_logs_button)
end
def check_button(button_name)
if button_name == "Help Center"
wait_for_element_exists(help_center)
end
end
endrequire 'calabash-cucumber/ibase'
class HelpPage < Calabash::IBase
def trait
"UILabel marked:'Support'"
end
def help_center
"UISwitch marked:'WordPress Help Center'"
end
def activity_logs_button
"UILabel marked:'Activity Logs'"
end
def has_log_button
wait_for_elements_exist([activity_logs_button])
end
def check_button(button_name)
if button_name == "Help Center"
wait_for_elements_exist([help_center])
end
end
endWhen(/^I tap the question mark$/) do
page(LoginPage).open_help
@current_page = page(HelpPage).await(timeout: 30)
end
Then(/^I see the "(.*?)" Button$/) do |button_name|
page(HelpPage).check_button(button_name)
end
Then(/^I see the button to open the logs$/) do
page(HelpPage).has_log_button
endb% bundle exec calabash-android run prebuilt/Android-debug.apk -p android features/help.feature Using the android profile...
5982 KB/s (552918 bytes in 0.090s)
6222 KB/s (4559840 bytes in 0.715s)
Feature: Help
Scenario: Help Buttons are visible # features/help.feature:3
Given I am about to login # features/step_definitions/login_steps.rb:1
When I tap the question mark # features/step_definitions/help_steps.rb:1
Then I see the "Help Center" Button # features/step_definitions/help_steps.rb:6
And I see the button to open the logs # features/step_definitions/help_steps.rb:10
1 scenario (1 passed)
4 steps (4 passed)
0m21.329s
% bundle exec cucumber -p ios features/help.feature
Using the ios profile...
Feature: Help
Scenario: Help Buttons are visible # features/help.feature:3
Given I am about to login # features/step_definitions/login_steps.rb:1
When I tap the question mark # features/step_definitions/help_steps.rb:1
Then I see the "Help Center" Button # features/step_definitions/help_steps.rb:6
And I see the button to open the logs # features/step_definitions/help_steps.rb:10
1 scenario (1 passed)
4 steps (4 passed)
0m13.595sYour cucumber features should drive your implementation, not reflect it.
You write step definition and page files after-the-fact to describe user events and actions.