First Steps with the Capybara Testing Tool

Posted by Ritinder Kaur

Capybara is a software testing tool that acts as an effective wrapper for web drivers like Selenium, Webkit, Rack Test and Poltergeist. The customized methods in the Capybara testing tool are implemented in Ruby, which has numerous libraries and frameworks - like Ruby on Rails - that make pre-written code accessible to you, making your testing task easier. Scripts written in Gherkin can be mapped to Capybara code for behavior driven development of projects.

This article describes some Capybara methods that automate app testing for simulating user input. Some methods help “set” the input and others “get” (verify) the page elements. Let’s look at some Gherkin scenarios for a user to update their identity details.

 

Filling in text fields

Let us look into an example for filling in the text field using Capybara:

1
2
3
4
5
6
7
8
Scenario: Verify existing data and edit employee info on Edit Employee Profile page
Given Joe Molly is on Edit Employee Profile page
When Joe Molly clicks on Identity tab
Then Joe Molly should see "Joe" in "First Name*" text box
And Joe Molly should see "Molly" in "Last Name*" text box
When Joe enters "Bob" in "First Name*" text box
And Joe Molly clicks Save button
Then Joe Molly verifies message "Your Identity changes have been submitted successfully." on Edit Employee Profile page

 

The underlying Capybara testing code for automating the scenario

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Given(/^Joe Molly is on Edit Employee Profile page$/) do
visit("user/profile/edit")
page.should have_content("Update Your Identity")
end

When(/^Joe Molly clicks on Identity tab$/) do
element = page.find_link("Identity")
element.trigger('click')
end

And(/^Joe Molly should see "([^"]*)" in "([^"]*)" text box$/) do |value, textBoxName|
element = find_field(textBoxName)
textBoxValue = element.value
textBoxValue.should eq value
end

When(/^Joe enters "([^"]*)" in "([^"]*)" text box$/) do |value, textBoxName|
fill_in(textBoxName, :with => value)
end

And(/^Joe Molly clicks Save button$/) do
button = find_button("Save")
button.trigger('click')
end

Then(/^Joe Molly verifies message "([^"]*)" on Edit Employee Profile page$/) do |messageText|
page.should have_content(messageText)
end

 

Let’s take a look at the various methods used :

  • The visit (line 2) method navigates to the given URL and page.should have_content (line 3) will check if the text is visible on the page. This method waits for the element to be visible for the default wait time which is 2 seconds in Capybara.
  • page.find_link (line 7) will find the link to update the user identity on the page and the element.trigger (line 8) method will ‘click’ on it.
  • The find_field method (line 12) finds the field TextboxName and passes it to the variable ‘element’.
  • find_button (line 22) will find the element ‘Save’ on the page and the trigger method will ‘click’ on it.

And what about the ‘get’ and ‘set’ methods used here?

Get method: The .value method gets the value and stores it in the variable ‘textBoxValue’.

    textBoxValue = element.value
 

 

Set method: fill_in locates the text field by its name, ID or label text and fills in the value.

1
2
3
  When(/^Joe enters "([^"]*)" in "([^"]*)" text box$/) do |value, textBoxName|
fill_in(textBoxName, :with => value)
end

 

Choose a radio button

We can use a similar scenario to see how to code for user input through a radio button:

1
2
3
4
5
6
7
Scenario: Verify employee's gender is shown correctly in Edit Employee Profile page
Given Joe Molly is on Edit Employee Profile page
When Joe Molly clicks on Identity tab
Then Joe Molly verifies that "Male" radio option is selected for gender
When Joe Molly selects "Female" radio option for gender
And Joe Molly clicks Save button
Then Joe Molly verifies message "Your Identity changes have been submitted successfully." on Edit Employee Profile page

 

What the code looks like

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Step definition:

Given(/^Joe Molly is on Edit Employee Profile page$/) do
visit("user/profile/edit")
page.should have_content("Update Your Identity")
end

When(/^Joe Molly clicks on Identity tab$/) do
element = page.find_link("Identity")
element.trigger('click')
end

Then(/^Joe Molly verifies that "([^"]*)" radio option is selected for gender$/) do |radioButtonName|
page.has_checked_field?(radioButtonName)
end

When(/^Joe Molly selects "([^"]*)" radio option for gender$/) do |radioOptionName|
choose(radioOptionName)
end

And(/^Joe Molly clicks Save button$/) do
button = find_button("Save")
button.trigger('click')
end

Then(/^Joe Molly verifies message "([^"]*)" on Edit Employee Profile page$/) do |messageText|
page.should have_content(messageText)

 

