How to make Capybara check for visibility after some JS has run?

Kevin Davis picture Kevin Davis · Jan 10, 2012 · Viewed 77.1k times · Source

After loading a page I have code that runs and hides and shows various items based on data returned by an xhr.

My integration test looks something like this:

it "should not show the blah" do
    page.find('#blah').visible?.should be_true
end 

When I manually go to the page in the context this test runs, #blah is not visible as I expect. I suspect that Capybara is looking at the initial state of the page (invisible in this case), evaluating the state of the DOM and failing the test before the JS runs.

Yes, I set the :js => true on the containing describe block :)

Any ideas would be greatly appreciated! I'm hoping I don't have to put an intentional delay in here, that feels flaky and will slow things down.

Answer

Jon M picture Jon M · Jan 11, 2012

I think that the find statement here is the one with the implicit wait, so Capybara will wait until the element is on the page, but won't wait for it to become visible.

Here, you would want Capybara to wait for the visible element to appear, which should be achievable by specifying the visible option:

expect(page).to have_selector('#blah', visible: true)

I haven't tried it, but the ignore_hidden_elements configuration option might be useful here as well, if you wanted find to always wait for visible elements.