About this book

Everybody understands why implementing automated tests is important but at the same time developing them can be costly and time consuming, and tests can be also be fragile and prone to false positives. By using Capybara, you can develop robust tests quickly and run them in multiple drivers ensuring greater re-use; Capybara’s API also extends the human readable style made popular by frameworks such as Cucumber and RSpec.

"Application Testing with Capybara" takes you from installing the gem to getting up and running with a YouTube search scenario within the first two chapters. We then look deeper into the API, using Rack-Test for applications built with Rails or Sinatra and see how to test handle Asynchronous JavaScript and “black box” components such as Flash. Finally, we consider some advanced topics such as looking at alternatives to Selenium and accessing the native driver directly.

This book takes you from the basics of installing Capybara, through its API and onto advanced topics. You will learn how to use Capybara’s extensive API to interact with your application, covering topics such as navigation, filling in forms, and querying your page for expected content. Beyond this we will consider why Capybara is so well suited to testing applications written in frameworks such as Rails and Sinatra. We will look at strategies for validating seemingly “untestable” components such as HTML5 or Flash by building out a testable API. Finally we will turn you into a Capybara ninja by covering advanced topics such as accessing functionality in the base driver, advanced driver configuration, and alternative flavours of drivers outside Selenium and Rack-Test.

Publication date:
September 2013
Publisher
Packt
Pages
104
ISBN
9781783281251

 

Chapter 1. Your First Scenario with Capybara

Capybara brings two key ingredients to test automation: human-readable code via an elegant domain-specific language (DSL) and the ability to write once and run on multiple drivers such as Selenium WebDriver or Rack::Test for Rails/Sinatra applications. Through the course of this book we will see how Capybara can greatly increase the resilience of our tests and enhance our productivity.

In this chapter we will walk through installing Capybara and get up and running straight away with a simple scenario.

Specifically, we will cover the following:

  • Ensuring that Ruby, RubyGems, and Bundler are available

  • Ensuring that you have the necessary system libraries available

  • Installing the Capybara gem

  • Implementing your first scenario with Capybara, Cucumber, and Selenium WebDriver

 

Installing Capybara


Installing Capybara is no different than installing any other Ruby gem; if you have done any Ruby development in the past, it is likely that you will have all the prerequisites, and this process will be straightforward.

 

Preparing your system


Capybara is a Ruby gem and as such we need to ensure Ruby is available on the system.

Note

When you are learning a new library, it makes sense to use standard Ruby (as opposed to Ruby that runs on a different platform, such as JRuby or Iron Ruby) and run everything from the command line. This simply limits the amount of things that might go wrong due to the quirks of a less well-supported platform or an overly complicated IDE.

Open a command prompt and check the version of your Ruby interpreter:

$ ruby -v
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin11.4.2]

If you see anything greater than 1.9, perfect! This means the correct version of Ruby installed and available for you to use.

If you see command not found, this means either Ruby is not installed or the system cannot find it. If you think you have installed Ruby, try modifying your PATH variable and add the location of the Ruby executable.

If you see anything less than 1.9, you should upgrade your current version of Ruby to 1.9 or greater. Capybara has a lot of dependencies and it no longer supports versions of Ruby prior to 1.9.

Installing gems with RubyGems

Like most languages Ruby has its own mechanism for managing libraries of code. RubyGems is the software used to manage gems that are libraries and Capybara is a Ruby gem itself.

The RubyGems application typically gets installed when you first install Ruby but it is worth double-checking if you have it.

At your command prompt, check the version of RubyGems installed by running the following command:

$ gem -v
1.8.23

If you see anything greater than Version 1.5.0 then you are good to go.

If you see the command not found message, you need to install RubyGems or add the executable to your PATH variable.

If you see anything less than Version 1.5.0, update the version by running the following command:

gem update –-system

Installing gems with Bundler

Although you can install and use Capybara quite happily without using Bundler , it is worth covering this because Bundler is becoming ubiquitous within the Ruby ecosystem and it is very likely that you will want to use it to manage your project's dependencies.

Bundler is itself a Ruby gem and applies a layer of finer grained dependency management on top of RubyGems. With RubyGems you can only ever have one version of a gem installed on your system; with Bundler you can isolate dependencies to a specific project.

Run the following command to install Bundler:

gem install bundler

In your project directory, create a file named Gemfile with the following contents:

source 'https://rubygems.org'

gem 'capybara'

Then at a command prompt within that directory run:

bundle install

