0
votes

I'm using devise to handle the authentication process. I am now developing integration tests for my application, starting with the sign in process.

RSpec.describe 'sign in', type: :feature, js: true do
  let!(:user) { create(:user)}

  scenario 'sign in with correct credentials' do
    visit new_user_session_path
    fill_in 'Login', with: '[email protected]'
    fill_in 'Password', with: 'password'
    click_on 'Sign in'
    expect(current_path).to eq(signed_in_path)
  end
end

After the test above clicks on the "Sign in" button, a session is created as intended and then the user is redirected to the signed_in_path. After this redirection, the controller for this path is called and it has a before_action :authenticate_user.

The problem is, after the redirect, this authenticate_user method doesn't recognize the current_user anymore which makes it redirect back to the sign in page and causes the test to fail.

What is causing this loss of session? How can I fix it?

PS: I've included config.include Devise::Test::IntegrationHelpers, type: :feature to my rails_helper.rb and the sign_in helper works great, but I shouldn't use this to test if the sign is page is working correctly.

1
You should at least change your spec to fill_in 'Login', with: user.email etc instead of hardcoding the values.max

1 Answers

1
votes

A few potential issues here but the most likely is that click_on doesn't wait for any actions triggered by the click to occur (because it has no way of knowing what those actions will be). This is why most (if not all) of Capybaras finders/matchers/assertions/etc have waiting/retrying builtin, in order to give the site/app time for things to occur. The problem is you've not using the Capybara provided matcher, so your expectation just fails immediately, the tests ends, and the database connection is cleaned up (probably while the user is being redirected). To fix this you should always use the Capybara provided matchers when dealing with Capybara returned values/objects (ie never use eq with the current path)

expect(page).to have_current_path(signed_in_path)

A second potential (or could be both) is if the domain being redirected to is not he same as the domain login is occurring on. For instance if login is happening at http://127.0.0.1/... but redirection is going to http://localhost... then the session cookie will be set for the wrong domain and the user will no longer be logged in.