Reputation: 9428
I can't get capybara working with rspec. It gives me this error:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
I know there are lots of posts about this but non of the solutions are working for me. Most of them involve the specs not being in /spec/features - which mine is in.
First the error:
$bundle exec rspec spec
F
Failures:
1) security signs users in
Failure/Error: visit "/sessions/new"
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
# ./spec/features/security_spec.rb:4:in `(root)'
Finished in 0.006 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/features/security_spec.rb:3 # security signs users in
I think its important to note that at first I was using the URL Helper 'new_sessions_path' and it kept giving me an error undefined local variable or method 'new_sessions_path'
. I know it is valid because:
$ rake routes
logout_sessions GET /sessions/logout(.:format) sessions#logout
sessions POST /sessions(.:format) sessions#create
new_sessions GET /sessions/new(.:format) sessions#new
contracts POST /contracts(.:format) contracts#create
new_contracts GET /contracts/new(.:format) contracts#new
edit_contracts GET /contracts/edit(.:format) contracts#edit
GET /contracts(.:format) contracts#show
PUT /contracts(.:format) contracts#update
DELETE /contracts(.:format) contracts#destroy
root / contracts#index
My Gemfile:
source 'https://rubygems.org'
gem 'rails', '3.2.11'
gem 'execjs'
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.1'
gem 'jruby-openssl'
gem 'therubyrhino'
gem 'kaminari'
gem 'nokogiri'
group :development do
gem 'warbler'
end
group :test do
gem 'rspec-rails'
gem 'capybara'
gem 'activerecord-jdbcsqlite3-adapter'
end
spec_helper.rb inside of my_app/spec:
# 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'
# Capybara integration
require 'capybara/rspec'
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}
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
# Include path helpers
config.include Rails.application.routes.url_helpers
end
my_app/spec/features/security_spec.rb:
describe "security", :type => :feature do
it "signs users in" do
visit "/sessions/new"
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
page.should have_content('Login Successful')
end
end
I've tried defining the test above both with and without :type => :feature
. It makes no difference either way. Any ideas what I should try next?
Upvotes: 95
Views: 57569
Reputation: 2842
One of the reasons might be if you defined page
variable using let
:
RSpec.describe "something" do
let(:page) { some_page }
it do
visit "/"
end
end
Results in the following error:
1) something
Failure/Error: visit "/"
NameError:
undefined method `visit' for class `#<Class:0x00007ffca6221898>'
Did you mean? visible
To fix it, rename page
variable.
Upvotes: 0
Reputation: 5940
Other than the upgrading issue which you would run into when ugprading from an older Rails app with require 'spec_helper.rb'
instead of require 'rails_helper.rb'
, this happens for 3 known reasons:
1. Your spec isn't of type "feature"
which means Capybara doesn't know how to run it using Javascript or a browser. You want to do one of two things: 1) Typically, you want config.infer_spec_type_from_file_location!
set in your RSpec.configure and that will mean that what's in the features folder will be a feature.
if you have something non-standard, you can add type: :feature
to the spec describe block to turn that spec in a feature, but typically it's easier just to put them into the /features folder and let the infer setting do its job.
2. You accidentally put the visit
outside of the it block
The visit must be within the it, which is within the describe. Be sure not to put the visit directly within the describe.
3. Some other kernal panic you can't see has caused Capy to shut down the spec.
This is a nasty one to diagnose but I have seen it. It means that Capy didn't actually parse this file correctly, and so somehow isn't in the right scope when it gets to the visit block. Carefully pick apart your Capy spec to figure out where you introduced it.
I induced the kernal panic today but have a let
block be called page
(whoops). page
appears to be a reserved word for Rspec or Capy here, and it causes the kernal panic, thus leading to the spec not to parse thus leading to the visit
method not being found.
in my case, it was simply changing this:
let(:page) {Page.new()}
to
let(:content_page) {Page.new()}
Notice that the word page
is not reserved by Rails, and works fine as a database name and also a model name, but the specific construction of using page
here as the let variable name seemed to cause Capy to get kind of crappy.
Upvotes: 2
Reputation: 9428
Adding require 'rails_helper'
at the top of my feature ended up fixing my problem:
require 'rails_helper'
describe "security", :type => :feature do
it "signs users in" do
visit new_sessions_path
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
page.should have_content('Login Successful')
end
end
This seems odd to me since every example I've seen for rspec and capybara didn't have that require, but oh well. Problem solved.
require 'spec_helper'
is used by older versions of RSpec. The better answer would be require 'rails_helper'
.
Upvotes: 56
Reputation: 669
I also had this problem,
Adding require 'rails_helper' at the top of my feature ended up fixing my problem:
require 'rails_helper'
RSpec.describe "Products", type: :request do
describe "GET /products" do
it "display tasks" do
Product.create!(:name => "samsung")
visit products_path
page.should have_content("samsung")
#expect(response).to have_http_status(200)
end
end
end
And add the 'config.include Capybara::DSL' in rails_helper.rb
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.include Capybara::DSL
end
Upvotes: 4
Reputation: 4896
Since Capybara 2.0 one has to use folder spec/features Capybara commands don't work in folder spec/requests anymore.
Upvotes: 37
Reputation: 16793
Try performing all your setup in a before
block:
spec/features/security_spec.rb
describe "security" do
before do
visit "/sessions/new"
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
end
it "signs users in" do
page.should have_content('Login Successful')
end
end
Upvotes: 6
Reputation: 6931
Try to add:
config.include Capybara::DSL
to your config block.
# 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'
# 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}
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
# Include path helpers
config.include Rails.application.routes.url_helpers
config.include Capybara::DSL
end
Upvotes: 213