Skip to content
This repository

undefined method `visit' for #<RSpec::Core::ExampleGroup:.... #360

Closed
be9 opened this Issue May 01, 2011 · 63 comments
Oleg Dashevskii
be9 commented May 01, 2011

I'm having trouble with my Capybara integration specs and rspec-rails 2.6.0.rc4.

  9) My profile should show profile
     Failure/Error: login_as @user
     undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_4:0x748aab0>
     # ./spec/support/request_helpers.rb:8:in `login_as'
     # ./spec/integration/user/profile_spec.rb:6

It's simple visit '/' which explodes.

2.6.0.rc2 works great. What has been changed? Capybara version is 1.0.0.beta1

David Chelimsky
Owner

rc4 adds more support for Capybara 0.4 and 1.0. How/where are you requiring capybara?

Oleg Dashevskii
be9 commented May 02, 2011

I have require 'capybara/rspec' line in spec/support/additional_requires.rb

David Chelimsky
Owner

Try getting rid of that and tell me what happens. rspec-rails already does this, so it might be that doing it a second time is causing a problem due to module reloading, etc.

Oleg Dashevskii
be9 commented May 02, 2011

I've commented out the require line, but nothing changed. visit is still broken.

David Chelimsky
Owner

What's in your Gemfile?

Oleg Dashevskii
be9 commented May 02, 2011

Posted Gemfile here: https://gist.github.com/952141

David Chelimsky
Owner

I just ran this: https://gist.github.com/952630 and the spec with visit in it passed. Do you get the same result from that gist?

Oleg Dashevskii
be9 commented May 02, 2011

Works here too. I tried to make visit explode by copying in Gemfile and other stuff from my project but it still passes.

On the other side, I experimented with rspec-rails git and found out that this commit exactly: 59793dc breaks things for me (the specs pass with the preceding one when rspec-rails is pulled from git).

Oleg Dashevskii
be9 commented May 02, 2011

The test example works if I manually add include Capybara::DSL.

How come it doesn't get included?

Oleg Dashevskii
be9 commented May 02, 2011

So, I found it. The example that also breaks for your example app:

require "spec_helper"
describe "things" do
    it "works with visit" do
      go_things
      page.status_code.should eq(200)
    end
end

The cause of the bug is as follows. If we look at the :include_or_extend_modules array in rspec configuration, we see following:

   [[:extend, RSpec::Matchers::DSL, {}],
     [:include, RSpec::Rails::FixtureSupport, {}],
     [:include, RSpec::Rails::Mocks, {}],
     [:include, Capybara::Features, {:capybara_feature=>true}],
     [:include, Capybara::DSL, {:type=>:request}],
     [:include, Capybara::DSL, {:type=>:acceptance}],
     [:include, Capybara::RSpecMatchers, {:type=>:request}],
     [:include, Capybara::RSpecMatchers, {:type=>:acceptance}],
     [:include,
      RSpec::Rails::ControllerExampleGroup,
      {:type=>:controller,
       :example_group=>{:file_path=>/spec[\\\/]controllers/}}],
     [:include,
      RSpec::Rails::HelperExampleGroup,
      {:type=>:helper, :example_group=>{:file_path=>/spec[\\\/]helpers/}}],
     [:include,
      RSpec::Rails::MailerExampleGroup,
      {:type=>:mailer, :example_group=>{:file_path=>/spec[\\\/]mailers/}}],
     [:include,
      RSpec::Rails::ModelExampleGroup,
      {:type=>:model, :example_group=>{:file_path=>/spec[\\\/]models/}}],
     [:include,
      RSpec::Rails::RequestExampleGroup,
      {:type=>:request,
       :example_group=>{:file_path=>/spec[\\\/](requests|integration)/}}],
     [:include,
      RSpec::Rails::RoutingExampleGroup,
      {:type=>:routing, :example_group=>{:file_path=>/spec[\\\/]routing/}}],
     [:include,
      RSpec::Rails::ViewExampleGroup,
      {:type=>:view, :example_group=>{:file_path=>/spec[\\\/]views/}}],
     [:include, Devise::TestHelpers, {:type=>:controller}],
     [:include, RequestHelpers, {:type=>:request}],
     [:include, GlobalSpecHelpers, {}]]}>

