1
votes

Been at this problem all day: After a lot of investigation it seems that any time we have the following sequence, rspec/capybara complete the test, and then hangs.

The sequence is:

  • visit a page
  • perform some operation (click) that causes JS to load a new page
  • the controller does a redirect of that page

Everything works fine with Selenium ff, but with webkit the tests run successfully, and then it hangs. You then have to hit ctrl-c twice.

We get this same behavior on three different machines (1 mac os, 2 linuxy) so the problem must be an interaction with the actual web page being loaded, but note that the page loads fine.

Latest capybara-webkit, qt etc. ( from the mac: Capybara: 2.5.0 capybara-webkit: 1.7.1 Qt: 5.5.1 WebKit: 538.1 QtWebKit: 5.5.1)

For example:

it 'redirects an existing logged in user to the dashboard' do
  user = FactoryGirl.create :user
  login(user, then_visit: "/")
  # the above which just does a session/new?redirect_to="/" succeeds but
  # rspec never terminates.
  # if I change it to
  #    login(user)
  #    wait(10)
  #    visit "/"
  # everything works fine.
  find(".tp-dashboard", wait: 10)      
  expect(page.current_path).to eq "/account/#{user.id}/dashboard"
end

The login method just does a session/new and then logs the user in.

To make things clear (at least to myself) I added this

  after(:all) do
    puts "**************************** I know I am done, I just can't quit **********************************"
  end

and sure enough I get this output:

.**************************** I know I am done, I just can't quit **********************************


Finished in 18.35 seconds (files took 13.23 seconds to load)
1 example, 0 failures

I can wait as long as I like, and it takes two ctrl-c's to exit.

>^C
RSpec is shutting down and will print the summary report... Interrupt again to force quit.
>^C:mitch$ 

Here are two logs: The first is when there is a 10 second delay, long enough for the page to load. The second is when there is a 1 second delay, and the page does not load (so the test fails, but rspec exits)

https://gist.github.com/catmando/81dafb5212e8163389bd

https://gist.github.com/catmando/264accacf25e98bcb179

For what its worth this is the login method, but understand we have the same thing happening in any scenario where javascript loads a page, that is redirected by the controller:

def login(user, opts = {})
  visit "/session/new#{'?return_to='+opts[:then_visit] if opts[:then_visit]}"
  fill_in "user_session[login]", with: user.login
  fill_in "user_session[password]", with: user.password
  click_button "mobile_login_submit"
end
1
Not sure why your tests hang, but rather than the expect you have, as long as you're using Capybara 2.5+, you can use expect(page).to have_current_path("/account/#{user.id}/dashboard") which uses Capybaras waiting behavior for the page to change and removes the need for the find or the sleep - Thomas Walpole
Tom - yes realize that... as the comment around the sleep notes, we would never normally do a sleep. This was just done to demonstrate that it seems to be waiting for the page to become loaded that causes the issue, regardless of what mechanism is used to wait. But thanks for the reminder! - Mitch VanDuyn
Does it give a stack trace or anything when you press ctrl-c to show where the code was? - Thomas Walpole
nope - just added the full output... - Mitch VanDuyn
Do you have any other after(:all/:suite) blocks or are you using any gems that add after blocks? - Thomas Walpole

1 Answers

0
votes

I had to give up and use phantomjs / poltergeist... excellent instructions for setting up here:

I just used the currently released phantomjs and added a polyfill for bind (important if you get errors and you are using react or react.rb )