Feature Testing with Capybara

Episode #102 by Teacher's Avatar David Kimura

Summary

Create Acceptance Tests or Feature Tests to extend your automated tests with browser testing. It can help tests some areas that cannot be reached with other types of tests.
rails test 14:40

Resources

Summary

# Gemfile
group :test do
  gem 'simplecov', require: false
  gem 'capybara'
  gem 'selenium-webdriver'
end

# rails_helper.rb
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'capybara/rspec'
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
end

# brew install geckodriver
# brew services start geckodriver
# Capybara.default_driver = :selenium

# brew install chromedriver
# brew services start chromedriver
# Capybara.default_driver = :selenium_chrome
Capybara.default_driver = :selenium_chrome_headless

# users_spec.rb
require 'rails_helper'

RSpec.feature "User Features", type: :feature do
  context 'create new user' do 
    before(:each) do
      visit '/users/new'
      within("form") do
        fill_in 'First name', with: 'john'
        fill_in 'Last name', with: 'doe'
      end
    end

    scenario "should be successful" do
      within("form") do
        fill_in 'Email', with: 'john.doe@example.com'
      end
      click_button 'Create User'
      expect(page).to have_content 'User was successfully created.'
    end

    scenario "should fail" do
      click_button 'Create User'
      expect(page).to have_content 'Email can\'t be blank'
    end
  end

  context 'update user' do 
    scenario "should be successful" do
      user = User.create(first_name: 'John', last_name: 'Doe', email: 'john.doe@example.com')
      visit edit_user_path(user)
      within("form") do
        fill_in 'First name', with: 'Jane'
        fill_in 'Email', with: 'jane.doe@example.com'
      end
      click_button 'Update User'
      expect(page).to have_content 'User was successfully updated.'
      expect(page).to have_content 'jane.doe@example.com'
    end

    scenario "should fail" do
      user = User.create(first_name: 'John', last_name: 'Doe', email: 'john.doe@example.com')
      visit edit_user_path(user)
      within("form") do
        fill_in 'First name', with: ''
      end
      click_button 'Update User'
      expect(page).to have_content 'First name can\'t be blank'
    end
  end


  context 'destroy user' do 
    scenario "should be successful" do
      user = User.create(first_name: 'John', last_name: 'Doe', email: 'john.doe@example.com')
      visit users_path
      # expect { click_link 'Destroy' }.to change(User, :count).by(-1)
      accept_confirm do
        click_link 'Destroy'
      end
      expect(page).to have_content 'User was successfully destroyed.'
    end
  end
end