Get method:  page.has_checked_field? (line 14) will ‘get’(verify) if the page has a radio button with the given value, id or label.

1
2
3
Then(/^Joe Molly verifies that "([^"]*)" radio option is selected for gender$/) do |radioButtonName|
page.has_checked_field?(radioButtonName)
end

 

Set method: choose (line 18) will find the radio button via its name, id or label and mark it as checked.

1
2
3
When(/^Joe Molly selects "([^"]*)" radio option for gender$/) do |radioOptionName|
choose(radioOptionName)
end

New call-to-action

'Check' a check box

The check box for the “Do Not Contact” option is to be unchecked:

1
2
3
4
5
6
7
Scenario: Verify employee un-checks Do Not Contact option in Edit Employee Profile page
Given Joe Molly is on Edit Employee Profile page
When Joe Molly clicks on Identity tab
Then Joe Molly verifies that "Do Not Contact" checkbox is checked
When Joe Molly un-checks "Do Not Contact" checkbox
And Joe Molly clicks Save button
Then Joe Molly verifies message "Your Identity changes have been submitted successfully." on Edit Employee Profile page

 

The code for this scenario

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Given(/^Joe Molly is on Edit Employee Profile page$/) do
visit("user/profile/edit")
page.should have_content("Update Your Identity")
end

When(/^Joe Molly clicks on Identity tab$/) do
element = page.find_link("Identity")
element.trigger('click')
end

Then(/^Joe Molly verifies that "([^"]*)" checkbox is checked$/) do |checkBoxName|
page.has_checked_field?(checkBoxName)
end

When(/^Joe Molly un-checks "([^"]*)" checkbox$/) do |checkBoxName|
uncheck(checkBoxName)
end

And(/^Joe Molly clicks Save button$/) do
button = find_button("Save")
button.trigger('click')
end

Then(/^Joe Molly verifies message "([^"]*)" on Edit Employee Profile page$/) do |messageText|
page.should have_content(messageText)
end

 

Get method:  page.has_checked_field? (line 12) will verify if the page has a check box with the given value, id or label.

1
2
3
Then(/^Joe Molly verifies that "([^"]*)" checkbox is checked$/) do |checkBoxName|
page.has_checked_field?(checkBoxName)
end

 

Set method : uncheck (line 16) will remove the check from the checkbox ‘checkBoxName’.

1
2
3
When(/^Joe Molly un-checks "([^"]*)" checkbox$/) do |checkBoxName|
uncheck(checkBoxName)
end

 

Select an option from a drop down

1
2
3
4
5
6
7
Scenario: Verify employee's country is shown correctly in Edit Employee Profile page
Given Joe Molly is on Edit Employee Profile page
When Joe Molly clicks on Identity tab
Then Joe Molly verifies that "United States" is selected in "Country" drop down
When Joe Molly selects "Canada" from "Country" drop down
And Joe Molly clicks Save button
Then Joe Molly verifies message "Your Identity changes have been submitted successfully." on Edit Employee Profile page

 

The code for selecting the country name from a drop down box

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Given(/^Joe Molly is on Edit Employee Profile page$/) do
visit("user/profile/edit")
page.should have_content("Update Your Identity")
end

When(/^Joe Molly clicks on Identity tab$/) do
element = page.find_link("Identity")
element.trigger('click')
end

Then(/^Joe Molly verifies that "([^"]*)" is selected in "([^"]*)" drop down$/) do |value, dropDownName|
case dropDownName
when 'Country'
dropDownCssSelector = "#country"
end
element = find_field(dropDownCssSelector)
dropDownValue = element.value
dropDownValue.should eq value
end

When(/^Joe Molly selects "([^"]*)" from "([^"]*)" drop down$/) do |dropDownValue, dropDownName|
page.select dropDownValue, :from => dropDownName
end

 

Get method: .value (line 17) gets the value of the previously selected option (the country name “United States”) and stores it in the variable dropDownValue.

  dropDownValue = element.value
 

 

Set method: page.select(dropDown Value :from => dropDownName) sets the new value (the country name “Canada”) from the variable dropDownName in the drop down box.

  page.select dropDownValue, :from => dropDownName

 

Some of the Capybara finder methods like select, fill_in, check and choose, which I have mentioned above, retry searching for the element if they can't find it at the first attempt. This prolongs the running time of the test suite, creating performance issues.

You can read more about Capybara methods and functions here

Capybara as a testing tool succeeds in providing an easily usable framework, combining the ease of the Gherkin script and the powerful features of Selenium.

For more on BDD and Gherkin syntax, read the article  “Why go for BDD?”

New call-to-action