2013-10-11 5 views
16

Ich implementiere eine faule Login-Funktion. Meine Gurke Funktion sollte es beschreiben:Rails + Cucumber/Capybara: Wie können Cookies in Tests gesetzt/abgerufen werden?

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 

Und das sind meine Schritt Definitionen:

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 

Dies ist, was passiert, wenn sich ein Benutzer anmeldet: der cookies.signed[:auth_token] gesetzt wird. Dies wird durch einen vor dem Filter in meinem Application verwendet werden, so dass Benutzer, die einen neuen Browser öffnen automatisch protokolliert werden:

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 

Ende

Dies ist das ist, bevor die Filter in meinem Application:

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 

Also das Problem ist, dass im letzten Schritt meiner Gurke-Funktion, cookies.signed[:auth_token] gibt Null zurück. Ich schätze, das ist nur eine Capybara-Sache. Also muss ich tatsächlich einen Cookie im Test setzen, anstatt den in meinem Controller zu verwenden?

Antwort

20

Also irgendwann habe ich es herausgefunden, nachdem ich viele verschiedene Dinge ausprobiert habe.

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:

Hier ist, was ich für den Fall, verwende ich bin mit Selen für einige der 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 
+2

undefined Methode 'set_cookie 'für # Nakilon

+0

Anstelle von' Capybara.current_session.driver.request.cookies. [] ('Auth_token')', verwenden Sie Ruby's Standard Zucker für Hashes - Dh 'Capybara.current_session.driver.request.cookies ['auth_token']' – Arepo

+1

Für den Poltergeist-Treiber ist die Methode (wie auf [der Poltergeist GitHub-Seite] (https://github.com/teampoltergeist/poltergeist) dokumentiert) 'page.driver.set_cookie()', und seine 3 Argumente sind der Name des Cookies, sein Wert und ein Options-Hash, um unter anderem den Ablaufwert des Cookies festzulegen. – sameers

7

Verwenden https://github.com/nruth/show_me_the_cookies, die die Fahrer Methoden wickelt. Es gibt Methoden zum Abrufen von Cookies, zum Löschen von Cookies und eine neue Methode create_cookie, die in der README noch nicht dokumentiert ist.

Verwandte Themen