Rails + Cucumber/Capybara: Как установить/получить файлы cookie в тестах?
Я использую функцию ленивого входа. Моя функция огурца должна описать это:
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
И это мои определения шага:
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
Это то, что происходит, когда пользователь входит в систему: устанавливается cookies.signed[:auth_token]
. Это будет использоваться фильтром before в моем ApplicationController, чтобы пользователи, открывающие новый браузер, регистрировались автоматически:
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
конец
Это фильтр before в моем 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
Итак, проблема в том, что на последнем этапе моей функции огурца cookies.signed[:auth_token]
возвращает nil. Я предполагаю, что это всего лишь капибара. Так я действительно должен установить cookie в тесте, а не использовать тот, что в моем контроллере?
Ответы
Ответ 1
Итак, в конце концов, я понял это, пробовав много разных вещей.
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
UPDATE:
Вот что я использую, если я использую Selenium для некоторых тестов:
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
Ответ 2
Используйте https://github.com/nruth/show_me_the_cookies, который обертывает методы драйвера. Он имеет методы для получения файлов cookie, удаления файлов cookie и нового метода create_cookie
, который еще не был задокументирован в README.