So far, we have written test specifications to test Dave Haeffner's The-Internet, and we have set up the Gauge-Ruby environment.
Now, we need to set Capybara up to be integrated with the Gauge test framework.
Gemfile Setup
Gauge uses Bundler to handle its dependencies, installing various Ruby gems found in RubyGems.org. If you open up the Gemfile that was installed with the test project, you will see:
source 'https://rubygems.org'
gem 'test-unit', :group => [:development, :test]
gem 'gauge-ruby' , '~>0.5.1', :group => [:development, :test]
We will be adding the Ruby gems:
- Capybara: This Ruby gem handles all interaction with the browser. Visit new pages. Fill in text boxes. Click button. Within a certain area, expect pages to have content described. These are the human readable commands you can use to navigate and execute browser tests.
- Rspec: This behavior driven framework can be implemented by Capybara to give you a whole library to compare an expected value to an actual value.
- Selenium WebDriver: Capybara is a good testing framework for Ruby, but can't do everything. For all else, there is Selenium WebDriver.
This now gives us:
Gemfile
source "https://rubygems.org"
gem 'capybara', '~> 3.12'
gem 'gauge-ruby' , '~>0.5.1', :group => [:development, :test]
gem 'rspec', '~> 3.8'
gem 'selenium-webdriver', '~> 3.141'
Save the new file! Let's make sure to install of this on our local machine. With our Mac Terminal:
- bundle update
Spec Helper Setup
Within the step_implementations folder, we will be adding a Ruby file called a spec_helper. All step implementations will use this file to setup Capybara to interact with the browser.
We will be creating a new file, spec_helper.rb, by stealing some code...
GoCD, Gauge's answer to continuous integration, has a suite of Ruby Functional tests. Taking an assortment of code that initializes their tests. In our spec_helper file we will:
- Require for Bundler, the Bundler.setup.
- Require Capybara/DSL and Capybara/RSpec, including these libraries in a module DRIVER.
- Configure Gauge to include the DRIVER module we set up, along with the Screengrabber library, which will save screenshots on test failure. By default, they will be added to our tests.
- Configure Capybara to have a default wait time of a variable we can call timeout, which we can set to 20 seconds.
Here's what we have so far for spec_helper.rb:
require 'bundler'
require 'capybara/dsl'
require 'capybara/rspec'
Bundler.setup(:default)
Bundler.require
module DRIVER
include RSpec::Matchers
include Capybara::DSL
end
TIMEOUT = 20
There's No Place Like Chrome
For this sample project, let's focus just on getting the tests up and running on Chrome:
- Chrome as the default driver, Chrome as the current driver, with Chrome as the Javascript driver.
... But, according to recent browser metrics of this site, 80% of the people accessing this blog is using Chrome, with only 8% using Firefox. If you are focusing solely on functional tests in a browser, and not on visual testing, getting things working in just Chrome might be a good start.
spec_helper.rb
Capybara.default_driver = :chrome
Capybara.current_driver = :chrome
Capybara.javascript_driver = :chrome
Capybara Registration and Configuration
Gauge allows you to set up execution hooks, to run certain things to happen either before the suite runs or after the test suite runs. They are called before_suite and after_suite.
Let's have before_suite register the Chrome driver, open a new window, then set up for options for the window to be 1240 x 1400 pixels.
Let's add the default max wait time that we had declared earlier, and make sure to ignore any hidden elements, so we can only see what the user sees.
spec_helper.rb
before_suite do
Capybara.register_driver(:chrome) do |app|
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--window-size=1240,1400')
Capybara::Selenium::Driver.new(app,
browser: :chrome,
options: options)
end
end
Capybara.configure do |config|
config.default_max_wait_time = timeout
config.ignore_hidden_elements = true
end
Gauge Configuration
Remember the DRIVER module which included Capybara/DSL and RSpec? Let's make sure that Gauge can use that. Let's also have Gauge know to use Capybara's save_screenshot method for Screengrabber, to include it in the HTML reports when things go sour, saving it as a file, screenshot.png, in the /tmp directory.spec_helper.rb
Gauge.configure do |config|
config.include DRIVER
config.screengrabber = -> {
Capybara.page.save_screenshot('/tmp/screenshot.png')
return File.binread('/tmp/screenshot.png')
}
end
Write a Navigation Test Case
Under the specs folder, let's delete the example.spec that was installed as part of the sample project.Let's create a new file, Navigation.spec, and test that we can navigate to https://the-internet.herokuapp.com/login. As a verification step, let's make sure that the header is "Login Page".
The test script could look like this:
specs/Navigation/Navigation.spec
# Navigation: Go to The-Internet Login Page
## NAVIGATION: Visit The-Internet Confirming Login Page
* LOGIN: Visit the Login Page
* LOGIN: Verify the heading is "Login Page"
The first line is the Heading. That text will go into the HTML Report. It can be whatever you like.
The next line is the Scenario Heading. The text will also go into the HTML Report. It can be whatever you like.
The next two bullet points are the test steps to be executed. Gauge will take whatever text is listed here, and search for the corresponding code block in the step_implementation folder.
You can use whatever sequence of characters you want to describe the step, as long as it starts off with a bullet point. Personally, I like describing exactly what is happening, and what page the action is happening on.
Notice the "Login Page" in quotation marks? That is how Gauge makes tests dynamically driven. In my experience, labels are always, always changing, therefore I never want to bury them in the code itself, else I will keep having to change the code, again and again.
If the header changes from "Login Page" to, say, "Login", to update the framework all I would need to do is update the spec.
Hook Up Test Steps To Capybara
There are two steps we need to hook up in the step_implementation folder:- LOGIN: Visit the Login Page
- LOGIN: Verify the heading is "Login Page"
For the second step, let's store whatever we passed into the step method into a variable. Let's call it "page_header".
Capybara includes Rspec methods where we can can compare and contrast expected values with actual values found.
We could easily do: expect(page).to have_content("Login Page")
... But I want it to be more exact, checking out only the text in the H2 element of the Login page. I also want to the test to be more dynamic, to take whatever value we have indicated on the Navigation.spec in the SPECS section.
Since this all relates to the LOGIN page, let's name the file "login_spec.rb".
login_spec.rb
require_relative 'spec_helper'
APP_URL = 'https://the-internet.herokuapp.com/login'
LOGIN_HEADER = 'h2'
step 'LOGIN: Visit the Login Page' do
visit(APP_URL)
end
step 'LOGIN: Verify the heading is <page_header>' do |page_header|
expect(LOGIN_HEADER).to have_content(page_header)
end
Run The Tests
To run all of the tests in verbose mode, we can run on the Mac Terminal:- bundle exec gauge run specs -v
- bundle exec gauge run specs/Navigation.spec -v
- A browser opens up
- The first step is executed, visiting The-Internet Login page
- The second step is executed, checking that the header level 2 matches the spec, "Login Page"
- The browser closes.
# Navigation: Go to The-Internet Login Page
## NAVIGATION: Visit The-Internet Confirming Login Page
* LOGIN: Visit the Login Page ...[PASS]
* LOGIN: Verify the heading is "Login Page" ...[PASS]
If you go to reports -> html-report, you can open index.html in a browser, which shows what passed and what failed, automatically taking a screenshot.
Want to see an example of a failing test? In the Navigation.spec, search for "Secure Area" instead of "Login Page", and the test will fail.
Next, let's alter the spec_helper file to allow Chrome to be run in headless mode!
Happy Testing!
Basic Capybara-Gauge:
- Part One: Analyzing The-Internet
- Part Two: Setup Ruby Environment
- Part Three: Setup Capybara to Test Opening Chrome
- Part Four: Add Option For Chrome Headless
- Part Five: Add Test Steps and Spec Implementations
- Part Six: Setup Chrome and ChromeDriver Logging
- Part Seven: Rubocop Code Review
- Source Code: https://github.com/tjmaher/capybara-gauge
-T.J. Maher
Sr. QA Engineer, Software Engineer in Test
Meetup Organizer, Ministry of Testing - Boston
Twitter | YouTube | LinkedIn | Articles
1 comment:
Great post on how to configure Capybara with Chrome I hope! Meta Refresh values are usually not very high because it’s always a struggle to get the browser settings to an optimal state. I must say that I really liked this tutorial to guarantee continuity. Anyway, when searching for the setups in the tech industry, he was able to find information on where one can buy cheap dissertations might come in handy for people who work simultaneously on multiple projects. I guess this is the best demo I’ve ever seen, you did a great job of explaining it.
Post a Comment