ruby-on-railscapybarapoltergeist

Rails 4: stubbing in a Capybara & Poltergeist integration test


I'm having trouble testing a rather simple spec using Capybara & Poltergeist in a Rails 4 app.

The spec looks like this:

feature 'Creating user groups', :devise, js: true do
  let(:panel) { create(:panel) }
  let(:admin) { create(:user, :admin) }

  before do
    login_as(admin)
    visit admin_panel_user_groups_path(panel)
    click_link 'New user group'
  end

  context 'successfully' do
    it 'admin can create a new user group' do
      fill_in 'User group', with: 'Some group'
      click_button 'Save'

      expect(page).to have_content('Your user group has been saved correctly')
    end
  end
end

The spec ends up calling this create method, which returns a json response with format.js (which is why I run the above spec with js: true):

class Admin::UserGroupsController < AdminController
  respond_to :html, :json, :js, :csv
  before_action :set_panel

  def create
    respond_to do |format|
      @user_group = UserGroup.new(user_group_params.merge({panel_id: @panel.id}))
      if @user_group.save
        @user_group.refresh!
        format.js do
          render json: {
            responseType: 'modelSaved',
            object: @user_group
          }.to_json, status: 200
        end
      else
        format.js do
          render json: {
            responseType: 'error',
            object: @user_group
          }.to_json, status: 500
        end
      end
    end
  end
end

I've set up Poltergeist in my rails_helper.rb fie:

require 'capybara/poltergeist'

RSpec.configure do |config|
  config.include Warden::Test::Helpers, type: :feature
  config.after(type: :feature) { Warden.test_reset! }
  Capybara.javascript_driver = :poltergeist
end

but I'm getting the following error message when I run the spec:

Failure/Error: visit admin_panel_user_groups_path(panel)
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET http://127.0.0.1:54553/__identify__ with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}

You can stub this request with the following snippet:

stub_request(:get, "http://127.0.0.1:54553/__identify__").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})

registered request stubs:

stub_request(:get, "/http:\/\/maps.googleapis.com\/maps\/api\/geocode\/json?components=country:US|postal_code:\d+/")
stub_request(:get, "https://freegeoip.net/json/123.123.123.123").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'})

I believe this is happening because external connections are not allowed in the specs (which is good). However, does it make sense to stub external requests in integration tests? Am I configuring Poltergeist incorrectly or thinking about this test incorrectly?

Thanks in advance!


Solution

  • You really shouldn't have WebMock enabled when running feature tests (it can't stub or block requests made by the "browser" you're using, PhantomJS, anyway so it's not really protecting you from outgoing connections). So you either need to allow connections when running feature tests

    WebMock.allow_net_connect!
    

    or at the very least allow connections to the AUT which in this case is being run on 127.0.0.1

    WebMock.disable_net_connect!(allow_localhost: true)