This will install and link the gems you specified in your Gemfile (as well as all their dependencies) with your current project. This will prevent you from accidentally breaking another project that might, for example, depend on an earlier version of the Nokogiri gem and will generally make your life a lot easier.

Bundler allows you to declare specific version requirements in your project Gemfile and provides many other options such as retrieving a gem directly from a GitHub repository. You can also bundle gems to a local directory under your project. See http://gembundler.com for more details of this awesome gem.

 

Installing system libraries


On some platforms certain gems have a dependency on system libraries. This is usually done for performance reasons. Ruby is an interpreted language so tasks, such as parsing XML can be slow; therefore, it makes sense to delegate that task to a system library.

On Windows you won't need to worry about this, though you will have to ensure you have the Ruby DevKit installed; see http://rubyinstaller.org/add-ons/devkit for detailed instructions on how to do this.

Capybara has a dependency on Nokogiri, the popular Ruby-based XML parser. This in turn needs the following system libraries to be available:

  • libxml2

  • libxml2-dev

  • libxslt

  • libxslt-dev

Tip

The latest version of Nokogiri now includes these dependencies within the gem itself. It is still worth installing the system libraries globally, however, as you will surely encounter projects that rely on versions of Nokogiri prior to 1.6.0.

How you install these on a particular system will differ, for example, apt-get for Ubuntu, yum for Red Hat, or brew for Mac OS X.

 

Installing Capybara


Your system is now ready for a painless installation of Capybara. How you install the gem will depend on whether you choose to use RubyGems directly or Bundler within your project.

Using RubyGems

If you decide to go without Bundler, installing Capybara is as simple as:

gem install capybara

If all goes well, you should see an output like the following at your command prompt. The precise output might differ slightly depending on how many of the dependencies you already had installed:

Fetching: mime-types-1.25.gem (100%)
Fetching: rack-1.5.2.gem (100%)
Fetching: rack-test-0.6.2.gem (100%)
Fetching: xpath-2.0.0.gem (100%)
Fetching: capybara-2.1.0.gem (100%)
IMPORTANT! Some of the defaults have changed in Capybara 2.1. If you're experiencing failures,
please revert to the old behaviour by setting:

    Capybara.configure do |config|
      config.match = :one
      config.exact_options = true
      config.ignore_hidden_elements = true
      config.visible_text_only = true
    end

If you're migrating from Capybara 1.x, try:

    Capybara.configure do |config|
      config.match = :prefer_exact
      config.ignore_hidden_elements = false
    end

Details here: http://www.elabs.se/blog/60-introducing-capybara-2-1

Successfully installed mini_portile-0.5.1
Successfully installed nokogiri-1.6.0
Successfully installed mime-types-1.25
Successfully installed rack-1.5.2
Successfully installed rack-test-0.6.2
Successfully installed xpath-2.0.0
Successfully installed capybara-2.1.0
7 gems installed

Using Bundler

If you are using Bundler, ensure you have a file named Gemfile in the root directory of your project directory and it contains the following:

source 'https://rubygems.org'
 
gem 'capybara'

Then install the necessary gems by running the following command:

bundle install

If everything is successful, you should see an output like the following:

$ bundle install 
Fetching gem metadata from https://rubygems.org/.........
Installing mime-types (1.25)
Installing mini_portile (0.5.1)
Installing nokogiri (1.6.0)
Installing rack (1.5.2)
Installing rack-test (0.6.2)
Installing xpath (2.0.0)
Installing capybara (2.1.0)
Using bundler (1.3.5)
Your bundle is complete!
 

Installing Cucumber and Selenium


Capybara is simply an API that provides a layer of abstraction on top of your actual automation library. If it helps, think of Capybara as your translator; you tell it to do something and it translates a nice elegant command into the API of your given driver (which can be a lot less friendly).

So to use this translator we need to have both a way of telling it what to do and also an automation library API for it to translate in to.

Capybara is a very flexible library and throughout this book we will see it used in a variety of settings; however, by far the most common use case is to employ Cucumber as the test runner with Capybara driving Selenium WebDriver to carry out the browser automation.

Cucumber allows the execution of behavior-driven development (BDD) scenarios written in the Gherkin syntax to drive your tests. If you are not overly familiar with Cucumber, http://cukes.info should be your first port of call but don't worry it's very straightforward and we will walk through creating your first scenario.

Here is an example Cucumber scenario, which we are going to automate:

Feature: Search for Videos on YouTube

    Scenario: Search for Videos of Large Rodents
        Given I am on the YouTube home page
        When I search for "capybara"
        Then videos of large rodents are returned

