Andrew Schwartz
Andrew Schwartz

Reputation: 4657

Rspec, Capybara and Poltergiest: Failed to reach server only when js: true is enabled

I have working integration/feature tests using Rails 4, rspec-rails 3.6, and capybara 2.18. I am trying to get these tests to pass on pages that are being rewritten in a javascript framework (React). To do so, I need to use a driver such as Poltergeist instead of the default headless browser so that javascript can run on the test pages.

I've installed poltergeist 1.18. I add Capybara.javascript_driver = :poltergeist, no problem. The tests pass with the old (html-only) pages.

However just adding js: true to an existing, working test (that is, before changing the rendered page to to the new version) and the test fails with

Request to 'http://account.example.com/user/sessions/new' failed to reach server, check DNS and/or server status

Note that this url is using the account subdomain in our application, and this may be related to the issue.

Here is one of the failing tests, isolated.

feature 'Vistor tries to login', js: true do
  scenario 'with valid login', :with_project_access_user do
    visit new_user_sessions_url
    fill_in 'user_session[login]', with: '[email protected]'
    fill_in 'user_session[password]', with: 'mysweetpassword'
    click_button 'Log In'
    expect(current_url).to match('http://account\.')
  end
end

It's failing on the first line: visit new_user_sessions_url. This test passes if I remove js" true. In both cases, new_user_sessions_url is "http://account.example.com/user/sessions/new"

Using new_user_sessions_path instead of new_user_sessions_url doesn't work here because the subdomain is a required part of the route. If there is a way around the subdomain matching (without removing the subdomains -- they are used in our production app) that's a totally acceptable solution.

Since the test works without js: true, I have to assume that Capybara is doing something behind the scenes to handle the example.com domain. But how does adding js: true break this? And how can I fix this to get my existing tests to pass?

Upvotes: 1

Views: 291

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49870

When not using js: true Capybara is using the rack_test driver which completely ignores hostnames, so the only thing that matters is the path. When you use js: true real hostnames are being used because the "browser" is querying them to figure out where to make its requests. It is your responsibility to make sure whatever hostname your app is generating urls with resolves to an ip the app is listening on. Easiest solution for that is to add entries to /etc/hosts mapping the domain/subdomain names you're using for testing to 127.0.0.1.

Note: Poltergeist uses PhantomJS which is equivalent to an 8-9 year old browser at this point. This means you're most likely going to run into issues trying to run React apps on it, and you should really look into upgrading to a driver for modern browser - Selenium, Apparition, etc.

Upvotes: 1

Related Questions