6

I am developing iOS app using turbolinks-ios and Rails variant.

In my iOS app, I set custom user agent iPadApp and detect that on Rails application controller is using request.user_agent.try(:index, 'iPadApp') for setting variant to tablet (because by views are like foo.html+tablet.haml).

My app is working fine and now I am trying to write feature tests for my app but can't properly set user agent. I tried this post that actually is stackoverflow but I see that it does not set request.user_agent instead (page.driver.browser.header(key, value)) set query parameter with in request.params.

In my controller test I simply use request.user_agent = 'iPadApp' to set user agent which is working fine.

How can I configure testing request so that I can use request.user_agent.try(:index, 'iPadApp')?

Thank you for any kind of help.

Community
  • 1
  • 1
Engr. Hasanuzzaman Sumon
  • 2,103
  • 3
  • 29
  • 38

3 Answers3

9

Since you're not specifying a driver Capybara should be using rack_test. With the rack_test driver you can set the user agent header, in your test code before calling visit, with

page.driver.header('User-Agent', 'the user agent string you want')

That should then make request.user_agent accessible in your application code.

A different solution would be register a specific driver for your ipad tests

Capybara.register_driver(:ipad_rack_test) do |app|
  Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'User agent string' })
end

and then specify your driver as :ipad_rack_test

Thomas Walpole
  • 48,548
  • 5
  • 64
  • 78
  • Your solution work though I found that `page.driver.header` call `page.driver.browser.header` (source code)[https://github.com/jnicklas/capybara/blob/master/lib/capybara/rack_test/driver.rb] . I don't know why last day it did no work ( I just restart my server). Is there any way to pass `User-Agent` as attribute as option of `visit` method? So that, instead of set header before every visit a can pass this option. Thanks for your help. – Engr. Hasanuzzaman Sumon Aug 24 '16 at 06:07
  • Of course I can override `visit` method where I can set `header` depending on passing `options`. – Engr. Hasanuzzaman Sumon Aug 24 '16 at 06:10
  • No there is no way to pass it to visit without you overriding `visit` yourself. A simpler/cleaner solution would probably be to just put the header setting in a before block, so it's run before every test (or tests you tag with specific metadata) – Thomas Walpole Aug 24 '16 at 06:21
  • @Engr.HasanuzzamanSumon If you need this for a lot of tests see the section I added to the answer about registering a driver specifically for it. – Thomas Walpole Aug 24 '16 at 06:36
  • undefined local variable or method `page' – Eddie Feb 10 '18 at 20:26
  • @Eddie Then you're not calling it in your test code which is what the answer talks about, or you haven't correctly installed Capybara for your tests. – Thomas Walpole Feb 10 '18 at 20:56
2

To add on to this, if you are looking to set the user agent for all of your testing. You can do something like this in your spec_helper.rb config section (chrome user agent as an example)

config.before(:each) do
  Capybara.page.driver.header('user-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36.')
end
Andrew
  • 2,829
  • 3
  • 22
  • 19
1

Since I cannot comment or edit, I was forced to make a new answer. Although the above is correct, for the top where he has page.driver.header('User-Agent', 'the user agent string you want'), I had to use Capybara.page.driver.header('User-Agent', 'the user-agent string you want').

Hope this helps.

Jay
  • 116
  • 1
  • 10