When Cucumber is invoked it parses the plain English scenario and using regular expressions it matches each line to an actual line of Ruby code, called a step definition. We will use Capybara to implement these steps. Capybara will then handle the communication with Selenium WebDriver, which will open the browser and start automating the scenario.

The following diagram illustrates the flow from Cucumber through to the underlying driver with Capybara sitting in the middle acting as a translator:

Cucumber and Selenium WebDriver are just additional gems. To install them, run the following:

gem install cucumber selenium-webdriver

Tip

If you are using Bundler, add cucumber and selenium-webdriver to your Gemfile and run the bundle install command again.

In versions of Capybara prior to 2.1, Selenium WebDriver was declared as a runtime dependency in which case it would have been installed when you installed Capybara and a separate installation would not have been required.

 

Cucumber-Rails


If you are using Capybara to test a Rails application, you should install the Cucumber-Rails gem as opposed to the standard Rails gem.

This gem has both Capybara and Cucumber declared as dependencies, so you will get these for free when you install the gem. To install Cucumber-Rails, simply run the following command:

gem install cucumber-rails

Alternatively, add this to your Gemfile if you are using Bundler, so it looks like the following:

source 'https://rubygems.org'
 
gem 'cucumber-rails'
 

Your first scenario – a YouTube search


Now that we have everything we need, let's get cracking and automate our first scenario, a simple YouTube search:

Feature: Search for Videos on YouTube

    Scenario: Search for Videos of Large Rodents
        Given I am on the YouTube home page
        When I search for "capybara"
        Then videos of large rodents are returned

A full guide to using Cucumber is outside the scope of this book, but let's assume you have a file/directory set up something like the one shown here, and that you can run features from the command line using Cucumber.

Tip

If you are using Bundler, run Cucumber using the following command:

bundle exec cucumber

This will ensure you get the Cucumber executable from your project gem bundle and not any global gems.

features/
├── youtube_search.feature
├── step_defs
│   └── steps.rb
└── support
    └── env.rb

Assuming you have a feature file containing the scenario text, when you run Cucumber from the command line you should get the step definition stubs generated:

$ bundle exec cucumber 
Feature: Search for Videos on YouTube

  Scenario: Search for Videos of Large Rodents 
    Given I am on the YouTube home page
    When I search for "capybara"
    Then videos of large rodents are returned

1 scenario (1 undefined)
3 steps (3 undefined)
0m0.014s
You can implement step definitions for undefined steps with these snippets:

Given(/^I am on the YouTube home page$/) do
  pending # express the regexp above with the code you wish you had
end

When(/^I search for "(.*?)"$/) do |arg1|
  pending # express the regexp above with the code you wish you had
end

Then(/^videos of large rodents are returned$/) do
  pending # express the regexp above with the code you wish you had
end

Copy and paste the snippets output by Cucumber into your steps.rb file. These are the stubs that we will complete with our Capybara commands.

If you run Cucumber again, you will now see it reporting that these steps exist but are not implemented:

$ bundle exec cucumber 
Feature: Search for Videos on YouTube

  Scenario: Search for Videos of Large Rodents
    Given I am on the YouTube home page
      TODO (Cucumber::Pending)
    When I search for "capybara"
    Then videos of large rodents are returned

1 scenario (1 pending)
3 steps (2 skipped, 1 pending)
0m0.003s

We now have enough code to bring Capybara into the picture. We will start off by adding the minimum amount of code needed to get started with the automation.

Ensure your env.rb file looks like the following:

require 'capybara/cucumber'

Capybara.default_driver = :selenium

We start by adding require 'capybara/cucumber'; this is all we need to load the necessary files.

Tip

On older versions of RubyGems you may need to add require 'rubygems' to your env.rb file and if using Bundler, you will also need to add require 'bundler/setup'.

We then need to tell Capybara to use the Selenium driver using:

Capybara.default_driver = :selenium

It is important to reiterate again that Capybara is simply acting as a translator and allows us to talk to any compatible driver. In this instance we use Selenium WebDriver because it is the most popular open source browser automation tool and allows us to test in a real browser, which is useful for our first ever web test.

If you don't set the driver, you may see an error like the following:

$ bin/cucumber 
Feature: Search for Videos on YouTube

  Scenario: Search for Videos of Large Rodents
    Given I am on the YouTube home page         
      rack-test requires a rack application, but none was given (ArgumentError)
    When I search for "capybara"
    Then videos of large rodents are returned

Failing Scenarios:
cucumber features/youtube_search.feature:3 # Scenario: Search for Videos of Large Rodents

