2013-10-11 24 views
16

Sto implementando una funzionalità di accesso lazy. La mia caratteristica cetriolo dovrebbe descriverlo:Rails + Cucumber/Capybara: come impostare/recuperare i cookie nei test?

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 

E questi sono i miei definizioni step:

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 

Questo è ciò che accade quando un utente accede a: la cookies.signed[:auth_token] viene impostata. Questo sarà utilizzato da un prima del filtro nella mia ApplicationController modo che gli utenti che aprono un browser fresco verranno registrati automaticamente:

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 

fine

Questa è la prima del filtro nella mia 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 

Quindi il problema è che nell'ultimo passaggio della funzione cetriolo, cookies.signed[:auth_token] restituisce zero. Immagino che questa sia solo una cosa da capibara. Quindi devo effettivamente impostare un cookie nel test invece di usare quello nel mio controller?

risposta

20

Così alla fine ho capito dopo aver provato un sacco di cose diverse.

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:

Ecco quello che uso nel caso in cui sto usando Selenio per alcuni dei test:

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

metodo non definito 'set_cookie 'per # Nakilon

+0

Invece di' Capybara.current_session.driver.request.cookies. [] (' Auth_token ') ', perché non utilizzare lo zucchero standard di Ruby per gli hash - cioè 'Capybara.current_session.driver.request.cookies ['auth_token']' – Arepo

+1

Per il driver Poltergeist, il metodo (come documentato su [la pagina GitHub di Poltergeist] (https://github.com/teampoltergeist/poltergeist)) è 'page.driver.set_cookie()', e i suoi 3 argomenti sono il nome del cookie, il suo valore e un hash delle opzioni per l'impostazione, tra le altre cose, del valore di scadenza del cookie. – sameers

Problemi correlati