Quick project creation with TestGen and setup for Capybara

Gems: testgen, capybara (instead of watir and pure selenium), cucumber, rspec, site_prism (instead of pageobject), factory_girl and faker (for test data).

There is a simple example how to create project, how to setup it for capybara and site_prism and how to write first test.

1 Install TestGen gem:

gem install testgen

2 Create new project with selenium: testgen project project_name –pageobject-driver=selenium

testgen project example_testgen --pageobject-driver=selenium

This creates the simple project structure:

create  example_testgen
create  example_testgen/cucumber.yml
create  example_testgen/Gemfile
create  example_testgen/Rakefile
create  example_testgen/features
create  example_testgen/features/support
create  example_testgen/features/step_definitions
create  example_testgen/features/support/env.rb
create  example_testgen/features/support/hooks.rb
create  example_testgen/features/support/pages

Pay attention to:

hooks.rb — to specify actions before and after scenario

cucumber.yml — settings (base url, default browser, reports and rerun etc)

env.rb — the heart of cucumber project

features/ — for feature files, step definitions and support files (env.rb, hooks.rb) and pages

3 Delete all from hooks.rb because we are going to use Capybara instead of Selenium. Delete Rakefile.

4 Edit Gemfile, add new gems and install them with bundler

Before:

source 'https://rubygems.org'

gem 'cucumber'
gem 'rspec'
gem 'rake'
gem 'page-object'

After:

source 'https://rubygems.org'

gem 'cucumber'
gem 'rspec'
gem 'site_prism'
gem 'capybara'
gem 'factory_girl'
gem 'faker'

5 Create features/support/factories/user.rb. This is for generating random user credentials.

FactoryGirl.define do

  factory :user, class: OpenStruct do
    Faker::Config.locale = :en
    first_name Faker::Name.first_name
    last_name Faker::Name.last_name
    email  "nn24086+#{Time.now.to_i}@gmail.com"
    password Faker::Internet.password(min_length = 6)
  end

  factory :user_blank_name, class: OpenStruct, parent: :user  do
    first_name ''
  end

  factory :user_blank_email, class: OpenStruct, parent: :user  do
    email ''
  end

  factory :user_invalid_email, class: OpenStruct, parent: :user  do
    email 'nn24086gmail.com'
  end

  factory :user_blank_password, class: OpenStruct, parent: :user  do
    password ''
  end

  factory :user_week_password, class: OpenStruct, parent: :user  do
    password Faker::Internet.password(max_length = 5)
  end

end

6 Create boot.rb file in the project root to not write ‘require_relative’ for every file from support/pages(factories).

Dir.chdir(File.join(File.dirname(__FILE__), '.'))

Dir[File.join(File.dirname(__FILE__), './pages/**/*.rb')].each { |f| require f }
Dir[File.join(File.dirname(__FILE__), './factories/**/*.rb')].each { |f| require f }

8 Edit env.rb:

Before:

require 'rspec'
require 'page-object'

World(PageObject::PageFactory)

Add gems:

require 'rspec'
require 'site_prism'
require 'capybara'
require 'capybara/cucumber'
require 'capybara/dsl'
require 'capybara/rspec/matchers'
require 'factory_girl'
require 'faker'
require_relative '../../boot'
World(Capybara::DSL)
World(Capybara::RSpecMatchers)
include FactoryGirl::Syntax::Methods

Add Capybara with Chrome as default browser:

Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

But it is better to get information about browser from cucumber.yml. And about base url too. So continue editing env.rb:

Capybara.register_driver ENV['BROWSER'].to_sym do |app|
  Capybara::Selenium::Driver.new(app, :browser => ENV['BROWSER'].to_sym)
end

Capybara.configure do |config|
  config.run_server = false
  config.app_host   = ENV['TEST_HOSTNAME']
  config.default_driver = ENV['BROWSER'].to_sym
  config.default_driver = ENV['BROWSER'].to_sym
end

Add this line to maximize browser window:

Capybara.page.driver.browser.manage.window.maximize

9 Now edit cucumber.yml:

default: TEST_HOSTNAME=http://www.dropbox.com BROWSER=chrome --no-source --color --format pretty --profile html_report --profile rerun
html_report: --format progress --format html --out=report.html
rerun: -f rerun --out rerun.txt

10 Create feature file: features/sign_up.feature

Feature: Dropbox sign up
  In order to use dropbox
  As a registered user
  I need to sign up

  Background:
    Given I am on the Dropbox sign up page

  Scenario: Sign up with valid credentials
    Given I have valid credentials
    When I fill the sign up form and submit
    Then account should be created

  Scenario: Sign up with blank name
    Given I have credentials without first name
    When I fill the sign up form and submit
    Then I should see error notification "Please enter your first name"
    And account should not be created

11 Describe page with site prism: features/support/pages/sign_up_page.rb

class SignUpPage < SitePrism::Page
  set_url "/register"
  set_url_matcher /dropbox.com\/register/

  element :first_name, 'input[name="fname"]'
  element :last_name, 'input[name="lname"]'
  element :email, 'input[name="email"]'
  element :password, 'input[name="password"]'
  element :agreement, 'input[name="tos_agree"]'
  element :create_account, 'form:first-of-type > button[class*="login"]'
  element :error_message, 'span[class="error-message"]'

  def fill_form_with(user)
    first_name.set user.first_name
    last_name.set user.last_name
    email.set user.email
    password.set user.password
  end

  def set_agreement_checkbox
    agreement.click
  end

  def submit_form
    create_account.click
  end

  def error_message_text
    error_message.text
  end
end

12 Create step definitions: features/step_definitions/sign_up_steps.rb

Given(/^I am on the Dropbox sign up page$/) do
  @sign_up_page = SignUpPage.new
  @sign_up_page.load
end

Given(/^I have valid credentials$/) do
  @user = FactoryGirl.create :user
end

Given(/^I have credentials without first name$/) do
  @user = FactoryGirl.create :user_blank_name
end

When(/^I fill the sign up form and submit$/) do
  @sign_up_page.fill_form_with(@user)
  @sign_up_page.set_agreement_checkbox
  @sign_up_page.submit_form
end

Then(/^account should be created$/) do
  pending # Write code here that turns the phrase above into concrete actions
end
Then(/^account should not be created$/) do
  pending # Write code here that turns the phrase above into concrete actions
end

Then(/^I should see error notification "([^"]*)"$/) do |text|
  expect(@sign_up_page).to have_error_message
  expect(@sign_up_page.error_message_text).to include text
end

13 Run features with cucumber:

cucumber

And the output:

Using the default, html_report and rerun profiles...
Feature: Dropbox sign up
  In order to use dropbox
  As a registered user
  I need to sign up

  Background: 
    Given I am on the Dropbox sign up page

  Scenario: Sign up with valid credentials
    Given I have valid credentials
    When I fill the sign up form and submit
    Then account should be created
      TODO (Cucumber::Pending)
      ./features/step_definitions/sign_up_steps.rb:21:in `/^account should be created$/'
      features/sign_up.feature:12:in `Then account should be created'

  Scenario: Sign up with blank name
    Given I have credentials without first name
    When I fill the sign up form and submit
    Then I should see error notification "Please enter your first name"
    And account should not be created
      TODO (Cucumber::Pending)
      ./features/step_definitions/sign_up_steps.rb:24:in `/^account should not be created$/'
      features/sign_up.feature:18:in `And account should not be created'

2 scenarios (2 pending)
9 steps (2 pending, 7 passed)
0m13.827s

Report — report.html

File with failed tests for quick rerun with ‘cucumber @rerun.txt’ (I hope it is empty) — rerun.txt