some_spec.rb
require 'spec_helper'
describe "Authentication." do
subject { page }
let(:user) { FactoryGirl.create(:user) }
before {visit new_user_session_path}
describe "Login with username" do
before do
fill_in "Login", with: user.username
fill_in "Password", with: user.password
click_button "Sign in"
end
expect(page).to have_content('Signed in successfully.')
end
describe "Login with email" do
before do
fill_in "Login", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
expect(page).to have_content('Signed in successfully.')
end
end
spec_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include Capybara::DSL
config.include Rails.application.routes.url_helpers
end
What's the problem? After run command terminal returned error: undefined local variable or method 'page'.
The following question did not help me:
rspec+capybara undefined local variable or method
I think you should remove subject { page } from your spec.
page is defined in Capybara.
Important: wrap your expectations by it blocks!
Related
Code example:
login_as(user, scope: :user)
visit user_edit_path #this is authorized
# some expectations
visit user_comments_path #this is not authorized, return 401, why?
But if I add second login_as after first visit - everything works. I don't know why devise session reseted.
When I try to login through the login form via fill_in and click_on 'Log in', session reseted after redirect to root_path! So in that case i can't do even basic expectations that user was logged in.
I tested on the different drivers.
Rspec configuration file:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/poltergeist'
# NOTE: For Chrome support
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
# Capybara.register_driver(:poltergeist) { |app| Capybara::Poltergeist::Driver.new(app, js_errors: false) }
# Capybara.javascript_driver = :poltergeist
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
# Checks for pending migration and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include WaitForAjax
config.include FeatureHelpers
config.include Devise::TestHelpers, type: :controller
config.include Warden::Test::Helpers
config.extend ControllerHelpers, type: :controller
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.before :suite do
Warden.test_mode!
end
end
I had to remove config.action_controller.default_url_options = {:host => "localhost:3000"} from environments/test.rb
My problem is that capybara holds only one authorized request (doesn't matter was it authorization through the login form or through the helper login_as method)
Other (second, third) requests are unauthorized!
It doesn't mater what driver I use. Where the problem can be?
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/poltergeist'
# NOTE: For Chrome support
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
# Capybara.register_driver(:poltergeist) { |app| Capybara::Poltergeist::Driver.new(app, js_errors: false) }
# Capybara.javascript_driver = :poltergeist
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
# Checks for pending migration and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include WaitForAjax
config.include FeatureHelpers
config.include Devise::TestHelpers, type: :controller
config.include Warden::Test::Helpers
config.extend ControllerHelpers, type: :controller
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.before :suite do
Warden.test_mode!
end
end
Most probably between the first request and the second, rspec cleans up the DB.
For this second request the user form the first request no more exists. You should create another user and login/authorize it.
Ex:
For each it block you'll have to do a login_as(a_new_just_created_user). Yes, you can put this into a before block to be executed for the entire test suite.
describe '' do
before do
login_as(a_new_just_created_user)
end
context '' do
it '' { get 'api/url' } # first user logged in
it '' { get 'api/url' } # second user logged in
end
context '' do
it '' { get 'api/url' } # third user logged in
end
end
I have set up Rspec with a rails4 app however the tests are returning:
Failure/Error: user = Factory(:user)
NoMethodError:
undefined method `Factory' for #<RSpec::Core::ExampleGroup::Nested_4::Nested_1:0x007fa08c0d8a98>
Seems like I'm including FactoryGirl incorrectly. I've tried a couple of variations but I can't get it to work.
My Spec Helper:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'factory_girl_rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include Capybara::DSL, :type => :request
config.include FactoryGirl::Syntax::Methods
end
gem file:
group :development, :test do
gem 'rspec-rails', '~> 2.0'
gem 'factory_girl_rails', :require => false # as per sugestion on SO. Without the require false also fails
gem "capybara"
end
my spec:
require 'spec_helper'
describe "Create Event" do
describe "Log in and create an event" do
it "Allows creation of individual events" do
user = Factory(:user)
visit "/"
end
end
end
and in /spec/factories/users.rb
FactoryGirl.define do
factory :user do |f|
f.email "provider#example.com"
f.password "password"
end
end
How can i get going with factory girl?
Given that you have included:
config.include FactoryGirl::Syntax::Methods
In your RSpec configure block, I'm guessing that the syntax you're looking for is:
user = create(:user)
or:
user = build(:user)
To create a user using FactoryGirl:
user = FactoryGirl.create(:user)
This will use everything you defined in the factory to create the user. You can also override any value, or specify additional values at the same time. For example:
user = FactoryGirl.create(:user, username: 'username', email: 'different-email#example.com)
Alternatively you can use FactoryGirl.build(:user, ...) where you want to make use of the factory to build an instance but not actually save it to the database.
It's definitely best to divide specs up so you have specs pertaining to each aspect of the MVC architecture, but I think there is a slight crossover with controller specs and view specs.
With view specs, you should only be concerned with the view, but with controller specs I still think it would be a good idea to test that the correct view is rendered, and maybe even test the content of the view, although more in-depth testing of the content should take place in the view spec.
Despite this clear article, https://www.relishapp.com/rspec/rspec-rails/v/2-1/docs/controller-specs/render-views, describing how to do this, I just cannot integrate my view and controller specs.
I keep getting the error undefined method 'contain'!
Here's my spec_helper:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/rails'
require 'factory_girl_rails'
require 'ap'
def set(factory)
#user = FactoryGirl.create(factory)
end
def sign_up(first_name, last_name, profile_name, email, password)
visit "/"
click_link "Register"
fill_in('First name', with: first_name)
fill_in('Last name', with: last_name)
fill_in('Profile name', with: profile_name)
fill_in('Email', with: email)
fill_in('Password', with: password)
fill_in('Password confirmation', with: password)
click_button 'Sign up'
end
def sign_in(email, password)
visit "/"
click_link "Sign In"
fill_in('Email', with: email)
fill_in('Password', with: password)
click_button 'Sign in'
end
def sign_out
visit "/"
click_link "Sign Out"
end
#Webrat.configure do |config|
# config.mode = :rails
#end
#webrat
require 'capybara/poltergeist'
# Capybara.javascript_driver = :poltergeist
Capybara.javascript_driver = :selenium
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
# true means 'yes, filter these specs'
config.filter_run_excluding stress: true
# config.current_driver = :webkit
# config.use_transactional_fixtures = false
# config.include Capybara::DSL
DatabaseCleaner.strategy = :truncation
config.after(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
# config.before(:suite) do
# DatabaseCleaner.strategy = :transaction
# DatabaseCleaner.clean_with(:truncation)
# DatabaseCleaner.start
# end
# config.after(:each) do
# DatabaseCleaner.clean
# end
#config.after(:suite) do
# DatabaseCleaner.strategy = :transaction
# DatabaseCleaner.clean_with(:truncation)
# DatabaseCleaner.clean
# end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.include RSpec::Rails::RequestExampleGroup, type: :feature
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
I18n.enforce_available_locales = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
Here's my controller spec:
require "spec_helper"
describe UserFriendshipsController, type: :controller do
render_views
let (:user_1) { FactoryGirl.create(:user_1)}
before {
sign_in user_1
get :index
}
it "renders the :index view" do
response.should render_template(:index)
end
it "view contains expected html" do
# a sanity test more than anything
response.should contain("Welcome to the home page")
end
end
Upon running this spec I get this:
.F
Failures:
1) UserFriendshipsController view contains expected html
Failure/Error: response.should contain("Listing widgets")
NoMethodError:
undefined method `contain' for #<RSpec::Core::ExampleGroup::Nested_1:0x00000008632268>
# ./spec/controllers/user_friendships_spec.rb:18:in `block (2 levels) in <top (required)>'
Finished in 0.1835 seconds
2 examples, 1 failure
Why is this happening? How can I get this to work?
If you look at the relish documentation for the current 2.14 version of Rspec you'll see that they're using match now instead:
expect(response.body).to match /Listing widgets/m
Using the should syntax, this should work:
response.body.should match(/Welcome to the home page/)
Right, it was a very unclear article from Rspec that caused this error. It was using webrat in its example and didn't think to tell you. If anyone else gets here, you can add webrat to your gemfile to use the contain method:
Gemfile
group :test do
gem 'webrat'
end
However, it makes a lot more sense to use rspec's native match method:
expect(response.body).to match /Listing widgets/m
I'm using rspec, capybara and launchy to test my web application.
Here's my spec:
require 'spec_helper'
describe "Routes" do
describe "GET requests" do
it "GET /root_path" do
visit root_path
page.should have_content("All of our statuses")
click_link "Post a New Status"
page.should have_content("New status")
fill_in "status_name", with: "Jimmy balooney"
fill_in "status_content", with: "Oh my god I am going insaaaaaaaaane!!!"
click_button "Create Status"
page.should have_content("Status was successfully created.")
click_link "Statuses"
page.should have_content("All of our statuses")
page.should have_content("Jimmy balooney")
page.should have_content("Oh my god I am going insaaaaaaaaane!!! ")
save_and_open_page
end
end
end
My .rspec
--color
--order default
and my spec_helper.rb:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
If you look back at my spec, you'll see a rspec spec that uses capybara to browse my application, and finishes by calling the launchy gem's save_and_open_page method to open this final page in a browser for a human to look at. At this final page, however, there is no javascript or css displayed, just pure HTML.
Does anyone have any ideas why this would be? I want to test javascript, and would prefer it if all assets were loaded.
Inside config.before(:suite) do
add:
%x[bundle exec rake assets:precompile]
to precompile your Rails assets then in your test.rb environment file add:
config.action_controller.asset_host = "file://#{::Rails.root}/public"
config.assets.prefix = 'assets_test'
to point to the location of the precompiled assets. Now you can use assets when you run Capybara. Note: make sure if you are using git to ignore that new folder.
You can just add to test.rb:
config.assets.compile = true