Reputation: 2954
There are waiting and non-waiting functions in Capybara. I am trying to use the first as much as possible.
Is there a way to use find
(or one of its derivatives) to look for a CSS element that appears asynchronously?
Unfortunately, function page.has_css?
is a non-waiting function.
Upvotes: 2
Views: 4655
Reputation: 49900
Your claim that page.has_css?
is a non-waiting function is not correct. page.has_css?
will wait up to Capybara.default_max_wait_time
seconds for an element to appear on the page and return true
or false
based on whether or not the element is on the page within that time. Therefore, given Capybara.default_max_wait_time = 5
if page.has_css?("div#my_div")
puts "on page"
else
puts "not on page"
end
will wait for up to 5 seconds. As soon as a div with id of "my_div" is visible on the page it will print "on page". If a matching div doesn't become visible within 5 seconds it will print "not on page". If you want it to wait longer for a specific call you can override default_max_wait_time
by passing the :wait
option
if page.has_css?("div#my_div", wait: 10) # will wait up to 10 seconds
...
If rather than wanting a boolean response you want to ensure the element exists you can do any of
page.assert_selector(:css, 'div#my_div') # :css is the default so can usually be omitted
page.assert_css('div#my_div') # minitest
expect(page).to have_css('div#my_div') # RSpec
which will wait for the element to appear as previously, but raise an exception rather than returning false
if the element does not appear
If you need the actual element you can use find
which will also wait. So
el = page.find(:css, 'div#my_div') # :css is the default and can usually be omitted
will wait for the element to appear and return the element when found. If the element is not found within default_max_wait_time
seconds it will raise an exception.
Note: Basically, the only non-waiting methods are all
and first
and even those can be made to wait if you pass in any of the count options (:count
, :minimum
, :maximum
, :between
), although the elements returned from them would still be non-reloadable and can therefore have further behavior effects if used for scoping, etc. Even methods like click_link
, click_button
, etc will wait since they are implemented as find(...).click
, etc
Upvotes: 7