(that's from my project). So Capybara::DSL gets included before RSpec::Rails::RequestExampleGroup. The former has :type => :request filter, but the type itself is set when the latter is included. So Capybara::DSL module is rejected by the filter and not included.

In your test example, with double describe block, module inclusion occurs twice. The second time type is already set, Capybara::DSL gets included, everything works.

The fix should be darn simple (haven't got more time right now, but I'll come up with it in the case you don't fix it first :)

Oleg Dashevskii be9 referenced this issue from a commit in be9/rspec-rails May 03, 2011
Oleg Dashevskii Require capybara after rspec/rails/example
Otherwise Capybara's includes are not set correctly.

Fixes #360
c19e295
Oleg Dashevskii
be9 commented May 03, 2011

Fix is available as pull request #362

David Chelimsky dchelimsky closed this issue from a commit May 03, 2011
Oleg Dashevskii Require capybara after rspec/rails/example
Otherwise Capybara's includes are not set correctly.

- Closes #360
- Closes #362
d0e790e
David Chelimsky dchelimsky closed this in d0e790e May 03, 2011
Tom Philip

I've got the same isssue (undefined method `visit' etc). I'm using capybara 1.0.0.beta1 I've got the rspec-rails and dependencies in my gemfile pointing to github. So I would have thought I'd have the latest, which includes the above commit? I have require 'rspec/rails' in my spec_helper.rb. It's in a new project I'm just getting started with. I'm also just getting started with rails, so I'm totally lost. Any help would be much appreciated.

Jack Kinsella

I ran into the same problem today with rspec-rails 2.6.1 and capybara 1.0.0

#spec_helper.rb

require 'rubygems'
require 'spork'
require "email_spec"
ENV["RAILS_ENV"] ||= 'test'     
Spork.prefork do
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
end
Spork.each_run do
  Dir[Rails.root.join("site/app/**/*.rb")].each {|f| require f}     
  require "#{Rails.root}/spec/factories.rb"
end
Jack Kinsella

Problem was due to the 'steak' gem. Once I removed it the Capybara methods worked once again.

David Chelimsky
Owner

@jackkinsella - glad to hear it, though a lot of people like to use steak so I'd like to understand why that doesn't work.

As an aside, I'd recommend the following changes to your spork config in spec_helper:

#spec_helper.rb

require 'rubygems'
require 'spork'
ENV["RAILS_ENV"] ||= 'test'

Spork.prefork do
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'email_spec' # shouldn't really need this if it's in the :test group in the Gemfile
end

Spork.each_run do
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
end

This assumes moving spec/factories.rb to spec/support. You don't need to require anything from app/** because Rails does that for you.

Jack Kinsella

Thanks Dave; I hadn't thought of putting the factories into the support dir. I'm aware that I don't need to require anything from app/, but I have a gem in site/app/ which I'm actively developing.

I decided against using Steak for the same reason I've stopped using Cucumber: unwarranted additional abstraction. Rspec and Capybara do the same job with less lines of code and with fewer configuration headaches.

David Chelimsky
Owner

Ah - missed that it was site/app. Cheers.

Derek Prior

I'm still seeing this with the latest rspec and rspec-rails. The visit method is undefined unless I nest my tests inside a second describe. As a result, I wrap my tests in a meaningless secondary describe.

I am using spork, so perhaps that has something to do with it?

require 'rubygems'
require 'spork'

Spork.prefork do
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'capybara/rspec'
  require 'rspec/rails'
  require 'database_cleaner'

  # use capybara-webkit
  Capybara.javascript_driver = :webkit

  # calls to DatabaseCleaner.clean will use truncation
  # otherwise, we will still use transactional fixtures
  DatabaseCleaner.strategy = :truncation

  # 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|
    config.treat_symbols_as_metadata_keys_with_true_values = true
    config.mock_with :rspec
    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    config.use_transactional_fixtures = true
    config.include ModelMacros
    config.include ActionView::TestCase::Behavior, :example_group => {:file_path => %r{spec/presenters}}
    # config.include FactoryGirl::Syntax::Methods

    config.before(:suite) do
      # Create the admin user
      Factory(:user, :login => ENV['REMOTE_USER'], :roles_mask => 1)
    end
  end
end

Spork.each_run do
  # verifies we start with a clean database each run
  DatabaseCleaner.clean

  # require factories
  require 'factory_girl_rails'
  RSpec.configure do |config|
    config.include FactoryGirl::Syntax::Methods
  end
end

# This allows us to use transactional fixtures when
# using selenium/capybara-webkit by forcing them to use
# the same thread as capybara.
ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
  def current_connection_id
    Thread.main.object_id
  end
end
Artem Veremey

Getting the same error with rspec-rails (2.8.1) and capybara (1.1.2).
Have to manually include Capybara::DSL.

David Chelimsky
Owner

@derekprior, @ala I can't repro this on my system w/ Mac OS and ruby 1.9.3. What OS and ruby versions are you running?

Derek Prior

I'm running OS X 10.6.8, with Ruby 1.9.2-p290. I'll take a shot at distilling a simplified reproduction.

Artem Veremey

Running on OS X too:

rvm -v
rvm 1.10.3 by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.beginrescueend.com/]

ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]

