Why rspec doesn't wait completion of previous

2019-09-02 12:30发布

问题:

My rails-app contain rspec-tests using Capybara poltergeist (which uses phantomjs). Frontend is Backbone.js. Some tests are sometimes passed, sometimes not. Debugging shows that the right content is not loaded at the time of inspection. If i add an delay, e.c. sleep (inspection_time = 1), then the test passes.

  describe 'Direct visit page / # / desk / page / [ID]' do
    before {sign_in user}
    it 'should contain page title' do
      visit "/#/desk/pages/#{page.id}"
      #sleep (inspection_time = 1)
      expect (page) .to have_css (". page-detail p.title",: text => page.title)
    end
  end

js-tests are performed and so long, and yet unreliable delay increases execution time. Is there a good solution for drivers poltergeist (gem 'poltergeist', '1.6.0')?

Might be worth abandon poltergeist in favor of, for example capybara-webkit?

回答1:

Testing asynchronous requests with capybara can be tricky. As you noticed capybara does not know to wait for a async request to finish. But the good news is that matchers are smart enough to wait for something to appear.

For example if you call

expect(page).to have_css(".new_data")

And a div with new_data class does not initially exist capybara will wait for X seconds (defined in configuration) to see if it appears. However this is sometimes not enough, and you are probably dealing with some kind of a race condition. Thoughtbot wrote a good article on how to resolve this.