问题描述
我正在实施一个延迟登录功能。我的黄瓜功能应该描述它:
功能:用户登录
场景: $ b由于我没有注销最后一次我在网站
当我去主页
然后我应该自动登录
这些是我的步骤定义:
/ ^我没有注销最后一次我在网站$ /)do
user = FactoryGirl.create(:user)
访问new_user_session_path
fill_in('user [email] ',with:user.email)
fill_in('user [password]',with:'test123')
click_button('登录')
Capybara.reset_sessions!
end
当(/ ^我去主页$ /)do
访问root_path
end
然后应该自动记入$ /)do#< - 失败
page.should have_content(Logout)
end
这是用户登录时会发生的情况: cookies.signed [:auth_token] 设置。这将由我的ApplicationController中的前过滤器使用,以便打开一个新的浏览器的用户将自动登录:
SessionsController< Devise :: SessionsController
def create
super
如果user_signed_in?
puts'yesssssss'
session [:user_id] = current_user.id
current_user.remember_me!如果current_user.remember_token.blank?
cookies.signed [:auth_token] = {
:value => current_user.remember_token,
:domain => mysite.com,
:secure => !(Rails.env.test?|| Rails.env.development?)
}
putscurrent_user.remember_token =#{current_user.remember_token}
puts'cookies:'
puts cookies.signed [:auth_token]
end
end
end
这是我的ApplicationController中的前过滤器:
def sign_in_through_cookie
logger.info通过cookie登录
puts通过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])
如果user.blank返回false?
sign_in(user)
put'success'
return true
else
return false
end
end
$所以问题是在我的黄瓜功能的最后一步, cookies.signed [:auth_token] / code>返回nil。我猜这只是一个水豚的事情。因此,我实际上必须在测试中设置一个cookie,而不是使用我的控制器中的一个。解决方案给定(/ ^我最后一次没有注销在网站$ /)do
user = FactoryGirl.create(:user)
访问new_user_session_path
fill_in('user [email]',带:user.email)
fill_in ('user [password]',with:'test123')
click_button('登录')
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
当(/ ^我去主页$ /)do
访问root_path
end
然后(/ ^我应该自动记入$ /)do
page.should have_content(Logout)
end
更新:
我使用Selenium进行一些测试:
如果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
输入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
I'm implementing a lazy login feature. My cucumber feature should describe it:
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 inAnd these are my step definitions:
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") endThis is what happens when a user logs in: the cookies.signed[:auth_token] gets set. This will be used by a before filter in my ApplicationController so that users who open a fresh browser will be logged in automatically:
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 endend
This is the before filter in my 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 endSo the issue is that in the last step of my cucumber feature, cookies.signed[:auth_token] returns nil. I'm guessing this is just a capybara thing. So do I actually have to set a cookie in the test as opposed to using the one in my controller?
解决方案So eventually I figured it out after trying a lot of different things.
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") endUPDATE:
Here's what I use in case I'm using Selenium for some of the tests:
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
这篇关于Rails + Cucumber / Capybara:如何在测试中设置/检索Cookie?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!