#102 Feature Testing with Capybara

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

Summary

Gemfilegroup :test do
  gem 'simplecov', require: false
  gem 'capybara'
  gem 'selenium-webdriver'
end
rails_helper.rbrequire '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.rbrequire '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: '[email protected]'
      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: '[email protected]')
      visit edit_user_path(user)
      within("form") do
        fill_in 'First name', with: 'Jane'
        fill_in 'Email', with: '[email protected]'
      end
      click_button 'Update User'
      expect(page).to have_content 'User was successfully updated.'
      expect(page).to have_content '[email protected]'
    end

    scenario "should fail" do
      user = User.create(first_name: 'John', last_name: 'Doe', email: '[email protected]')
      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: '[email protected]')
      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
marklar PRO said almost 2 years ago on Feature Testing with Capybara :

Thanks for the great episode. I know you mentioned that once you've got it all set up it is quite similar to doing system tests (as system tests use Capybara) but are there any plans for an episode on getting set up with system tests, differences between what was implemented in this video (feature tests), and best practices?

marklar PRO said almost 2 years ago on Feature Testing with Capybara :

I just realised that episode 100 covers the difference between feature tests and system tests.

oalbacha said 7 months ago on Feature Testing with Capybara :

thanks for this episode, very helpful!

However, I have the following code:
html erb

<%= form_tag restaurant_update_staff_names_path(current_restaurant), { role: "form", method: :patch, remote: true } do %>
<table class="table table-striped taker-table">
<thead>
<tr>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody class="taker-table">
<% if @staff_names.present? %>
<% @staff_names.each do |taker| %>
<tr class="reservation-taker-row">
<td>
<%= text_field_tag "restaurant[staff_names][][name]", taker["name"], class: "form-control taker-name-input col-lg-6", placeholder: 'reservation taker name' %>
<%= number_field_tag "restaurant[staff_names][][pin]", taker["pin"], in: 1.0..9999.0, class: "form-control taker-pin-input col-lg-6", placeholder: 'pin code' %>
</td>
<td>
<%= link_to "-", "#", {class: "delete-taker delete-btn"} %>
</td>
</tr>
<% end %>
<% else %>
<tr class="reservation-taker-row">
<td>
<%= text_field_tag "restaurant[staff_names][][name]", nil, class: "form-control taker-name-inpu col-lg-6", placeholder: 'reservation taker name' %>
<%= number_field_tag "restaurant[staff_names][][pin]", nil, in: 1.0..9999.0, class: "form-control taker-pin-input col-lg-6", placeholder: 'pin code' %>
</td>
<td>
<%= link_to "-", "#", {class: "delete-taker delete-btn"} %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to "Add Taker", "#", class: "btn btn-default btn-lg add-taker-button" %>
<div class="pull-right">
<ul class="list-inline">
<li><%= link_to "Cancel", restaurant_users_path, class: "btn btn-default btn-lg" %></li>
<li><%= submit_tag 'Save Reservation Takers', { class: 'btn btn-success btn-lg btn btn-success'} %></li>
</ul>
</div>
<% end %>

spec

it "allows deleting of existing reservation takers" do
restaurant = create(:restaurant, staff_names: [{"name"=>"Marc Jeffrey", "pin"=>""}])
visit restaurant_users_path
fill_in "restaurant[staff_names][][name]", match: :first, with: "Nezar Khadem"
click_on "Save Reservation Takers"
within(first("td a.delete-taker")) do
click_link('-')
expect(page).not_to have_css("a.delete-taker", text: "-")
end
end
end

the view looks like this:

How can I test the deleting of the user?

Login to Comment