0

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
brntsllvn
  • 931
  • 11
  • 18

1 Answers1

2

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.

Robin Daugherty
  • 7,115
  • 4
  • 45
  • 59
  • added rails_helper.rb and spec_helper.rb to clarify. – brntsllvn Sep 02 '15 at 07:19
  • Thanks for your help on this. Regarding this line Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } ... I am getting ... /spec/spec_helper.rb:7:in `': uninitialized constant Rails (NameError) ... Any ideas? Trying to debug on my end, but letting you know current status of this. – brntsllvn Sep 02 '15 at 17:27
  • Hard-coding the file path, i.e. require 'app-stuff/spec/support/features/session_helpers.rb' worked...but I like your more-general, environment-independent solution. – brntsllvn Sep 02 '15 at 17:39
  • Edited answer to make it work. Broadly, from reading this SO post (http://stackoverflow.com/questions/24145329/how-is-spec-rails-helper-rb-different-from-spec-spec-helper-rb-do-i-need-it) - please correct if I am mistaken - spec_helper.rb is independent of Rails and so it makes sense that Rails.root is not recognized. To fix I required rails_helper.rb in spec_helper.rb (which seems circular to me...but it works). Improvements more than welcome! – brntsllvn Sep 02 '15 at 22:09
  • 1
    I've re-edited. Sorry about that, it does require Rails to already be loaded. The idea is that spec_helper is independent of Rails, but rails_helper requires it, so it shouldn't also require spec_helper. This also assumes that specs require 'rails_helper.rb' instead 'spec_helper.rb' which is now the default when using rspec-rails. – Robin Daugherty Sep 03 '15 at 19:21
  • Great, thanks. Made the change on my end. Works like a charm. – brntsllvn Sep 03 '15 at 23:04