Derek Prior

Okay, @dchelimsky, I think I boiled it down to a base case (at least in my case). Please see this repository:
https://github.com/derekprior/rspec_rails_bug

The reproduction succeeds (visit is undefined) if I require capyabara/rspec before rspec/rails in spec_helper.rb. Interestingly, it seems completely unnecessary to require capyabara/rspec at all as removing that line completely makes all tests pass. Requiring rspec/rails first also causes all tests to pass.

The repository I linked to will produce a failing spec on 1.9.2-p290 and 1.9.3-p0. I suspect the same is true of 1.8.7, but I didn't have time to correct the hash syntax and re-run the tests there.

Seems like "leave it to rspec-rails to require capyabara" is the way to go. I think that line was in my spec_helper from days prior to whatever version of rspec-rails added the automatic require.

Derek Prior

Actually, it appears that test case isn't true to my actual project issue. In my actual project, neither removing or re-ordering the requires fixes anything. Calls to visit still must be at least 2 describes deep. Odd.

I'll keep looking...

Artem Veremey
#
#  *Working*
# spec/controller/pages_controller_spec.rb
#
require 'spec_helper'

describe PagesController do
  render_views

  describe "GET 'home'" do
    it "should be successful" do
      visit '/'
      response.should be_successful
    end
  end
end
#
# *Not Working*
# spec/requests/user_registration_spec.rb
#
require 'spec_helper'

describe "user registration" do  
  it "should serve the registration page" do
    visit '/signup'
    page.should have_content("Sign Up")
  end
end
David Chelimsky
Owner

@ala - what's not working? You're getting undefined method on visit? Or something else?

Artem Veremey

@dchelimsky yes, getting the undefined visit method.

David Chelimsky
Owner

@ala is your repo public?

Artem Veremey

@dchelimsky unfortunately no. Let me see if I can cut out that example. Should be a pretty basic Rails 3.2 app.

duckpond

I'm seeing this identical issue. We had

  config.include RSpec::Rails::RequestExampleGroup, :example_group => { :file_path => /spec\/externals/ }

in our spec_helper but it was still getting undefined method 'visit'.

Steve
dnd commented March 22, 2012

Just another mention that I'm having the same problem described by aia. If I nest the visit call two describes deep then it works fine. This is on rspec* 2.9.0

David Chelimsky
Owner

Folks - I need a repro. Can anybody who is experiencing this problem post a repo to github that I can clone, bundle, run, and see the issue?

Derek Prior

I will try to cleans my app of anything proprietary and post the repro

Derek Prior

Alright, here's a repo:
https://github.com/derekprior/rspec-rails-capybara-bug

In my case it seems that the gem 'capybara-screenshot' is causing the problem. If I remove this gem from the gemfile, both specs pass. I've tried keeping it in with various gem orderings, but I have not had any success. I haven't yet dug into this gem to see what's going on.

Curious if other folks having problems also have this gem?

Steve
dnd commented March 27, 2012

I can't try removing that gem from mine at the moment, but I am also using 'capybara-screenshot', version 0.1.10 to be specific.

Derek Prior

Here's what capybara-screenshot is doing on load:
https://github.com/mattheworiordan/capybara-screenshot/blob/master/lib/capybara-screenshot.rb

I don't know enough about the internals to say what the problem is off hand, but perhaps David or someone else does?

David Chelimsky
Owner

It's definitely a load order integration bug. I don't understand it yet, but you can work around it by doing the following:

# in Gemfile
  gem 'capybara-screenshot', :require => false

# in spec/spec_helper.rb
  require 'rspec/rails'
  require 'capybara-screenshot'
David Chelimsky
Owner

