brntsllvn
brntsllvn

Reputation: 951

Rails 4 Rspec Capybara: Extracting common test functionality to Ruby module not working

I want to extract sign_in out of my feature tests into a Ruby module, consistent with this Thoughtbot article. Feature is not seeing sign_in. What am I doing wrong?

Failures:
  1) User signs in with valid email and password
     Failure/Error: sign_in
     NameError:
       undefined local variable or method `sign_in' for #<RSpec::ExampleGroups::UserSignsIn:0x0000000238a958>
     # ./spec/features/sign_in_spec.rb:16:in `block (2 levels) in <top (required)>'
     # .bundle/binstubs/rspec:16:in `load'
     # .bundle/binstubs/rspec:16:in `<main>'
Finished in 0.17549 seconds (files took 2.77 seconds to load)
1 example, 1 failure

spec/features/sign_in_spec.rb

require 'rails_helper'

feature 'User signs in' do
  scenario 'with valid email and password' do
    sign_in
    expect(page).to have_content 'Signed in successfully'
  end
end

spec/support/features/session_helpers.rb

module Features
  module SessionHelpers
    def sign_in
      user = create(:user)
      visit '/'
      find(:xpath, "//a[@href='/users/sign_in']").click
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_button 'Sign in'
    end
  end
end

spec/support/features.rb

RSpec.configure do |config|
  config.include Features::SessionHelpers, type: :feature
end

rails_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)

abort("The Rails environment is running in production mode!") if Rails.env.production?

require 'spec_helper'
require 'rspec/rails'
require 'pry'
require 'faker'
require 'devise'
require 'email_spec'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods # Include Factory Girl syntax to simplify calls to factories
  config.use_transactional_fixtures = true
  config.include Devise::TestHelpers, type: :controller
  config.infer_spec_type_from_file_location!
  config.include(EmailSpec::Helpers)
  config.include(EmailSpec::Matchers)
end

spec_helper.rb

require 'codeclimate-test-reporter'
CodeClimate::TestReporter.start

require 'capybara/rspec'
require 'capybara/email/rspec'

RSpec.configure do |config|

  config.before(:each) { ActionMailer::Base.deliveries.clear } # uses email_spec gem to clear mail delivereies

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
end

Upvotes: 0

Views: 400

Answers (1)

Robin Daugherty
Robin Daugherty

Reputation: 7524

Do you have something in your rails_helper.rb or spec_helper.rb that will cause your helper to be loaded?

Change your rails_helper.rb to start with:

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)

abort("The Rails environment is running in production mode!") if Rails.env.production?

require 'spec_helper'
require 'rspec/rails'
require 'pry'
require 'faker'
require 'devise'
require 'email_spec'

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

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
    config.include Features::SessionHelpers, type: :feature
...

And delete spec/support/features.rb. This will ensure that the order of execution is correct, creating your Helper module (and anything else in your support folder) and then including the helper in RSpec's namespace.

Upvotes: 2

Related Questions