aklybw
13.49K
· July 2013 ·
84687433fbeed3d44d0298b7032f9780

Wait for ajax with capybara 2.0

Since they removed wait_until from capybara 2.0 I had to work out a different way to wait for all the ajax requests in a test to finish.

This need comes since we have a backbone application and many of the ajax requests executed won't have direct side effects on the DOM.

So the solution looks like this:

def wait_for_ajax
  Timeout.timeout(Capybara.default_wait_time) do
    active = page.evaluate_script('jQuery.active')
    until active == 0
      active = page.evaluate_script('jQuery.active')
    end
  end
end
Sign in or sign up to add your response.

9 Responses

8384
5009d470b40e5f3aefb5515559c8745d

Thanks for share.
I would like to add my 2 cents with a DRY version of your code.

def wait_for_ajax
  Timeout.timeout(Capybara.default_wait_time) do
    loop do
      active = page.evaluate_script('jQuery.active')
      break if active == 0
    end
  end
end
over 1 year ago ·
9512

Good solution, thanks!

over 1 year ago ·
11889
483f1b98648c3e9b2c75fb6bb7ad2ed9

Where exactly do you add this?

over 1 year ago ·
11930
84687433fbeed3d44d0298b7032f9780

@dejancancarevic just add this in your spec_helper.rb

over 1 year ago ·
12880
D4d312a34cfa93a577373558f8c34da8

does this work for Selenium? I got a:

Failure/Error: wait_for_ajax
     Capybara::NotSupportedByDriverError:
       Capybara::Driver::Base#evaluate_script

after putting it in my spec_helper.rb

over 1 year ago ·
12881
D4d312a34cfa93a577373558f8c34da8

actually, not sure if this is necessary, see http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara

over 1 year ago ·
12945
84687433fbeed3d44d0298b7032f9780

@mswieboda, I don't know why you would get such error. I normally use phantomjs but sometimes selenium.
In my project I have selenium-webdriver (2.38.0) just in case

An regarding your second command. We use this helper only in some special cases, normally you should check for DOM changes

over 1 year ago ·
14231
3915eeaee91d96525e3e4e0fcdf93343

I found this through thoughbot's blog. Here are some minor changes I made (from their version). In the application I'm testing the AJAX requests are potentially long. I've added the ability to set a custom wait time AND to ensure that jQuery is defined before calling jQuery.active

  # @see http://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara Automatically wait for AJAX with Capybara
  def finished_all_ajax_requests?
    return_value = page.evaluate_script <<-SCRIPT.strip.gsub(/\s+/,' ')
      (function () {
        if (typeof jQuery != 'undefined') {
          return jQuery.active;
        }
        else {
          console.log("Failed on the page: " + document.URL);
          console.error("An error occurred when checking for `jQuery.active`.");
        }
      })()
    SCRIPT
    return_value and return_value.zero?
  end

  # @see http://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara Automatically wait for AJAX with Capybara
  def wait_for_ajax(task: 'Waiting for AJAX', wait_time: nil)
    DebugHelpers.time_execution(task) do
      wait_time ||= Capybara.default_wait_time

      Timeout.timeout(wait_time) do
        loop until finished_all_ajax_requests?
      end
    end
  end
over 1 year ago ·
19340
None

Thanks for this. Of the various suggestions I found at stack overflow and elsewhere, this was the only one which worked (Rails 4.1, RSpec 2.14, Capybara Webkit 1.3).

over 1 year ago ·
Featured Programming Job

Engineer turned Programmer
·
Cambridge, MA
·
Full Time
Search all programming jobs