To add knowledge to an existing body:
For tests, JS Capybara must support the synchronization of two threads (one for RSpec, one for Rails) and the second process (browser). It does this by waiting (up to the set maximum timeout) in most matching and node-binding methods.
Capybara also has methods that don't wait, most notably Node#all . Using them is like telling your specifications that you want them to fail intermittently.
The accepted answer offers page.first('selector') . This is undesirable, at least for JS specifications, because Node#first uses Node#all .
However, Node#first will wait if you configure Capybara like this:
# rails_helper.rb Capybara.wait_on_first_by_default = true
This option was added in Capybara 2.5.0 and is false by default.
As Andrew mentioned, you should use instead
find('selector', match: :first)
or change your selector. Any of these will work well regardless of configuration or driver.
To complicate matters even further, in older versions of Capybara (or with the configuration option enabled) #find happily ignores the ambiguity and simply returns the first matching selector. This is also not great, as it makes your specifications less explicit, which, I think, is no longer the default behavior. I do not take into account the specifics, because they have already been discussed above.
Additional resources:
johncip Mar 03 '16 at 19:52 2016-03-03 19:52
source share