为什么 Capybara 在访问时不将服务器的端口发送到浏览器,即 root_path?

Why is Capybara not sending the server's port to the browser on visit i.e root_path?

在 ruby 2.6.1 中,rails 6.0 我正在尝试让 Capybara 启动测试服务器,并可以选择显示或不显示 chrome 使用 capybara 3.35.3 和 cuprite 0.13 的案例,方法是打开或关闭无头选项。

我的发现和问题:

理想情况下不要定义 Capybara.server_hostCapybara.server_port 而是使用 Capybara.always_include_port = true ,根据 Capybara 的文档,这意味着无论何时总是将端口发送或附加到服务器主机地址visit 用于测试用例,浏览器中的 url 将是 http://127.0.0.1:xxxx/。这种方法的问题是 Capybara.always_include_port 没有这样做,而是在服务器 运行 之后,浏览器转到 http://127.0.0.1/

如果我设置 Capybara.server_port,无论 Capybara.always_include_port.

的状态如何,浏览器在 bundle exec rspec 时仍然没有端口

供参考,我之所以在每个case前用CAPYBARA_APP_HOSThost!而不用一般的Capybara.app_host是因为Rails会自动改变后者的值到 127.0.0.1,所以这更像是从 evilmartians 获得的解决方案。

注释的代码行是为了展示我提到的观点。

值得注意的是,当前环境唯一可行的方法是设置 Capybara.run_server = false 并取消注释 server_hostserver_portCAPYBARA_APP_HOSThost! 行,然后使用 rails s 启动单独的 rails 服务器,然后使用 运行 规格,这不太理想。

有什么指点吗?谢谢

我的rails_helper.rb:

require 'spec_helper'

ENV['RAILS_ENV'] ||= 'test'

require File.expand_path('../config/environment', __dir__)

abort("The Rails environment is running in production mode!") if Rails.env.production?

require 'rspec/rails'
require 'capybara/rails'
require "capybara/cuprite"

Dir[File.join(__dir__, "system/support/**/*.rb")].sort.each { |file| require file }

Capybara.default_driver = Capybara.javascript_driver  = Capybara.current_driver = :cuprite
Capybara.default_max_wait_time = 5
Capybara.default_normalize_ws = true

Capybara.server = :puma
Capybara.always_include_port = true
# Capybara.server_host = '0.0.0.0'
# Capybara.server_port = 3030
# CAPYBARA_APP_HOST = "http://#{Capybara.server_host}:#{Capybara.server_port}".freeze

Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(
    app,
    **{
      window_size: [1200, 800],
      browser_options: {},
      process_timeout: 10,
      inspector: true,
      headless: !ENV["HEADLESS"].in?(%w[n 0 no false])
    }
  )
end

begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/factories"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!

  config.prepend_before(:each, type: :system) do
    # host! CAPYBARA_APP_HOST
    # Use JS driver always
    driven_by Capybara.javascript_driver
  end
end

所以我决定调试 lib/capybara/session.rb 并注意到 always_include_port 实际上在正常工作,结果确实是启动了一个带有完整 uri 的驱动程序;一个 url + 端口。

问题是当 运行 规范关于在应用程序控制器中具有 force_ssl if: :ssl_configured? 时我一直忽略的警告。我整理了那一行,一切都按预期工作。

教训:不要忽略运行时警告。