RSpec + Capybara + Devise Login Tests

For the new version of Connect.Me (in development), the interface is mostly driven through AJAX interactions. In the past, I’ve used Cucumber + Capybara to test JavaScript, but I really don’t like the Cucumber syntax and slow tests. I recently switched to RSpec request specs with Capybara. The only problem is testing testing JS on pages that require a login.

Since Capybara runs in a different thread from the tests, session data is not available. So the Devise sign_in method does nothing for Capybara.

There are basically two solutions to get Capybara to authenticate:

  1. Use Capybara to login through a Devise login form by posting the user’s email and password
  2. Set session data in Capybara to simulate a login (basically do the same thing that Devise’s sign_in does)

For speed of tests reasons, I’d prefer to just set session data. After Googling around, I found this solution and modified it a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# spec/support/request_helpers.rb
require 'spec_helper'
include Warden::Test::Helpers

module RequestHelpers
  def create_logged_in_user
    user = Factory(:user)
    login(user)
    user
  end

  def login(user)
    login_as user, scope: :user
  end
end

Now you just need to call create_logged_in_user and you’re good to go.

1
2
3
4
5
6
7
8
describe "user settings" do
  let(:authed_user) { create_logged_in_user }

  it "should allow access" do
    visit user_settings_path(authed_user)
    # should be good!
  end
end