ruby-on-rails - test - rspec in rails 5
Rails+Cucumber/Capybara: ¿Cómo configurar/recuperar cookies en las pruebas? (2)
Estoy implementando una función de inicio de sesión lento. Mi característica de pepino debería describirlo:
Feature: User log in
Scenario: Lazy login
Given I didn''t log out the last time I was on the site
When I go to the homepage
Then I should automatically be logged in
Y estas son mis definiciones de paso:
Given(/^I didn''t log out the last time I was on the site$/) do
user = FactoryGirl.create(:user)
visit new_user_session_path
fill_in(''user[email]'', with: user.email)
fill_in(''user[password]'', with: ''test123'')
click_button(''Sign in'')
Capybara.reset_sessions!
end
When(/^I go to the homepage$/) do
visit root_path
end
Then(/^I should automatically be logged in$/) do #<-- Fails here
page.should have_content("Logout")
end
Esto es lo que sucede cuando un usuario inicia sesión: se establece el cookies.signed[:auth_token]
. Esto será utilizado por un filtro anterior en mi ApplicationController para que los usuarios que abran un nuevo navegador inicien sesión automáticamente:
class SessionsController < Devise::SessionsController
def create
super
if user_signed_in?
puts ''yesssssss''
session[:user_id] = current_user.id
current_user.remember_me! if current_user.remember_token.blank?
cookies.signed[:auth_token] = {
:value => current_user.remember_token,
:domain => "mysite.com",
:secure => !(Rails.env.test? || Rails.env.development?)
}
puts "current_user.remember_token = #{current_user.remember_token}"
puts ''cookies:''
puts cookies.signed[:auth_token]
end
end
fin
Este es el filtro anterior en mi ApplicationController:
def sign_in_through_cookie
logger.info "logging in by cookie"
puts "logging in by cookie"
puts cookies.signed[:auth_token] #<-- PROBLEM: this returns nil.
return true if !current_user.nil?
if !cookies[:auth_token].nil? && cookies[:auth_token] != ''''
user = User.find_by_remember_token(cookies.signed[:auth_token])
return false if user.blank?
sign_in(user)
puts ''success''
return true
else
return false
end
end
Entonces, el problema es que en el último paso de mi función de pepino, cookies.signed[:auth_token]
devuelve nil. Supongo que esto es sólo una cosa capibara. Entonces, ¿tengo que configurar una cookie en la prueba en lugar de usar la que está en mi controlador?
Así que eventualmente lo resolví después de probar muchas cosas diferentes.
Given(/^I didn''t log out the last time I was on the site$/) do
user = FactoryGirl.create(:user)
visit new_user_session_path
fill_in(''user[email]'', with: user.email)
fill_in(''user[password]'', with: ''test123'')
click_button(''Sign in'')
Capybara.current_session.driver.request.cookies.[](''auth_token'').should_not be_nil
auth_token_value = Capybara.current_session.driver.request.cookies.[](''auth_token'')
Capybara.reset_sessions!
page.driver.browser.set_cookie("auth_token=#{auth_token_value}")
end
When(/^I go to the homepage$/) do
visit root_path
end
Then(/^I should automatically be logged in$/) do
page.should have_content("Logout")
end
ACTUALIZAR:
Esto es lo que uso en caso de que esté usando Selenium para algunas de las pruebas:
if Capybara.current_session.driver.class == Capybara::Selenium::Driver
auth_token = page.driver.browser.manage.cookie_named(''auth_token'')[:value]
page.driver.browser.manage.delete_all_cookies
page.driver.browser.manage.add_cookie(:name => "auth_token", :value => auth_token)
else
puts "cookies = #{Capybara.current_session.driver.request.cookies}"
Capybara.current_session.driver.request.cookies.[](''auth_token'').should_not be_nil
auth_token_value = Capybara.current_session.driver.request.cookies.[](''auth_token'')
Capybara.reset_sessions!
page.driver.browser.set_cookie("auth_token=#{auth_token_value}")
end
Utilice https://github.com/nruth/show_me_the_cookies que envuelve los métodos del controlador. Tiene métodos para obtener cookies, eliminar cookies y un método para crear cookies llamado create_cookie
.