Session resets after form submission and redirect when testing with RSpec & Capybara

838 views
Skip to first unread message

Vell

unread,
May 12, 2016, 2:52:34 PM5/12/16
to Devise
Hello all,

I am having an issue where my session resets after I submit a form within an RSpec feature test. I am kicked out and sent to the login page after submitting the form. This issue does not happen when I am doing this process manually through the browser. It is only happening when I am running an RSpec feature test.

I can't seem to figure out what the issue is and I have been able to reproduce this in both Chrome and Firefox and also with a Vanilla rails application with a minimal amount of code. 

I am hoping that someone can help me determine where my issue is coming from. I have looked what I believe to be the obvious places but can't seem to figure out what is missing or misconfigured.

Below are the relevant files that I have been working with to try and solve this issue:

Gems
devise 3.5.6
rails
4.2.6
rspec
-rails 3.4.2
capybara
2.7.1
selenium
-webdriver 2.53.0
chromedriver
-helper 1.0.0

spec/rails_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__)
# Prevent database truncation if the environment is production
abort
("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'simplecov'
SimpleCov.start
require 'pry'

if ENV['CHROME']
 
Capybara.register_driver :selenium do |app|
   
Capybara::Selenium::Driver.new(app, :browser => :chrome)
 
end
end

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

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|

  config
.include(JavascriptHelper, type: :feature)
  config
.fixture_path = "#{::Rails.root}/spec/fixtures"
  config
.use_transactional_fixtures = false
  config
.infer_spec_type_from_file_location!
  config
.filter_rails_from_backtrace!
end


spec/support/devise.rb
RSpec.configure do |config|
  config
.include Devise::TestHelpers, type: :controller
  config
.include Devise::TestHelpers, type: :view
end

config/routes.rb
Rails.application.routes.draw do
  devise_for
:users
 
get 'ui(/:action)', controller: 'ui'
  root
'pages#index'
  resources
:drinks
end

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action
:authenticate_user!

  protect_from_forgery
with: :exception

 
private

 
def error_message
   
"There were errors!"
 
end
end

app/controllers/drinks_controller.rb
class DrinksController < ApplicationController
  before_action
:drink, only: [:show, :edit, :update, :destroy]
 
def index
   
@drinks = Drink.for_user(current_user)
 
end
 
 
def new
   
@drink = Drink.new
 
end
 
 
def create
   
@drink = Drink.new(drink_params.merge({creator: current_user}))
   
if @drink.save
      flash
[:success] = 'Drink created'
      redirect_to
@drink
   
else
      flash
[:error] = error_message
      render
:new
   
end
 
end
 
 
def update
   
if @drink.update(drink_params.merge({updater: current_user}))
      flash
[:success] = 'Drink updated'
      redirect_to
@drink
   
else
      flash
[:error] = error_message
      render
:edit
   
end
 
end
 
 
def destroy
   
@drink.destroy
    flash
[:success] = 'Drink deleted'
    redirect_to drinks_path
 
end
 
 
private
 
 
def drink
   
@drink = Drink.find(params[:id])
 
end
 
 
def drink_params
   
params.require(:drink).permit(:name, :note, :public)
 
end
end

spec/features/drinks/new_drink_spec.rb
require 'rails_helper'


feature
'drink management' do
  scenario
'user can create a new drink', js: true do
    user = create(:user) # using factory girl 
    visit drinks_path
    fill_in 'user_email', with: user.email
    fill_in 'user_password', with: CONFIG[:test_user_password]
    click_button 'Log in'
    click_link 'Drinks'
    click_link
'New Drink'
    fill_in
'drink_name', with: Faker::Lorem.word
    fill_in
'drink_note', with: Faker::Lorem.paragraph
    click_button
'Create Drink'
    expect
(page).to have_content 'Drink created'
 
end
end

spec/factories/user.rb
FactoryGirl.define do
  factory
:user do
    sequence
(:email) {|n| "#{n}_#{Faker::Internet.email}"}
    password
'****'
    password_confirmation
'****'
 
end
end

RSpec output
Failures:


 
1) drink management user can create a new drink
     
Failure/Error: expect(page).to have_content 'Drink created'
       expected to find text
"Drink created" in "Drink Notes About Sign In You need to sign in or sign up before continuing. Log in Email Password Remember me Sign up Forgot your password?"
     
# ./spec/features/drinks/new_drink_spec.rb:15:in `block (2 levels) in <top (required)>'


Finished in 10.12 seconds (files took 3.23 seconds to load)
34 examples, 1 failure, 1 pending


Failed examples:


rspec
./spec/features/drinks/new_drink_spec.rb:4 # drink management user can create a new drink

Any help is greatly appreciated.

Thanks

Michael Over

unread,
Sep 19, 2016, 3:19:28 PM9/19/16
to Devise
Old post I know... but did you ever figure this out? I've run into the same issue and can't figure it out for the life of me. Everything in the app works fine but in my rspec feature spec, the session gets reset after the controller logs the user in and redirects to the home page. 

Jason Fleetwood-Boldt

unread,
Sep 19, 2016, 3:26:01 PM9/19/16
to plataforma...@googlegroups.com
tail your test logs while you run the test and look for "CSRF Authentication invalid" --- 

tail -f log/test.log

99 times out of 100 when sessions drop for me it is because a form was submitted with an invalid CSRF token. But of course it could be anything


--

---
You received this message because you are subscribed to the Google Groups "Devise" group.
To unsubscribe from this group and stop receiving emails from it, send an email to plataformatec-de...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

If you'd like to reply by encrypted email you can find my public key on jasonfleetwoodboldt.com (more about setting GPG: https://gpgtools.org

Vell

unread,
Sep 20, 2016, 9:10:39 AM9/20/16
to Devise
Mike,

Yes my issue was resolved.

The issue I had was related to how I was setting the password for the test user in factorygirl. 

In my case I was using a configuration setting to set the password. For instance I had a config/application.yml file that had something like:

test:
  password
: some password


There really wasn't a need for this so once I hardcoded the password in the factory itself, the issue went away. 

I still have no idea why it would matter where the password is coming from, but that is what solved it for me. Some one else actually discovered the solution as a last ditch suggestion since there was nothing in the logs or anywhere else that pointed to a specific issue.

I hope this helps.

Vell

unread,
Sep 20, 2016, 9:19:07 AM9/20/16
to Devise
Mike,

I apologize, After looking at my original email to the forum, it was that I hardcoded the password in the factory but in the feature I used that same password but it was in a  configuration setting. I didn't need a test user password in both places, so I removed the configuration setting in my config/application.yml file and hardcoded the password directly in the feature. 

So instead of
fill_in 'user_password', with: config[:test_user_password]

I used
fill_in 'user_password, with: 'somepassword'

This is what solved it for me.
Reply all
Reply to author
Forward
0 new messages