Also - @derekprior thanks for posting the app - that helped me see the bug, figure out the workaround, and will eventually lead to a fix.

5minpause

Unfortunately this workaround doesn't do it for me. I still get

NoMethodError:
   undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1::Nested_1:0x007fbfeb535298>

The repo is public under: https://github.com/ikusei/Goldencobra_Newsletter
You need to look at the branch '28817499-subscribe'

edit: If i put include Capybara::DSL inside my describe block it works.

bigtunacan

I see this is marked as closed, but I'm having this same issue

5minpause

Did you see my edit? After doing that it worked for me.

bigtunacan

@jazzgumpy , Thanks that works for me as well using include Capybara::DSL within my outer describe

Henrik Nyh
henrik commented July 31, 2012

@dchelimsky I started on a new app and ran into this, so this is a very small (if not minimal) failure case with RSpec 2.11: https://dl.dropbox.com/u/546793/joblog.zip

Note that there is a workaround (config.include Capybara::DSL) in spec/spec_helper.rb:19, so comment that out to (hopefully) reproduce.

(And I will of course make sure to change the secret_token.)

Henrik Nyh
henrik commented July 31, 2012

@bigtunacan @jazzgumpy A slightly nicer workaround is to put

config.include Capybara::DSL

in spec_helper.rb, inside the config block.

David Chelimsky
Owner

@henrik the directory is requests (plural), not request. Try that and it works as expected.

Henrik Nyh
henrik commented July 31, 2012

@dchelimsky Thanks, that did work. Sorry for bothering you with such a silly mistake. Maybe @jazzgumpy and @bigtunacan made similar mistakes.

Would be nice if it was harder to make a mistake, or easier to recover from it, but I can't think of how, other than maybe emphasizing it in the docs. Pull request for that: #585

David Chelimsky
Owner

I merged your pull request, so that should help. Thx. Also, the integration test generator puts it in the right place.

Vojtěch Kusý

I've run in this issue after update to capybara 2.0. First I implemented the henrik's workaround by mixing Capybara::DSL methods to Rspec but now I've found this in the Capybara 2.0 update notes:

To upgrade to capybara 2.0, you'll need to do a few things:

Move any tests that use capybara from spec/requests to spec/features. Capybara tests use the visit method and usually assert against page. Alternatively, you can keep using capybara in request specs, but you'll need to manually mix in the methods.

See http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html

I have my tests in the old path spec/requests of course ...

Might be it could help someone.

reejosamuel

for others facing the issue, renaming request to requests is no longer the problem, all requests need to be moved to features folder

2wojtha and @reejosamuel, thank you. I renamed my requests dir to features and that fixed it!

Paola Cerioli

thank you @wojtha.
That fixed the issue for me.

George Anderson

renaming requests to features worked here, too. Thx.

Eric Schaefer

ditto for me @george

Andy Lindeman
Owner

For reference, it's documented in Capybara.md and this blog post

Chris Arndt

renamed requests to features. Problem fixed. Thank you.

Dave Gerton

I'm using rails 4.0.0.beta1. Renamed the requests folder to features, but still needed to add config.include Capybara::DSL to spec_helper.rb.

Emad Elsaid

i got the same problem and fixed with 2 way :
1- renaming the "requests" directory to "features"
2- the work around of adding Capybara DSL to my rspec helper mentioned above

thanks guys

dmxforever

renaming "requests" to "features" fix it. rails 4

Lucas

:+1: renaming "requests" to "features" fixed it, on Rails 3.

longli
longli commented May 03, 2013

1、add "gem "rspec-rails", "~> 2.0" and gem 'capybara', '~>1.1.2'" in Gemfile
2、bundle install
3、add “config.include Capybara::DSL” in spec_helper.rb
OK! Good luck for you!

Song Yangyu
flyfy1 commented June 05, 2013

Hmm I think it might be helpful to add the poing number 3 into the README.md file of capybara so that when people use they don't need to do search for the problem again.

Nathan Hamilton

Renaming the spec/requests folder to spec/features got things rolling for me too. Thanks for the help.

Steven Clontz

Renaming the spec/requests folder to spec/features got things rolling for me too. Thanks for the help.

+1

Alex Rothenberg alexrothenberg referenced this issue from a commit in alexrothenberg/rspec-rails August 01, 2012
Henrik Nyh Clarify when webrat/capybara autoloading applies.
Since I got it wrong: rspec#360
3622324
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.