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

问题描述:

我正在用set_headers方法修补Capybara :: Session,该方法分配给Capybara :: RackTest :: Browser的options属性(我已经从attr_reader更改为attr_accessor)。

I'm monkey patching Capybara::Session with a set_headers method that assigns to Capybara::RackTest::Browser's options attribute (which I've changed from an attr_reader to an 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似乎有点过头了。有什么想法吗?

This works, but I'm wondering if there's a better way, it seems a bit overkill to just be able to set a custom remote_ip/remote_addr on a request. Any thoughts?

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

I've discovered an ability to modify headers when using the default Capybara::RackTest driver.

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

There's a method Capybara::RackTest::Browser#process which prepares a request before finaly being sent (https://www.rubydoc.info/gems/capybara/Capybara%2FRackTest%2FBrowser:process). As you can see there in the code the request headers are built from the options[:headers]. The options actually refers to the driver.options attribute. So you can set any headers by modifying this hash.

以下是我的带有自定义标题的功能规格示例


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

经过测试


  • 水豚:3.13.2(RackTest驱动程序)

  • rspec:3.8

  • 轨道:5.2.2

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

P.S. Haven't tested it with selenium driver yet. But probably it works in a similar way.