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?
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
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.
Original Answer (older versions of rspec)
require 'spec_helper' is used by older versions of RSpec. The better answer would be require 'rails_helper'.
Since Capybara 2.0 one has to use folder spec/features Capybara commands don't work in folder spec/requests anymore.
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
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
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.
Related
I have a Problem with an rspec-request-test in my rails app. The tests, that need a user-login are failing. I have implemented the devise-tests according to this tutorial. Also I found many links, that are using a similar approach. e.g. here
Here is an extract of my gemfile:
gem 'devise', '~> 3.5'
gem 'devise-i18n'
gem 'devise-i18n-views'
gem 'cancancan', '~> 1.10'
gem 'rolify'
gem 'alchemy_cms', '~> 3.2.0'
gem 'rspec-core'
gem 'rspec-rails'
gem 'i18n-tasks', '~> 0.8.7'
gem 'factory_girl_rails'
Here is the rspec-test, that is failing: (spec/requests/campaigns_spec.rb)
require 'rails_helper'
RSpec.describe "Campaigns", type: :request do
describe "GET /campaigns" do
it "responds with 200" do
sign_in_as_a_valid_user_request
get campaigns_path
expect(response).to have_http_status(200)
end
end
end
You should only see this page, when you are logged in. So in the test I want to log in as a User (created with FactoryGirl), than go to the site, and get a 200-response. In the application itself this is working good.
spec/rails_helper.rb (extract)
...
require 'spec_helper'
require 'rspec/rails'
require 'devise'
require 'support/devise_support'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include Devise::TestHelpers, type: :controller
config.include Devise::TestHelpers, type: :view
config.include ValidUserRequestHelper
...
end
spec/support/devise_support.rb
module ValidUserRequestHelper
def sign_in_as_a_valid_user_request
#user ||= FactoryGirl.create :user
post_via_redirect user_session_path, 'user[email]' => #user.email, 'user[password]' => #user.password
end
end
here is the error, that the test is throwing:
1) Campaigns GET /campaigns responds with 200
Failure/Error: sign_in_as_a_valid_user_request
ActionController::RoutingError:
Alchemy::Page not found "/"
# ./spec/support/devise_support.rb:13:in `sign_in_as_a_valid_user_request'
# ./spec/requests/campaigns_spec.rb:6:in `block (3 levels) in <top (required)>'
According to the links that I found, this should work! but it doesn't... Can anyone tell me why? Why is there a routing error? The app itself is working fine.
The routing error occurs, because your host app does not know of the engines routes. That's why you have to use the routing proxy objects of rails engines in views outside the current controller scope. Please read more about rails engines and the characteristics of their routes in the official rails guides
Luckily, Alchemy comes with a handy test helper that solves your problems. Just add this to your spec_helper:
# spec/spec_helper.rb
require 'alchemy/test_support/controller_requests'
...
RSpec.configure do |config|
config.include Alchemy::TestSupport::ControllerRequests
...
end
Know you can use alchemy_get instead of get in your request specs.
I just started playing with Capycabra+poltergeist and after execution of my Capy test rspec ./spec/features/test_spec.rb
I got the following error:
Failure/Error: visit '/item/new'
ArgumentError: rack-test requires a rack application, but none was given
Also I have a few standard rspec tests and whenever I try to excute all tests, rspec tests are passed successfully, but only the capy test fails with weird error
ActionView::Template::Error: couldn't find file 'jquery.min' (in app/assets/javascripts/application.js:13)
Which leads me to the confusion.
I have viewed several similar threads on stackoverflow in some cases the error is about missing config.include Capybara::DSL in the spec_helper.rb or incorrect location of tests. I made appropriate changes, but it doesn't work, the error is still the same.
My spec_helper.rb file
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
config.include Capybara::DSL
end
Full Version of spec_helper: http://pastebin.com/qkANfu39
Test file:
#spec/features/test_spec.rb
require 'spec_helper'
describe 'accessibility of webpage' do
it 'should access web page' do
visit '/item/new'
expect(page).to have_content("Something")
end
end
Thoughts?
Update
This workaround is no longer needed according to the report(see in comments), but I haven't checked it yet.
Found workaround..
I had to specify the app host url and a default driver..
#spec/spec_helper.rb
require 'capybara'
require 'database_cleaner'
require 'capybara/dsl'
require 'capybara/poltergeist'
Capybara.configure do |c|
c.javascript_driver = :poltergeist
c.default_driver = :poltergeist
c.app_host = "http://localhost:3000"
end
Update 1
In order to fix error:
Failure/Error: visit '/item/new'
ArgumentError: rack-test requires a rack application, but none was given
I included rails_helper file into my Capy test. the final version of test:
require 'rails_helper'
require 'spec_helper'
describe 'accessibility of webpage' do
it 'should access web page' do
visit '/item/new'
expect(page).to have_content I18n.t("form_input.item.item_s")
end
end
After that for some reason specified app_host url no longer needed and it can be removed from the spec_helper helper file. The final version:
Capybara.configure do |c|
c.javascript_driver = :poltergeist
c.default_driver = :poltergeist
end
The full version of spec_helper.rb http://pastebin.com/DKgF1uQA
Error
ActionView::Template::Error: couldn't find file 'jquery.min' (in app/assets/javascripts/application.js:13)
Occurred because gem 'jquery-rails' wasn't available in the test scope in my Gemfile, It was available only in :development & :production environment. I moved the gem 'jquery-rails' out to the global scope. The full version of a Gemfile: http://pastebin.com/dt4KrHGG
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.
I'm running Rails 4, trying to set up some integration test with Rspec and Capybara. I want to set up guard to run 'zeus test .' whenever I make changes. Problem is, whenever anything form the Capybara DSL is called, or whenever I try to use route helpers, I'm given errors like this:
undefined local variable or method `root_path' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007f55682c6d60>
If I replace root_path with '/' it get:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007f556833bbb0>
If I just run 'rspec spec .' or 'zeus test .' it works fine.
I've tried removing the 'cmd: 'zeus test .' option from my Guardfile, but I'm having the same issues. It seems clear that the problem is with Guard and unrelated to zeus.
In my Gemfile:
group :development, :test do
gem 'capybara'
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'guard-rspec', require: false
gem 'better_errors'
gem 'binding_of_caller'
end
Spec helper:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'factory_girl_rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
end
Spec I'm trying to run:
require 'spec_helper'
describe "HomePage" do
describe "Root page" do
before { visit root_path }
it "works!" do
page.status_code.should be(200)
end
it 'contains bottom nav buttons' do
page.should have_link 'How it works'
page.should have_link 'Customer Service'
page.should have_link 'Terms of Service'
page.should have_link 'Contact Us'
end
end
end
try add
config.include Capybara::DSL
to your spec_helper.rb
Try to add url_helpers to spec_helper.rb
RSpec.configure do |config|
...
config.include Rails.application.routes.url_helpers
end
and check my other answer about visit method missing
I fixed this problem by commenting out this line in my spec_helper.rb:
require 'rspec/autorun'
Again, the problem was only with Guard and I suppose that autorun somehow skips over the config block in the spec_helper, so everything works fine now. Hope this helps someone else having the same problem.
I cannot get capybara to work. I am using capybara 2.0.0
I get this error
Failure/Error: visit "/users/sign_in"
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_21:0x007fdda4c6eba0>
on this spec
spec/requests/forgot_password_spec.rb
describe "forgot password" do
it "redirects user to users firms subdomain" do
visit "/users/sign_in"
end
end
I do not get any errors that it cannot find capybara and it's included in the spec_helper.rb
spec_helper.rb
require 'rubygems'
require 'spork'
require 'database_cleaner'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'rspec/autorun'
require 'factory_girl'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller
config.include RequestMacros, :type => :request
config.mock_with :rspec
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.infer_base_class_for_anonymous_controllers = false
end
Spork.each_run do
FactoryGirl.reload
end
end
Has anybody else encountered this?
If you've got version >= 2.0, any tests that use Capybara methods like visit should go under a spec/features directory, and not under spec/requests, where they'd normally reside in Capybara 1.1.2.
Have a look at the following links for more information:
rspec-rails and capybara 2.0: what you need to know
rspec-rails gem Capybara page
If you don't want to use a spec/features directory, you should be able to mark a test as a feature in the following way and have Capybara methods work:
describe "Some action", type: :feature do
before do
visit "/users/sign_in"
# ...
end
# ...
end
In my case, I got this error because I forgot to putrequire "spec_helper"
at the top of my new spec file.
I've done it enough times that I'm adding an answer to an already answered question in hopes that it helps some other knucklehead (or most likely me searching this again in the future).