1 scenario (1 failed)
3 steps (1 failed, 2 skipped)
0m0.178s

By default, Capybara assumes that you wish to test a Rack application. Rack is an ingenious piece of middleware used in both the Rails and Sinatra frameworks that allows full-stack testing of client/server interaction without the overhead of HTTP, thus making tests very fast. We will cover this in depth later in the book when we discuss how Capybara can be used to test Rails and Sinatra applications.

All that remains now is to fill in the step definitions with our Ruby code that will call the Capybara API to drive the test.

Ensure your steps.rb file looks like the following:

Given(/^I am on the YouTube home page$/) do
  visit 'http://www.youtube.com'
end

When(/^I search for "(.*?)"$/) do |search_term|
  fill_in 'search_query', :with => search_term
  click_on 'search-btn'
end

Then(/^videos of large rodents are returned$/) do
  page.should have_content 'Largest Rodent'
end

Before we dissect the code, let's run the test and see what happens. As always, run your test using the command cucumber.

Hopefully you see Firefox open, navigate to the YouTube home page and then search YouTube for videos of Capybara.

Congratulations! You have just successfully run your first full-stack test using Capybara.

Tip

The only issue I can see you might have here is if you don't have Firefox installed or you have it installed to a custom location and Selenium can't find the executable.

Let's briefly look at each step before we dive deep into Capybara's rich API. Here you will see how elegant Capybara's API is, as the code literally needs no explanation. Hopefully this demonstrates that when twinned with Cucumber we have a human-readable specification, which is automated by code that is very expressive. For anybody who has lived through using some of the commercially available test automation tools this should be a revelation!

The first line tells Capybara to inform the driver (Selenium WebDriver) to open a browser and navigate to a URL we provide as a string:

visit 'http://www.youtube.com'

Tip

Selenium WebDriver has built-in mechanisms to wait for page loads in the browser so we don't have to worry about any kind of page load check. Note that this does not include waiting for asynchronous JavaScript, for example, Ajax/XHTTP requests. Fortunately Capybara has this covered, as we will discover in due course.

After this we need to enter our search terms and click on the Search button. So we tell Capybara to get the driver to fill in the search form with our search terms. Again Capybara's API is helpful in telling us this.

#note the search_term variable is passed from the Cucumber scenario
fill_in 'search_query', :with => search_term
click_on 'search-btn'

The only source of confusion here might be the use of the string literal search_query in the fill_in method. A lot of Capybara's methods use a "best guess" strategy when you tell them to find something on the page. That is to say they look at various attributes on DOM elements to try to find the one you asked for. In this instance, we know the name attribute on the YouTube search form element is search_query so this is what we provided.

Finally we need to check if the results returned by the search were relevant. For this, we use Capybara's built-in RSpec magic matchers. If you don't know much about RSpec, there is plenty online (http://rspec.info/) but essentially the matchers provide semantically friendly ways of asserting the state of something is as you expect, with the difference to traditional assertions being that they raise exceptions when conditions are not met (as opposed to returning false).

   page.should have_content 'Largest Rodent'

Finally it is worth noting that the have_content matcher has a default wait built into it. This is useful because if the content we are waiting for happens to be loaded via asynchronous JavaScript (and not part of the initial page load), Capybara will retry for a configurable amount of time to see if it exists. We will cover strategies for handling asynchronous JavaScript in depth later.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

 

Summary


The aim of this chapter was to get you to a point where you have automated your first scenario using Capybara. We checked if you had Ruby and RubyGems available and installed Capybara and its dependencies as well as Cucumber as our test runner. Finally we implemented a simple scenario that automated a YouTube search; hopefully this has given you a glimpse of Capybara's elegant API, which we will be investigating in more detail in the next chapter.

About the Author

  • Matthew Robbins

    Matthew Robbins is an experienced developer in test, having spent many years wrestling with commercially available test automation tools. He has spent the last five years immersed in developing robust test automation frameworks using open source tools. He worked extensively with the BBC developing test automation frameworks and tools across their web platform and continues to work in the media industry for other high-profile broadcasters. Aside from test automation, he is passionate about becoming more productive in Vim and learning about web browser internals. He also regularly blogs at http://opensourcetester.co.uk.

    Browse publications by this author

Latest Reviews

(1 reviews total)
Was hoping there would be some coverage of mobile testing using Capybara. This pretty much gathers everything you can find on the internet and makes it conveniently located.
Book Title
Access this book, plus 7,500 other titles for FREE
Access now