title: Feature testing conditional page content rendering for a mobile device
body: <p>I'm using the <a href="https://github.com/jistr/mobvious-rails" rel="nofollow noreferrer">Mobvious gem</a> in a Rails project to determine the kind of device being used to access a page.  The user story I'm having issues with is:</p>
  
  <ul>
  <li>A user on a mobile device is on the mobile version of the site</li>
  <li>The mobile user clicks a 'Visit Full Site' button which takes them to the desktop site</li>
  <li>A <code>desktop</code> value is put into the session to make sure their preference for viewing the desktop site on their mobile device is recorded (when mobile users first access the home page on a mobile device, they get automatically re-directed to the mobile site)</li>
  <li>On the desktop site home page, the mobile device user can see a 'Switch to Mobile Site' banner to give them to do so (the desktop user obviously never sees this banner)</li>
  </ul>
  
  <p>The code to implement the conditional rendering with Mobvious is trivial:</p>
  
  <p><strong>app/views/welcome/index.html.haml</strong></p>
  
  <pre class="lang-rb prettyprint-override"><code>- for_device_type :mobile do
    .switch-to-mobile-site-banner
      # code for banner
  </code></pre>
  
  <p>The code itself works as expected: the issue is that I want to write a <a href="https://www.relishapp.com/rspec/rspec-rails/docs/feature-specs/feature-spec" rel="nofollow noreferrer">RSpec feature test</a> for this, but I think I can't seem to simulate a mobile user agent properly in a RSpec feature test scenario where I <em>don't have direct access to the</em> <code>request</code> <em>object</em>.  My rationale is that a feature spec is more appropriate here than a <a href="https://www.relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec" rel="nofollow noreferrer">request spec</a> as I am testing for the presence of specific content on a page.</p>
  
  <p>So far, taking cues from the <a href="https://github.com/jistr/mobvious-rails/blob/759a22215096d385ecdaf97c76c383d0fae8ea42/spec/mobvious/rails/helper_spec.rb" rel="nofollow noreferrer">helper specs of the Mobvious gem</a>, I've stubbed out a <code>request</code> object in my feature spec that sets <code>device_type</code> to <code>:mobile</code> as I want, but I can't seem to get the content in the <code>.switch-to-mobile-site-banner</code> to display:</p>
  
  <p><strong>spec/features/mobile_navigation_features_spec.rb</strong></p>
  
  <pre class="lang-rb prettyprint-override"><code>feature 'Switch to mobile site banner' do
    include Mobvious::Rails::Helper
  
    given(:env) { double('env') }
    given(:request) { double('request') }
  
    background do
      allow(env).to receive(:[]).with('mobvious.device_type').and_return(:mobile)
      allow(request).to receive(:env).and_return(env)
    end
  
    scenario 'mobile user prefers using the desktop site' do
      visit root_url(desktop: 1)
      puts "Device type is #{device_type}" # =&gt; correctly returns :mobile
      expect(page).to have_selector('.switch-to-mobile-site-banner') # fails
    end
  end
  </code></pre>
  
  <p>The expectation is failing, and using <code>save_and_open_page</code> to look at what's rendering on the page shows no banner, and I don't know why.  I don't seem to be getting any errors when the code runs through Mobvious' <a href="https://github.com/jistr/mobvious-rails/blob/759a22215096d385ecdaf97c76c383d0fae8ea42/lib/mobvious/rails/helper.rb#L19" rel="nofollow noreferrer"><code>for_device_type</code></a> method, so I'm thinking perhaps there's something I'm missing in the <code>request</code> object mocking(?).</p>
  
  <p>I'm not tied specifically to any implementation/test-type, so I'm open to any other ideas on how I can test the functionality I want to.  I thought initially the <a href="https://github.com/railsware/rack_session_access" rel="nofollow noreferrer"><code>rack_session_access</code> gem</a> could help out, but unless I'm using it wrong, I couldn't use it to do what I want.</p>
  
  <p><strong>Clarification</strong>: I am using <a href="https://github.com/jonleighton/poltergeist" rel="nofollow noreferrer">Poltergeist</a> for Capybara's javascript driver.</p>
  
  <h2>Update with solution</h2>
  
  <p>I think what really threw me with this problem is that in the <a href="https://github.com/jistr/mobvious-rails" rel="nofollow noreferrer">mobvious-rails</a> gem, when you want to get the <code>device_type</code>, it <a href="https://github.com/jistr/mobvious-rails/blob/master/lib/mobvious/rails/helper.rb#L36" rel="nofollow noreferrer">calls the <code>request</code> object directly</a> and I figured I needed to mock this out in order to get the helper working properly in my specs.  As pointed out in the answers, this kind of low-level mocking in a high-level feature spec is a code (spec?) smell, and in hindsight I should have listened to the code practically telling me I was doing it wrong.  Also, for some reason, adding <code>js: true</code> in this case didn't even cross my mind, regardless of having used it in other tests of mine.</p>
  
  <p>I ended up using parts of both <a href="https://stackoverflow.com/users/1721198/billy-chan">Billy Chan</a> and <a href="https://stackoverflow.com/users/790174/kaleidoscope">Kaleidoscope</a>'s answers to formulate a solution I like that is much simpler and cleaner:</p>
  
  <p><strong>spec/features/mobile_navigation_features_spec.rb</strong></p>
  
  <pre class="lang-rb prettyprint-override"><code>feature 'Switch to mobile site banner' do
    background do
      page.driver.headers = { "User-Agent" =&gt; "mobile" }
    end
  
    scenario 'mobile user prefers using the desktop site', js: true do
      visit root_path(desktop: 1)
      expect(page).to have_selector('.switch-to-mobile-site-banner')
    end
  end
  </code></pre>
  
  <p>Since Kaleidoscope was the first to come up with a working set of specs that took me most of the way, I'm awarding him the bounty, but I'm going to accept Billy Chan's answer as correct because I think it is a more 'canonical' solution that I would direct others to reference in the future.</p>