在 RSpec 请求规范中使用 Capybara 时设置自定义请求标头的最佳方法是啥?

Posted

技术标签:

【中文标题】在 RSpec 请求规范中使用 Capybara 时设置自定义请求标头的最佳方法是啥?【英文标题】:What's the best way to set custom request headers when using Capybara in RSpec request specs?在 RSpec 请求规范中使用 Capybara 时设置自定义请求标头的最佳方法是什么? 【发布时间】:2011-10-27 02:07:46 【问题描述】:

我正在使用 set_headers 方法对 Capybara::Session 进行猴子修补,该方法分配给 Capybara::RackTest::Browser 的选项属性(我已将其从 attr_reader 更改为 attr_accessor)。

补丁:

class Capybara::RackTest::Browser
  attr_accessor :options
end

class Capybara::Session
  def set_headers(headers)
    if driver.browser.respond_to?(:options=) #because we've monkey patched it above
      options = driver.browser.options
      if options.nil? || options[:headers].nil?
        options ||= 
        options[:headers] = headers
      else
        options[:headers].merge!(headers)
      end
    else
      raise Capybara::NotSupportedByDriverError
    end
  end
end

在我的请求规范中,我正在做:

page.set_headers("REMOTE_ADDR" => "1.2.3.4")
visit root_path

这行得通,但我想知道是否有更好的方法,仅能够在请求上设置自定义 remote_ip/remote_addr 似乎有点矫枉过正。有什么想法吗?

【问题讨论】:

【参考方案1】:

如果您希望在所有请求上全局设置标头,您可以使用类似:

Capybara.register_driver :custom_headers_driver do |app|
  Capybara::RackTest::Driver.new(app, :headers => 'HTTP_FOO' => 'foobar')
end

请参阅 Capybara 1.1.2 中的 rack_test_driver_spec.rb 和 Capybara 的问题 #320,Setting up HTTP headers。

【讨论】:

【参考方案2】:

您是否需要使用 capybara 将自定义标头添加到 rspec 中的一个特定请求中?我在验收测试中使用了它。这是我对特定标题数据使用 get 方法的最佳方式。您可以评估响应页面上的特定元素。请参阅下面的示例:

get user_registration_path,  :invite => invite_token ,  'X_GEOIP_COUNTRY_CODE' => 'US'  
expect(assigns(:ip_country)).to eq('US')
response.body.should have_selector("input#currency_usd[checked='checked']")

我希望它有所帮助。

【讨论】:

【参考方案3】:

我发现使用默认 Capybara::RackTest 驱动程序时可以修改标头。

有一个方法 Capybara::RackTest::Browser#process 在最终发送之前准备一个请求 (https://www.rubydoc.info/gems/capybara/Capybara%2FRackTest%2FBrowser:process)。正如您在代码中看到的那样,请求标头是从options[:headers] 构建的。 options 实际上是指driver.options 属性。因此,您可以通过修改此哈希来设置任何标头。

这是我的带有自定义标头的功能规范示例


let(:headers) do
  
    "YOUR_CUSTOM_HEADER_1" => "foo",
    "YOUR_CUSTOM_HEADER_2" => "bar",
    ...
  
end 

before(:each) do
  @origin_headers = page.driver.options[:headers]
  page.driver.options[:headers] ||= 
  page.driver.options[:headers].merge!(headers)
end

after(:each) do
  page.driver.options[:headers] = @origin_headers
end

经测试

capybara:3.13.2(RackTest 驱动程序) rspec:3.8 导轨:5.2.2

附:尚未使用硒驱动程序对其进行测试。但可能它以类似的方式工作。

【讨论】:

以上是关于在 RSpec 请求规范中使用 Capybara 时设置自定义请求标头的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 rspec 中使用 capybara 点击下拉选项

Capybara-webkit、rspec 集成规范和 xvfb:webkit_server:致命 IO 错误:客户端被杀死

如何在 Capybara 和 RSpec 中测试 CSV 文件下载?

在 Rails 中使用 RSpec 和 Capybara 时未定义的方法“访问”

如何使用rails cucumber,rspec,capybara在视图(dhtml)中测试动态部分?

使用 RSpec + capybara-webkit 检查 JS 框是不是存在