我正在实施一个懒惰的登录功能。我的黄瓜特征应该描述它:
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中的before过滤器使用,以便打开全新浏览器的用户将自动登录:
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中的before过滤器:
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而不是在我的控制器中使用它?
答案 0 :(得分: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
更新:
以下是我在使用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
答案 1 :(得分:9)
使用包含驱动程序方法的https://github.com/nruth/show_me_the_cookies。它有获取cookie,删除cookie的方法,以及创建名为create_cookie
的cookie的方法。
答案 2 :(得分:0)
我只需要测试Cookie值
灵感来自https://collectiveidea.com/blog/archives/2012/01/05/capybara-cucumber-and-how-the-cookie-crumbles
并移植到Rails 5.x
创建import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Positioned(
left: MediaQuery.of(context).size.width * 0.15,
child: AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0),
end: const Offset(0, 0),
).animate(CurvedAnimation(
curve: const Interval(0, 1, curve: Curves.easeIn),
parent: transitionAnimation)),
child: child);
},
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width * 0.85,
color: Colors.orange,
),
),
),
Positioned(
left: 0,
child: AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-1, 0),
end: const Offset(0, 0),
).animate(CurvedAnimation(
curve:
const Interval(.01, 0.25, curve: Curves.easeInExpo),
parent: transitionAnimation)),
child: child);
},
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width * 0.15,
color: Colors.black,
),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
transitionAnimation.repeat();
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => FirstPage(),
// ));
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
有内容
features/support/cookies.rb
然后进行测试
module Capybara
class Session
def cookies
@cookies ||= ActionDispatch::Request.new(Rails.application.env_config.deep_dup).cookie_jar
end
end
end
Before do
allow_any_instance_of(ActionDispatch::Request).to receive(:cookie_jar).and_return(page.cookies)
allow_any_instance_of(ActionDispatch::Request).to receive(:cookies).and_return(page.cookies)
end