2013-10-11 78 views
16

我正在實現一個懶惰的登錄功能。我的黃瓜功能應該形容它: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]被設定。這將通過一個在我的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 

這是在我的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]返回零。我猜這只是水豚的事。那麼我真的必須在測試中設置一個cookie,而不是在我的控制器中使用該cookie?

回答

20

所以最終我在嘗試了很多不同的事情後發現了它。

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:

這裏是我的情況下,使用我使用硒一些測試:

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

未定義的方法'set_cookie'爲# Nakilon

+0

爲了不使用Capybara.current_session.driver.request.cookies。[]('auth_token')',爲什麼不使用Ruby的標準糖作爲散列 - 即'Capybara.current_session.driver.request.cookies ['auth_token']' – Arepo

+1

對於Poltergeist驅動程序,該方法(如[Poltergeist GitHub頁面](https://github.com/teampoltergeist/poltergeist)所記錄)是'page.driver.set_cookie()',它的3個參數是cookie的名字,它的值和一個選項哈希,用於設置cookie的到期值等等。 – sameers

相關問題