在 Rails 3 中使用 Cucumber/Capybara,如何设置自定义用户代理字符串?

发布于 2024-09-12 20:45:18 字数 2379 浏览 2 评论 0原文

在我的 Rails 3 应用程序中,我为 iPhone 和桌面浏览器提供了不同的布局。我正在尝试使用 Cucumber/Capybara 测试 iPhone 布局。到目前为止,我在请求的 HTTP 标头中设置 iPhone 用户代理字符串的所有尝试都失败了。

我已遵循 测试自定义标头和 ssl使用 Cucumber 和 Capybara 教程,但似乎没有在 HTTP 请求中设置 User-Agent 字符串。

如果我只是使用 iPhone 浏览我的 Rails 应用程序,我就会得到正确的布局。我正在使用 Rack-Mobile-Detect 将 Rails request.format 设置为 :iphone 。

关于如何实现这项工作有什么想法吗?我正准备抛弃水豚,回到 Webrat。

这是我到目前为止所拥有的:

Feature: Detect Browser
  In order to have different layouts for iPhone vs. desktop browsers
  As a developer
  I want to show different layouts for different browsers

Scenario: Show home page with desktop layout 
  Given I am using "a desktop browser"
  When I go to "the home page"
  Then I should see "desktop browser"

Scenario: Show home page with iPhone layout
  Given I am using "mobile safari"
  When I go to "the home page"
  Then show me the page
  Then I should see "mobile safari"

Detect_browser_steps.rb

Given /^(?:|I )am using (.+)$/ do |browser|
  case browser
  when "mobile safari"
    agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16"
    add_headers({'User-Agent' => agent})
  else
    # don't set a special User-Agent header
  end
end

headers_hack.rb

# http://aflatter.de/2010/06/testing-headers-and-ssl-with-cucumber-and-capybara/
# The following solution will work only if you use the :rack_test driver.
module RackTestMixin

  def self.included(mod)
    mod.class_eval do
      # This is where we save additional entries.
      def hacked_env
        @hacked_env ||= {}
      end

      # Alias the original method for further use.
      alias_method  :original_env, :env

      # Override the method to merge additional headers.
      # Plus this implicitly makes it public.
      def env
        original_env.merge(hacked_env)
      end
    end
  end

end

Capybara::Driver::RackTest.send :include, RackTestMixin

module HeadersHackHelper

  def add_headers(headers)
    page.driver.hacked_env.merge!(headers)
  end

end

World(HeadersHackHelper)

In my Rails 3 app, I have different layouts for iPhone vs desktop browsers. I'm trying to test the iPhone layout using Cucumber/Capybara. So far, all my attempts at setting an iPhone User-Agent string in the request's HTTP header have failed.

I have followed the Testing custom headers and ssl with Cucumber and Capybara tutorial but it doesn't seem to set the User-Agent string in the HTTP request.

If I just browse to my Rails app using my iPhone, I get the right layout. I am using Rack-Mobile-Detect to set the Rails request.format to :iphone.

Any ideas on how to make this work? I'm about ready to ditch Capybara and go back to Webrat.

Here's what I have so far:

Feature: Detect Browser
  In order to have different layouts for iPhone vs. desktop browsers
  As a developer
  I want to show different layouts for different browsers

Scenario: Show home page with desktop layout 
  Given I am using "a desktop browser"
  When I go to "the home page"
  Then I should see "desktop browser"

Scenario: Show home page with iPhone layout
  Given I am using "mobile safari"
  When I go to "the home page"
  Then show me the page
  Then I should see "mobile safari"

Detect_browser_steps.rb

Given /^(?:|I )am using (.+)$/ do |browser|
  case browser
  when "mobile safari"
    agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16"
    add_headers({'User-Agent' => agent})
  else
    # don't set a special User-Agent header
  end
end

headers_hack.rb

# http://aflatter.de/2010/06/testing-headers-and-ssl-with-cucumber-and-capybara/
# The following solution will work only if you use the :rack_test driver.
module RackTestMixin

  def self.included(mod)
    mod.class_eval do
      # This is where we save additional entries.
      def hacked_env
        @hacked_env ||= {}
      end

      # Alias the original method for further use.
      alias_method  :original_env, :env

      # Override the method to merge additional headers.
      # Plus this implicitly makes it public.
      def env
        original_env.merge(hacked_env)
      end
    end
  end

end

Capybara::Driver::RackTest.send :include, RackTestMixin

module HeadersHackHelper

  def add_headers(headers)
    page.driver.hacked_env.merge!(headers)
  end

end

World(HeadersHackHelper)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

英雄似剑 2024-09-19 20:45:19

嘿。很高兴您找到我的帖子;-)

您检查过 Rack::Test 是否将标头传递给控制器​​了吗?
您可以在控制器中尝试类似 Rails.logger.info("Headers: #{headers.inspect}") 的内容,然后检查日志文件。

Hey there. Glad you found my post ;-)

Did you check if Rack::Test passes your header to the controller?
You could try something like Rails.logger.info("Headers: #{headers.inspect}")in your controller and then inspect your log file.

春庭雪 2024-09-19 20:45:18

不得不对此进行一些修改,但最终我只需添加以下内容即可使其正常工作:

# features/support/capybara_headers.rb:

module CapybaraHeadersHelper
  def add_headers(headers)
    headers.each do |name, value|
      page.driver.browser.header(name, value)
    end
  end
end
World(CapybaraHeadersHelper)

您可以在此 博客文章 我写的,但基本上就是这样。

Had to fiddle a bit on this, but in the end I managed to get it working just by adding:

# features/support/capybara_headers.rb:

module CapybaraHeadersHelper
  def add_headers(headers)
    headers.each do |name, value|
      page.driver.browser.header(name, value)
    end
  end
end
World(CapybaraHeadersHelper)

You can get more info in this blog post I wrote, but that's basically it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文