croceldon
croceldon

Reputation: 4605

Upgrade to Rails 4.2 breaks rspec feature specs - why?

My model and controller specs are running fine, but after the upgrade to rails 4.2, my feature specs, which use Capybara, no longer work. Example:

#in spec_helper.rb:
def login_admin
  create(:user,
         first_name: 'John',
         last_name: 'Doe',
         email: '[email protected]',
         admin: true)

  visit root_path
  fill_in 'email', with: '[email protected]'
  fill_in 'password', with: 'password1'
  click_button 'Log in'
  puts 'created'
end

#in spec/features/albums_spec.rb
feature "Albums", :type => :feature do
  before(:each) do
    login_admin
  end

  scenario 'do something' do
    save_and_open_page
  end
end

When I run this spec, it never finishes, either pass or fail. No error is thrown; it just sits there, showing Albums with the cursor beneath. 'created' is never put to stdout, and the page is never launched by the save_and_open_page call. Test log shows the erb file is rendered by my login action. This was all working prior to the rails 4.2 upgrade.

This only fails during the spec run - using the app in the browser works fine.

What am I missing here?

Upvotes: 1

Views: 496

Answers (1)

Cezary Baginski
Cezary Baginski

Reputation: 2105

UPDATE: possible problems related to capybara/rspec:

  1. Avoid creating models in feature specs, because they're created in a different thread. Instead, create the user using capybara steps (i.e. "sign up" the user every time).

  2. If you really need the database prepared for scenario in a way impossible to create from clicking around the site, implement a simple "admin" area in your app (you'll probably need one anyway) or admin API interface or something like a CSV upload option, etc.

  3. Otherwise, you can search for "capybara rspec database_cleaner append_after" for a setup to support creating models in feature specs, but I've found that none of the solutions are really bullet-proof. You could try: https://github.com/RailsApps/rails_apps_testing

I'm guessing your example is/was stuck on a database operation (waiting for db connection in other threads to end).

PREVIOUS ANSWER:

A few ideas:

  1. catch exceptions in the login_admin method and print them out using STDERR.puts
  2. remove the click_button and see if it fails as expected (shows you the login page)
  3. add a sleep 4 after the password is typed in
  4. separate the click_button into 2 calls (to see which one hangs):

    btn = find(:button, locator, options)
    STDERR.puts "found: #{btn.inspect}"
    btn.click 
    
  5. use bundle show capybara to find out where it is, edit the find (or click) method and put in STDERR.puts methods there to see what's wrong

Upvotes: 2

Related Questions