The insider's guide to everything sparqcode
Header image

Author Archives: yowhan

This problem has been bugging me for quite a while and the usual googling did not get me a solution that worked.

After some experimentation and a bit more research, I found the answer in the comments section of a blog post here: http://aflatter.de/2010/06/testing-headers-and-ssl-with-cucumber-and-capybara/

So let me share the solution I ended up with. First, we have to hack the Capybara Driver and allow the headers to be overridden. This part I just copied verbatim from the blog post. You can put this file anywhere in features/support.

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)

Now, we need to add a new step definition. This is where we diverge from the blog post.

Given /^my user agent is "(.+)"$/ do |agent|
  add_headers({'HTTP_USER_AGENT'=> agent})
end

So that’s it for testing user agent strings. Now, I was trying to figure this out because I wanted cucumber to run tests for different mobile phone types. So it made sense for me to throw in another step definition that would make this easier.

Given /^I have an? (.+)$/ do |phone_name|
  add_headers({‘HTTP_USER_AGENT’=> SAMPLE_AGENT_STRING[phone_name]})
end

SAMPLE_AGENT_STRING can be defined as a constant hash like below:

#Sample user agent strings
SAMPLE_AGENT_STRING={
  “iPhone” => “Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7″,
  “Android” => “HTC_Eris Mozilla/5.0 (Linux; U; Android 4.0; en-ca; Build/GINGERBREAD) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1″,
  “Windows Mobile” => “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; HTC_Touch_Diamond2_T5353; Windows Phone 6.5)”,
  “Windows Phone 7″ => “Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0) Asus;Galaxy6″,
  “Blackberry” => “BlackBerry9700/5.0.0.351 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/123″,
  “Palm Pre” => “Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0″,
  “Nokia N97″ => “Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124″
}

Now I can write scenarios like:

Given I have an iPhone
And I am viewing “/detect-phone”
Then I should see “You are using an iPhone!”