← Back to Upcase

Sleep in a Capybara AJAX test, needed?

(Justin Gordon) #1

In the code below, if I have the sleep 1, the test passes. Without the sleep, the test reliably fails. Calling hover on the_image triggers the ajax. Maybe I’m setting up the last expect incorrectly? Or are there cases where sleep is needed?

    the_image = find(:xpath, "//a[@data-image-id='#{@image.id}']/..")
    expect(page).to have_xpath("//a[@data-image-id='#{@image.id}']/../a[contains(@class, 'thumb-download')]")
    sleep 1
    expect(find(:xpath, "//a[@data-image-id='#{@image.id}']/../a[contains(@class, 'thumb-download')]")[:href]).to match(/https:/)

(Guirec Corbel) #2

I don’t know if it is the best solution but you can apply this.


(Justin Gordon) #3

@Guirec_Corbel I tried that, but for some reason, it didn’t work for me.


(Chris Toomey) #4

In general you should not have to add explicit sleep calls in capybara feature specs as it has built in logic for waiting for ajax requests, and retrying find and has_content calls within a given period of time. You can read up on the specifics of this in the Async & AJAX section of the docs.

That said, it looks like you are using the expected methods, ie find and have_xpath, which should activate this waiting logic. With that in mind, you might want to try bumping up the overall Capybara wait timeout setting:

# in spec/spec_helper.rb
Capybara.default_wait_time = 3 # default is 2

Whereas sleep 1 is guaranteed to add 1 sec to your spec run time, bumping Capybara’s timeout threshold will only use as much time as needed.


(Justin Gordon) #5

@christoomey, my timeout was already set fairly high (like 8 seconds). Maybe there is some bug in Capybara that I’m hitting.


(Derek Prior) #6
expect(find(:xpath, "//a[@data-image-id='#{@image.id}']/../a[contains(@class, 'thumb-download')]")[:href]).to match(/https:/)

Chris is right : find will wait. However, you’re only calling find for the link. Is it possible the selector for that link is present before the href attribute is populated with a value that will match?


(Justin Gordon) #7

That is true. The link already exists with the value of “#”. How can I convert the selector to check the value of the link?