我正在编写一个系统测试,以确认整个注册流程在Rails 7应用程序中运行(带有Clearance gem和电子邮件确认SignInGuard(。
测试一直运行良好,直到我";点击";电子邮件中的确认链接(在与Nokogiri解析后(。出于某种原因,电子邮件中的URL指向我的开发服务器(端口3000(,而不是指向测试服务器(端口4973649757/49991,等等(。
我可以查找测试服务器正在使用的当前端口(每次运行都会更改(,并替换URL的端口部分,但这似乎很麻烦。我是错过了什么显而易见的事情还是做错了什么?
邮件中的URL:confirm_email_url(@user.email_confirmation_token)
来自rails routes
:的路线
Prefix Verb URI Pattern Controller#Action
confirm_email GET /confirm_email/:token(.:format) email_confirmations#update
迄今为止的系统测试:
require "application_system_test_case"
require "test_helper"
require "action_mailer/test_helper"
class UserSignUpFlowTest < ApplicationSystemTestCase
include ActionMailer::TestHelper
test "Sign up for a user account" do
time = Time.now
email = "test_user_#{time.to_s(:number)}@example.com"
password = "Password#{time.to_s(:number)}!"
# Sign up (sends confirmation email)
visit sign_up_url
fill_in "Email", with: email
fill_in "Password", with: password
assert_emails 1 do
click_on "Sign up"
sleep 1 # Not sure why this is required... Hotwire/Turbo glitch?
end
assert_selector "span", text: I18n.t("flashes.confirmation_pending")
# Confirm
last_email = ActionMailer::Base.deliveries.last
parsed_email = Nokogiri::HTML(last_email.body.decoded)
target_link = parsed_email.at("a:contains('#{I18n.t("clearance_mailer.confirm_email.link_text")}')")
visit target_link["href"]
# ^^^^^^^^^^^^^^^^^^^^^^^^^
# This is the bit that fails... The link in the email points to my dev server (port 3000) rather than
# the test server (port 49736, 49757, 49991, etc). I only figured this out when my dev server crashed
# and Selenium started choking on a "net::ERR_CONNECTION_REFUSED" error
assert_selector "span", text: I18n.t("flashes.email_confirmed")
end
end
编辑
目前,我已经通过用visit hacky_way_to_fix_incorrect_port(target_link["href"])
:替换visit target_link["href"]
来解决这个问题
private
def hacky_way_to_fix_incorrect_port(url)
uri = URI(url)
return "#{root_url}#{uri.path}"
end
邮件中使用的URL由以下项指定:Rails.application.configure.action_mailer.default_url_options
在config/environments/test.rb
中,当我第一次安装Clearance:config.action_mailer.default_url_options = {host: "localhost:3000"}
时,我已将我的端口设置为3000
为了解决这个问题,我首先尝试动态指定端口,但建议的方法实际上不起作用,而且似乎没有必要。删除端口号足以使我的系统测试通过:config.action_mailer.default_url_options = {host: "localhost"}
正如Thomas Walpole所提到的,这之所以有效,是因为Capybara.always_include_port
被设置为true。使用此设置,访问http://localhost/confirm_email/<token>
(未指定端口(的尝试会自动重新路由到http://localhost:<port>/confirm_email/<token>
。
Capybara gem中的always_include_port
设置默认为false,但事实证明Rails在启动System Test服务器时将其设置为true。