
[英]Cucumber devise sign in step failing (rails 3.2, cucumber, capybara, rspec)
[英]Testing sign up and sign in with Capybara (Rails, RSpec, Devise)
我编写了以下功能规范,以在具有Devise的Rails 4.2.8应用程序中测试注册,登录,密码恢复和帐户锁定行为。
测试工作。 但是,我对Capybara还是比较陌生,所以我希望您提出有关如何提高其可读性,可维护性,干燥度,速度,降低脆性等方面的建议。
电子邮件唯一性,密码强度等验证是在User
模型规范中执行的。 因此,我没有在这里重新测试这些行为。
# spec/features/user_registration_spec.rb
require 'rails_helper'
def login_via_form(email, password)
expect(page).to have_current_url("/users/sign_in")
fill_in "Email", with: email
fill_in "Password", with: password
click_button "Sign in"
end
RSpec::Matchers.define :be_logged_in do |user_first_name|
match do |page|
expect(page).to have_current_path "/"
expect(page).to have_content "Hello #{user_first_name}"
end
failure_message do |actual|
"expected the current path to be /, actual path is #{page.current_path}" \
"\nexpected to find a 'Hello #{user_first_name}' in '#{page.text}'."
end
end
describe "User self-management", type: :feature, js: true do
let!(:user) { FactoryGirl.create(:user) }
let(:valid_attributes) { FactoryGirl.attributes_for(:user) }
it "registers a new user" do
visit "/"
click_link "Sign up"
fill_in "Email", with: valid_attributes[:email]
fill_in "Password", with: valid_attributes[:password]
fill_in "Password confirmation", with: valid_attributes[:password]
fill_in "First name", with: valid_attributes[:first_name]
fill_in "Last name", with: valid_attributes[:last_name]
select "United States", from: "Country"
select "New York", from: "State"
select "New York", from: "City"
fill_in "Sangha", with: "My Sangha"
fill_in "Phone number", with: "+1 212-555-0187"
fill_in "Facebook url", with: "http://www.facebook.com/johndoe"
click_button "Sign up"
# The user may only login *after* confirming her e-mail
expect(page).to have_content "A message with a confirmation link has been" \
" sent to your email address. Please follow the link to activate your" \
" account."
expect(page).to have_current_path "/users/sign_in"
# Find email sent to the given recipient and set the current_email variable
# Implemented by https://github.com/DockYard/capybara-email
open_email(valid_attributes[:email])
expect(current_email.subject).to eq "Confirmation instructions"
current_email.click_link "Confirm my account"
expect(page).to have_content "Your email address has been successfully " \
"confirmed."
login_via_form(valid_attributes[:email],
valid_attributes[:password])
expect(page).to have_content "Signed in successfully."
expect(page).to be_logged_in(valid_attributes[:first_name])
end
it "performs password recovery (creates a new password)" do
visit "/users/sign_in"
click_link "Forgot your password?"
fill_in "Email", with: user.email
click_button "Send me reset password instructions"
expect(page).to have_text "You will receive an email with instructions " \
"on how to reset your password in a few minutes."
# Find email sent to the given recipient and set the current_email variable
open_email(user.email)
expect(current_email.subject).to eq "Reset password instructions"
current_email.click_link "Change my password"
fill_in "New password", with: valid_attributes[:password]
fill_in "Confirm new password", with: valid_attributes[:password]
click_button "Change my password"
expect(page).to have_content "Your password has been changed " \
"successfully. You are now signed in."
expect(page).to be_logged_in(user.first_name)
open_email(user.email)
expect(current_email.subject).to eq "Password Changed"
expect(current_email.body). to have_text "We're contacting you to notify " \
"you that your password has been changed."
end
describe "resend confirmation e-mail" do
context "with an already confirmed e-mail address" do
it "warns the user and does not send a new confirmation e-mail" do
# Our factory creates users with confirmed e-mails
visit "/users/sign_in"
click_link "Didn't receive confirmation instructions?"
fill_in "Email", with: user.email
expect {
click_button "Resend confirmation instructions"
}.not_to change(ActionMailer::Base.deliveries, :count)
expect(page).to have_text "Email was already confirmed"
end
end
context "with an unconfirmed e-mail address" do
it "sends a new confirmation e-mail" do
# Unconfirm user (our factory creates users with confirmed e-mails)
user.update(confirmed_at: nil)
visit "/users/sign_in"
click_link "Didn't receive confirmation instructions?"
fill_in "Email", with: user.email
click_button "Resend confirmation instructions"
expect(page).to have_text "You will receive an email with " \
"instructions for how to confirm your email address in a few minutes."
open_email(user.email)
expect(current_email.subject).to eq "Confirmation instructions"
current_email.click_link "Confirm my account"
expect(page).to have_content "Your email address has been " \
"successfully confirmed."
login_via_form(user.email, user.password)
expect(page).to have_content "Signed in successfully."
expect(page).to be_logged_in(user.first_name)
end
end
end
it "locks the account after 5 failed login attempts" do
visit "/users/sign_in"
3.times do
login_via_form(user.email, "bogus")
expect(page).to have_text "Invalid Email or password."
end
login_via_form(user.email, "bogus")
expect(page).to have_text "You have one more attempt before your " \
"account is locked."
login_via_form(user.email, "bogus")
expect(page).to have_text "Your account is locked."
open_email(user.email)
expect(current_email.subject).to eq "Unlock instructions"
current_email.click_link "Unlock my account"
expect(page).to have_content "Your account has been unlocked " \
"successfully. Please sign in to continue."
login_via_form(user.email, user.password)
expect(page).to have_content "Signed in successfully."
expect(page).to be_logged_in(user.first_name)
end
context "account is locked, didn't receive unlocking instructions" do
it "sends a new unlocking instructions e-mail" do
user.update(locked_at: DateTime.now)
visit "/users/sign_in"
click_link "Didn't receive unlock instructions?"
fill_in "Email", with: user.email
click_button "Resend unlock instructions"
expect(page).to have_text "You will receive an email with instructions " \
"for how to unlock your account in a few minutes."
open_email(user.email)
expect(current_email.subject).to eq "Unlock instructions"
current_email.click_link "Unlock my account"
expect(page).to have_content "Your account has been unlocked " \
"successfully. Please sign in to continue."
login_via_form(user.email, user.password)
expect(page).to have_content "Signed in successfully."
expect(page).to be_logged_in(user.first_name)
end
end
context "account is not locked, attempts to re-send unlocking instructions" do
it "warns the user and does not send a new confirmation e-mail" do
# Our factory creates users with confirmed e-mails
visit "/users/sign_in"
click_link "Didn't receive unlock instructions?"
fill_in "Email", with: user.email
expect {
click_button "Resend unlock instructions"
}.not_to change(ActionMailer::Base.deliveries, :count)
expect(page).to have_text "Email was not locked"
end
end
end
谢谢。
最好在https://codereview.stackexchange.com/上接收
也就是说,对于open_email
如何神奇地设置current_email
,我并不open_email
。 我希望该方法返回它,如果可能,您对照该返回值进行检查; 这可能是多线程应用程序或测试套件的问题。
您对页面上文本的期望非常脆弱。 如果该副本有任何更改,则还需要重新进行测试。 就个人而言,我可以接受,但是如果您将其与半松散的正则表达式匹配,或者将这些字符串放入翻译文件中,并对照I18n.t('email.confirmation.message')
进行检查, I18n.t('email.confirmation.message')
您节省一些精力I18n.t('email.confirmation.message')
。
为了提高性能,您可能希望使用不使用login_via_form
的登录方法,我认为Devise测试帮助程序仍包括login_as
,它可以直接为您设置登录会话。
总的来说,我认为这是一项伟大的工作。 保持!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.