Created
April 17, 2014 21:18
-
-
Save esmerino/11012237 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSPEC | |
gem 'rspec-rails', group: [:development, :test] | |
gem 'capybara', group: [:test] | |
gem 'factory_girl_rails', group: [:test] | |
gem 'faker', group: [:test] | |
#Expectations for RSpec | |
https://github.com/rspec/rspec-expectations | |
#You can chain the two rake tasks together on your command line with | |
rake db:migrate db:test:clone | |
#Introdution | |
" | |
• Tests should be reliable. | |
• Tests should be easy to write. | |
• Tests should be easy to understand. | |
" | |
#Model specs | |
" | |
• First we’ll create a model spec for an existing model–in our case, the actual Contact model. | |
• Then, we’ll write passing tests for a model’s validations, class, and instance methods, and | |
organize our spec in the process. | |
" | |
##Anatomy of a model spec | |
" | |
• The model’s create method, when passed valid attributes, should be valid. | |
• Data that fail validations should not be valid. | |
• Class and instance methods perform as expected. | |
" | |
##Testing validations | |
describe Contact do | |
it "is invalid without a firstname" do | |
expect(Contact.new(firstname: nil)).to have(1).errors_on(:firstname) | |
end | |
it "is invalid with a duplicate email address" do | |
Contact.create( | |
firstname: 'Joe', lastname: 'Tester', | |
email: '[email protected]') | |
contact = Contact.new( | |
firstname: 'Jane', lastname: 'Tester', | |
email: '[email protected]') | |
expect(contact).to have(1).errors_on(:email) | |
end | |
end | |
app/models/phone.rb | |
validates :phone, uniqueness: { scope: :contact_id } | |
describe Phone do | |
it "does not allow duplicate phone numbers per contact" do | |
contact = Contact.create(firstname: 'Joe', lastname: 'Tester', | |
email: '[email protected]') | |
contact.phones.create(phone_type: 'home', | |
phone: '785-555-1234') | |
mobile_phone = contact.phones.build(phone_type: 'mobile', | |
phone: '785-555-1234') | |
expect(mobile_phone).to have(1).errors_on(:phone) | |
end | |
it "allows two contacts to share a phone number" do | |
contact = Contact.create(firstname: 'Joe', lastname: 'Tester', | |
email: '[email protected]') | |
contact.phones.create(phone_type: 'home', | |
phone: '785-555-1234') | |
other_contact = Contact.new | |
other_phone = other_contact.phones.build(phone_type: | |
'home', phone: '785-555-1234') | |
expect(other_phone).to be_valid | |
end | |
end | |
##Testing instance methods | |
app/models/contact.rb | |
def name | |
[firstname, lastname].join(' ') | |
end | |
describe Contact do | |
it "returns a contact's full name as a string" do | |
contact = Contact.new(firstname: 'John', lastname: 'Doe', | |
email: '[email protected]') | |
expect(contact.name).to eq 'John Doe' | |
end | |
end | |
## Testing class methods and scopes | |
app/models/contact.rb | |
def self.by_letter(letter) | |
where("lastname LIKE ?", "#{letter}%").order(:lastname) | |
end | |
describe Contact do | |
it "returns a sorted array of results that match" do | |
smith = Contact.create(firstname: 'John', lastname: 'Smith', | |
email: '[email protected]') | |
jones = Contact.create(firstname: 'Tim', lastname: 'Jones', | |
email: '[email protected]') | |
johnson = Contact.create(firstname: 'John', lastname: 'Johnson', | |
email: '[email protected]') | |
expect(Contact.by_letter("J")).to eq [johnson, jones] | |
end | |
end | |
#DRYer specs with describe, context, before and after | |
spec/models/contact_spec.rb | |
require 'spec_helper' | |
describe Contact do | |
describe "filter last name by letter" do | |
end | |
end | |
spec/models/contact_spec.rb | |
require 'spec_helper' | |
describe Contact do | |
describe "filter last name by letter" do | |
context "matching letters" do | |
end | |
context "non-matching letters" do | |
end | |
end | |
end | |
spec/models/contact_spec.rb | |
require 'spec_helper' | |
describe Contact do | |
describe "filter last name by letter" do | |
before :each do | |
@smith = Contact.create(firstname: 'John', lastname: 'Smith', | |
email: '[email protected]') | |
@jones = Contact.create(firstname: 'Tim', lastname: 'Jones', | |
email: '[email protected]') | |
@johnson = Contact.create(firstname: 'John', lastname: 'Johnson', | |
email: '[email protected]') | |
end | |
context "matching letters" do | |
end | |
context "non-matching letters" do | |
end | |
end | |
end | |
##### Code | |
spec/models/contact_spec.rb | |
require 'spec_helper' | |
describe Contact do | |
it "is valid with a firstname, lastname and email" do | |
contact = Contact.new( | |
firstname: 'Aaron', | |
lastname: 'Sumner', | |
email: '[email protected]') | |
expect(contact).to be_valid | |
end | |
it "is invalid without a firstname" do | |
expect(Contact.new(firstname: nil)).to have(1).errors_on(:firstname) | |
end | |
it "is invalid without a lastname" do | |
expect(Contact.new(lastname: nil)).to have(1).errors_on(:lastname) | |
end | |
it "is invalid without an email address" do | |
expect(Contact.new(email: nil)).to have(1).errors_on(:email) | |
end | |
it "is invalid with a duplicate email address" do | |
Contact.create( | |
firstname: 'Joe', lastname: 'Tester', | |
email: '[email protected]') | |
contact = Contact.new( | |
firstname: 'Jane', lastname: 'Tester', | |
email: '[email protected]') | |
expect(contact).to have(1).errors_on(:email) | |
end | |
it "returns a contact's full name as a string" do | |
contact = Contact.new(firstname: 'John', lastname: 'Doe', | |
email: '[email protected]') | |
expect(contact.name).to eq 'John Doe' | |
end | |
describe "filter last name by letter" do | |
before :each do | |
@smith = Contact.create(firstname: 'John', lastname: 'Smith', | |
email: '[email protected]') | |
@jones = Contact.create(firstname: 'Tim', lastname: 'Jones', | |
email: '[email protected]') | |
@johnson = Contact.create(firstname: 'John', lastname: 'Johnson', | |
email:'[email protected]') | |
end | |
context "matching letters" do | |
it "returns a sorted array of results that match" do | |
expect(Contact.by_letter("J")).to eq [@johnson, @jones] | |
end | |
end | |
context "non-matching letters" do | |
it "returns a sorted array of results that match" do | |
expect(Contact.by_letter("J")).to_not include @smith | |
end | |
end | |
end | |
end | |
##### | |
### Generating test data with factories | |
" | |
Enter factories: Simple, flexible, building blocks for test data. If I had to point to a single | |
component that helped me see the light toward testing more than anything else, it would | |
be Factory Girl18, an easy-to-use and easy-to-rely-on gem for creating test data without the | |
brittleness of fixtures. | |
" | |
spec/factories/contacts.rb | |
FactoryGirl.define do | |
factory :contact do | |
firstname "John" | |
lastname "Doe" | |
sequence(:email) { |n| "johndoe#{n}@example.com"} | |
end | |
end | |
spec/models/contact_spec.rb | |
it "is invalid without a firstname" do | |
contact = FactoryGirl.build(:contact, firstname: nil) | |
expect(contact).to have(1).errors_on(:firstname) | |
end | |
it "is invalid without a lastname" do | |
contact = FactoryGirl.build(:contact, lastname: nil) | |
expect(contact).to have(1).errors_on(:lastname) | |
end | |
it "is invalid without an email address" do | |
contact = FactoryGirl.build(:contact, email: nil) | |
expect(contact).to have(1).errors_on(:email) | |
end | |
it "returns a contact's full name as a string" do | |
contact = FactoryGirl.build(:contact, | |
firstname: "Jane", lastname: "Doe") | |
expect(contact.name).to eq "Jane Doe" | |
end | |
it "is invalid with a duplicate email address" do | |
FactoryGirl.create(:contact, email: "[email protected]") | |
contact = FactoryGirl.build(:contact, email: "[email protected]") | |
expect(contact).to have(1).errors_on(:email) | |
end | |
#Simplifying our syntax | |
spec/spec_helper.rb | |
RSpec.configure do |config| | |
config.include FactoryGirl::Syntax::Methods | |
end | |
require 'spec_helper' | |
describe Contact do | |
it "has a valid factory" do | |
expect(build(:contact)).to be_valid | |
end | |
it "is invalid without a firstname" do | |
expect(build(:contact, firstname: nil)).to \ | |
have(1).errors_on(:firstname) | |
end | |
it "is invalid without a lastname" do | |
expect(build(:contact, lastname: nil)).to \ | |
have(1).errors_on(:lastname) | |
end | |
end | |
# Associations and inheritance in factories | |
spec/factories/phones.rb | |
FactoryGirl.define do | |
factory :phone do | |
association :contact | |
phone { '123-555-1234' } | |
phone_type 'home' | |
end | |
end | |
spec/models/phone_spec.rb | |
it "allows two contacts to share a phone number" do | |
create(:phone, | |
phone_type: 'home', | |
phone: "785-555-1234") | |
expect(build(:phone, | |
phone_type: 'home', | |
phone: "785-555-1234")).to be_valid | |
end | |
spec/factories/phones.rb | |
FactoryGirl.define do | |
factory :phone do | |
association :contact | |
phone { '123-555-1234' } | |
factory :home_phone do | |
phone_type 'home' | |
end | |
factory :work_phone do | |
phone_type 'work' | |
end | |
factory :mobile_phone do | |
phone_type 'mobile' | |
end | |
end | |
end | |
spec/models/phone_spec.rb | |
require 'spec_helper' | |
describe Phone do | |
it "does not allow duplicate phone numbers per contact" do | |
contact = create(:contact) | |
create(:home_phone, | |
contact: contact, | |
phone: '785-555-1234') | |
mobile_phone = build(:mobile_phone, | |
contact: contact, | |
phone: '785-555-1234') | |
expect(mobile_phone).to have(1).errors_on(:phone) | |
end | |
it "allows two contacts to share a phone number" do | |
create(:home_phone, | |
phone: "785-555-1234") | |
expect(build(:home_phone, phone: "785-555-1234")).to be_valid | |
end | |
end | |
#Generating more realistic fake data | |
spec/factories/contacts.rb | |
require 'faker' | |
FactoryGirl.define do | |
factory :contact do | |
firstname { Faker::Name.first_name } | |
lastname { Faker::Name.last_name } | |
email { Faker::Internet.email } | |
end | |
end | |
#Advanced associations | |
spec/factories/contacts.rb | |
require 'faker' | |
FactoryGirl.define do | |
factory :contact do | |
firstname { Faker::Name.first_name } | |
lastname { Faker::Name.last_name } | |
email { Faker::Internet.email } | |
after(:build) do |contact| | |
[:home_phone, :work_phone, :mobile_phone].each do |phone| | |
contact.phones << FactoryGirl.build(:phone, | |
phone_type: phone, contact: contact) | |
end | |
end | |
end | |
end | |
spec/models/contact_spec.rb | |
it "has three phone numbers" do | |
expect(create(:contact).phones.count).to eq 3 | |
end | |
## Basic controller specs | |
" | |
.First, we’ll discuss why you should test controllers at all. | |
.We’ll follow that discussion with the very basics (or, controller specs are just unit specs). | |
.Next we’ll begin organizing controller specs in an outline-like format. | |
.We’ll then use factories to set up data for specs. | |
.Then we’ll test the seven CRUD methods included in most controllers, along with a non-CRUD example. | |
.Next, we’ll look at testing nested routes. | |
.We’ll wrap up with testing a controller method with non-HTML output, such as a file export. | |
" | |
# Setting up test data | |
spec/factories/contacts.rb | |
require 'faker' | |
FactoryGirl.define do | |
factory :contact do | |
firstname { Faker::Name.first_name } | |
lastname { Faker::Name.last_name } | |
email { Faker::Internet.email } | |
after(:build) do |contact| | |
[:home_phone, :work_phone, :mobile_phone].each do |phone| | |
contact.phones << FactoryGirl.build(:phone, | |
phone_type: phone, contact: contact) | |
end | |
end | |
factory :invalid_contact do | |
firstname nil | |
end | |
end | |
end | |
# Testing GET requests | |
spec/controllers/contacts_controller_spec.rb | |
describe 'GET #show' do | |
it "assigns the requested contact to @contact" do | |
contact = create(:contact) | |
get :show, id: contact | |
expect(assigns(:contact)).to eq contact | |
end | |
it "renders the :show template" do | |
contact = create(:contact) | |
get :show, id: contact | |
expect(response).to render_template :show | |
end | |
end | |
" | |
• The basic DSL for interacting with controller methods: Each HTTP verb has its own | |
method (in these cases, get), which expects the controller method name as a symbol (here, | |
:show), followed by any params (id: contact). | |
• Variables instantiated by the controller method can be evaluated using assigns(:variable_- | |
name). | |
• The finished product returned from the controller method can be evaluated through | |
response. | |
" | |
spec/controllers/contacts_controller_spec.rb | |
describe 'GET #index' do | |
context 'with params[:letter]' do | |
it "populates an array of contacts starting with the letter" do | |
smith = create(:contact, lastname: 'Smith') | |
jones = create(:contact, lastname: 'Jones') | |
get :index, letter: 'S' | |
expect(assigns(:contacts)).to match_array([smith]) | |
end | |
it "renders the :index template" do | |
get :index, letter: 'S' | |
expect(response).to render_template :index | |
end | |
end | |
context 'without params[:letter]' do | |
it "populates an array of all contacts" do | |
smith = create(:contact, lastname: 'Smith') | |
jones = create(:contact, lastname: 'Jones') | |
get :index | |
expect(assigns(:contacts)).to match_array([smith, jones]) | |
end | |
it "renders the :index template" do | |
get :index | |
expect(response).to render_template :index | |
end | |
end | |
end | |
spec/controllers/contacts_controller_spec.rb | |
describe 'GET #new' do | |
it "assigns a new Contact to @contact" do | |
get :new | |
expect(assigns(:contact)).to be_a_new(Contact) | |
end | |
it "renders the :new template" do | |
get :new | |
expect(response).to render_template :new | |
end | |
end | |
describe 'GET #edit' do | |
it "assigns the requested contact to @contact" do | |
contact = create(:contact) | |
get :edit, id: contact | |
expect(assigns(:contact)).to eq contact | |
end | |
it "renders the :edit template" do | |
contact = create(:contact) | |
get :edit, id: contact | |
expect(response).to render_template :edit | |
end | |
end | |
# Testing POST requests | |
it "does something upon post#create" do | |
post :create, contact: attributes_for(:contact) | |
end | |
spec/controllers/contacts_controller_spec.rb | |
describe "POST #create" do | |
before :each do | |
@phones = [ | |
attributes_for(:phone), | |
attributes_for(:phone), | |
attributes_for(:phone) | |
] | |
end | |
context "with valid attributes" do | |
it "saves the new contact in the database" do | |
expect{ | |
post :create, contact: attributes_for(:contact, | |
phones_attributes: @phones) | |
}.to change(Contact, :count).by(1) | |
end | |
it "redirects to contacts#show" do | |
post :create, contact: attributes_for(:contact, | |
phones_attributes: @phones) | |
expect(response).to redirect_to contact_path(assigns[:contact]) | |
end | |
end | |
end | |
end | |
spec/controllers/contacts_controller_spec.rb | |
context "with invalid attributes" do | |
it "does not save the new contact in the database" do | |
expect{ | |
post :create, | |
contact: attributes_for(:invalid_contact) | |
}.to_not change(Contact, :count) | |
end | |
it "re-renders the :new template" do | |
post :create, | |
contact: attributes_for(:invalid_contact) | |
expect(response).to render_template :new | |
end | |
end | |
end | |
# Testing PATCH requests | |
spec/controllers/contacts_controller_spec.rb | |
describe 'PATCH #update' do | |
before :each do | |
@contact = create(:contact, | |
firstname: 'Lawrence', lastname: 'Smith') | |
end | |
context "valid attributes" do | |
it "locates the requested @contact" do | |
patch :update, id: @contact, contact: attributes_for(:contact) | |
expect(assigns(:contact)).to eq(@contact) | |
end | |
it "changes @contact's attributes" do | |
patch :update, id: @contact, | |
contact: attributes_for(:contact, | |
firstname: "Larry", lastname: "Smith") | |
@contact.reload | |
expect(@contact.firstname).to eq("Larry") | |
expect(@contact.lastname).to eq("Smith") | |
end | |
it "redirects to the updated contact" do | |
patch :update, id: @contact, contact: attributes_for(:contact) | |
expect(response).to redirect_to @contact | |
end | |
end | |
end | |
spec/controllers/contacts_controller_spec.rb | |
describe 'PATCH #update' do | |
context "with invalid attributes" do | |
it "does not change the contact's attributes" do | |
patch :update, id: @contact, | |
contact: attributes_for(:contact, | |
firstname: "Larry", lastname: nil) | |
@contact.reload | |
expect(@contact.firstname).to_not eq("Larry") | |
expect(@contact.lastname).to eq("Smith") | |
end | |
it "re-renders the edit template" do | |
patch :update, id: @contact, | |
contact: attributes_for(:invalid_contact) | |
expect(response).to render_template :edit | |
end | |
end | |
end | |
# Testing DELETE requests | |
spec/controllers/contacts_controller_spec.rb | |
describe 'DELETE #destroy' do | |
before :each do | |
@contact = create(:contact) | |
end | |
it "deletes the contact" do | |
expect{ delete :destroy, id: @contact}.to change(Contact,:count).by(-1) | |
end | |
it "redirects to contacts#index" do | |
delete :destroy, id: @contact | |
expect(response).to redirect_to contacts_url | |
end | |
end | |
# Testing non-CRUD methods | |
describe "PATCH hide_contact" do | |
before :each do | |
@contact = create(:contact) | |
end | |
it "marks the contact as hidden" do | |
patch :hide_contact, id: @contact | |
expect(@contact.reload.hidden?).to be_true | |
end | |
it "redirects to contacts#index" do | |
patch :hide_contact, id: @contact | |
expect(response).to redirect_to contacts_url | |
end | |
end | |
# Testing nested routes | |
config/routes.rb | |
resources :contacts do | |
resources :phones | |
end | |
describe 'GET #show' do | |
it "renders the :show template for the phone" do | |
contact = create(:contact) | |
phone = create(:phone, contact: contact) | |
get :show, id: phone, contact_id: contact.id | |
expect(response).to render_template :show | |
end | |
end | |
# Testing non-HTML controller output | |
link_to 'Export', contacts_path(format: :csv) | |
def index | |
@contacts = Contact.all | |
respond_to do |format| | |
format.html | |
format.csv do | |
send_data Contact.to_csv(@contacts), | |
type: 'text/csv; charset=iso-8859-1; header=present', | |
disposition: 'attachment; filename=contacts.csv' | |
end | |
end | |
end | |
describe 'CSV output' do | |
it "returns a CSV file" do | |
get :index, format: :csv | |
expect(response.headers['Content-Type']).to have_content 'text/csv' | |
end | |
it 'returns content' do | |
create(:contact, | |
firstname: 'Aaron', | |
lastname: 'Sumner', | |
email: '[email protected]') | |
get :index, format: :csv | |
expect(response.body).to have_content 'Aaron Sumner,[email protected]' | |
end | |
end | |
it "returns comma separated values" do | |
create(:contact, | |
firstname: 'Aaron', | |
lastname: 'Sumner', | |
email: '[email protected]') | |
expect(Contact.to_csv).to match /Aaron Sumner,[email protected]/ | |
end | |
it "returns JSON-formatted content" do | |
contact = create(:contact) | |
get :index, format: :json | |
expect(response.body).to have_content contact.to_json | |
end | |
# Advanced controller specs | |
spec/factories/users.rb | |
require 'faker' | |
FactoryGirl.define do | |
factory :user do | |
email { Faker::Internet.email } | |
password 'secret' | |
password_confirmation 'secret' | |
factory :admin do | |
admin true | |
end | |
end | |
end | |
spec/controllers/contacts_controller_spec.rb | |
describe "administrator access" do | |
before :each do | |
user = create(:admin) | |
session[:user_id] = user.id | |
end | |
describe 'GET #index' do | |
it "populates an array of contacts" do | |
get :index | |
expect(assigns(:contacts)).to match_array [@contact] | |
end | |
it "renders the :index template" do | |
get :index | |
expect(response).to render_template :index | |
end | |
end | |
describe 'GET #show' do | |
it "assigns the requested contact to @contact" do | |
get :show, id: @contact | |
expect(assigns(:contact)).to eq @contact | |
end | |
it "renders the :show template" do | |
get :show, id: @contact | |
expect(response).to render_template :show | |
end | |
end | |
end | |
# Testing the guest role | |
spec/controllers/contacts_controller_spec.rb | |
describe "guest access" do | |
describe 'GET #new' do | |
it "requires login" do | |
get :new | |
expect(response).to redirect_to login_url | |
end | |
end | |
describe 'GET #edit' do | |
it "requires login" do | |
contact = create(:contact) | |
get :edit, id: contact | |
expect(response).to redirect_to login_url | |
end | |
end | |
describe "POST #create" do | |
it "requires login" do | |
post :create, id: create(:contact), | |
contact: attributes_for(:contact) | |
expect(response).to redirect_to login_url | |
end | |
end | |
describe 'PUT #update' do | |
it "requires login" do | |
put :update, id: create(:contact), | |
contact: attributes_for(:contact) | |
expect(response).to redirect_to login_url | |
end | |
end | |
describe 'DELETE #destroy' do | |
it "requires login" do | |
delete :destroy, id: create(:contact) | |
expect(response).to redirect_to login_url | |
end | |
end | |
end | |
# Testing a given role’s authorization | |
spec/controllers/users_controller_spec.rb | |
describe 'user access' do | |
before :each do | |
@user = create(:user) | |
session[:user_id] = @user.id | |
end | |
describe 'GET #index' do | |
it "collects users into @users" do | |
user = create(:user) | |
get :index | |
expect(assigns(:users)).to match_array [@user,user] | |
end | |
it "renders the :index template" do | |
get :index | |
expect(response).to render_template :index | |
end | |
end | |
it "GET #new denies access" do | |
get :new | |
expect(response).to redirect_to root_url | |
end | |
it "POST#create denies access" do | |
post :create, user: attributes_for(:user) | |
expect(response).to redirect_to root_url | |
end | |
end | |
# Feature specs | |
gem "database_cleaner", group: :test | |
gem "launchy", group: :test | |
mkdir spec/features/ | |
# A basic feature spec | |
spec/features/users_spec.rb | |
require 'spec_helper' | |
feature 'User management' do | |
scenario "adds a new user" do | |
admin = create(:admin) | |
visit root_path | |
click_link 'Log In' | |
fill_in 'Email', with: admin.email | |
fill_in 'Password', with: admin.password | |
click_button 'Log In' | |
visit root_path | |
expect{ | |
click_link 'Users' | |
click_link 'New User' | |
fill_in 'Email', with: '[email protected]' | |
find('#password').fill_in 'Password', with: 'secret123' | |
find('#password_confirmation').fill_in 'Password confirmation',with: 'secret123' | |
click_button 'Create User' | |
}.to change(User, :count).by(1) | |
expect(current_path).to eq users_path | |
expect(page).to have_content 'New user created' | |
within 'h1' do | |
expect(page).to have_content 'Users' | |
end | |
expect(page).to have_content '[email protected]' | |
end | |
end | |
# Adding feature specs | |
require 'spec_helper' | |
feature 'my feature' do | |
background do | |
"add setup details" | |
end | |
scenario 'my first test' do | |
"write the example!" | |
end | |
end | |
spec/features/users_spec.rb | |
require 'spec_helper' | |
feature 'User management' do | |
scenario "adds a new user" do | |
admin = create(:admin) | |
sign_in admin | |
visit root_path | |
expect{ | |
click_link 'Users' | |
click_link 'New User' | |
fill_in 'Email', with: '[email protected]' | |
find('#password').fill_in 'Password', with: 'secret123' | |
find('#password_confirmation').fill_in 'Password confirmation', | |
with: 'secret123' | |
click_button 'Create User' | |
}.to change(User, :count).by(1) | |
save_and_open_page | |
end | |
end | |
# Including JavaScript interactions | |
spec/features/about_us_spec.rb | |
require 'spec_helper' | |
feature "About BigCo modal" do | |
scenario "toggles display of the modal about display" do | |
visit root_path | |
expect(page).to_not have_content 'About BigCo' | |
expect(page).to_not \ | |
have_content 'BigCo produces the finest widgets in all the land' | |
click_link 'About Us' | |
expect(page).to have_content 'About BigCo' | |
expect(page).to \ | |
have_content 'BigCo produces the finest widgets in all the land' | |
within '#about_us' do | |
click_button 'Close' | |
end | |
expect(page).to_not have_content 'About BigCo' | |
expect(page).to_not \ | |
have_content 'BigCo produces the finest widgets in all the land' | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment