Search code examples
ruby-on-railscapybarapoltergeist

Capybara/Poltergeist - Wait for JavaScript completions


After I log in through devise I'm clicking on the button with attached javascript which makes some HTML visible.

<button id="btn_simple_search" 
        class="btn btn-primary btn-md well_button" 
        data-toggle="button"
>
   Search
</button>

calls function

$("#btn_simple_search").click(function(){
   $("#simple_search").toggle(500);
});

I would like for capybara test to wait till this function is completed (I don't know - like some callback or something) rather than make sleep 0.6 before I click other button or select some options from newly displayed HTML block. I'm using Minitest as the test framework. How to do it?

Above javascript is embedded directly on the page.


Solution

  • Capybaras finders (other than all/first), matchers, and session actions default to a waiting/retrying behavior specifically to deal with the issue you are talking about. They will (by default) wait up til Capybara.default_max_wait_time seconds for the needed elements to appear on the page. What this means is that when you perform an action that is going to take some time, and you want to wait for it to finish, you need to instruct Capybara to look for something on the page that changes to indicate the finish. When clicking a button that makes things visible, that could be looking for text content that appears or it could just be telling it to click a button that becomes visible since finding the button will wait a bit until it becomes visible.

    The one wrinkle in that is items that animate into existence on the page. The problem here is that the items become visible but are still moving. This can cause some drivers (particularly Poltergeist due to architecture issues that can't really be worked around) to click in the wrong place on the page. The best solution for that is to disable animation in test mode, which will also speed up your tests, but how exactly you do that is dependent on what libraries you are using that produce the animations.