I am working on a Rails 4 app. In the app, there is a page with a modal form whose behavior I am trying to test as follows:
<li>
form via JS <li>
form via JS <li>
elements My web_step for counting the number of <li>
elements uses an expect(all())
RSpec expectation like so:
Then(/^I should see the number of items equals "(.*?)"$/) do |number_of_ items |
expect(all(:xpath, xpath_items).length).to eq(number_of_ items.to_i)
end
xpath_items
is collecting the elements correctly.
I am getting intermittent cucumber test failures. I think Capybara is looking for the <li>
elements to count (and failing) before JS has changed them in the DOM. I think expect(all())
is the culprit, but not sure the best way to refactor or make it work consistently.
I have tried to fix this race condition via a few methods, including (1) increasing Capybara.default_wait_time = 120
, (2) adding sleep(10)
to web_steps (an anti-pattern I think), (3) wrapping web_step functionality in page.document.synchronize
as shown in How to use synchronize in Capybara exactly?
I know wait_until
method is removed from Capybara as shown here.
Stack: rails 4.0.3, cucumber 1.5.15, capybara 2.2.1, selenium-webdriver 2.41.0, angular.js, jquery, bootstrap. FWIW…my machine is a Retina MacBook Pro i7, so pretty fast.
Any ideas appreciated. Thanks!
Capybara provides options (:count, :minimum, :maxium, :between) for specifying how many elements to wait for. Assuming you are using the latest version of Capybara, these can now be used in all
.
By specifying the :count
, you can tell the all
method to wait for a specific number of items to appear. This could be added to your step as:
Then(/^I should see the number of items equals "(.*?)"$/) do |number_of_ items|
expect(all(:xpath, xpath_items, count: number_of_ items.to_i).length).to eq(number_of_ items.to_i)
end
However, this seems a bit hard to read to me. I would suggest switching to using a have_selector
, which does support these options. With this, you could simplify the step to:
Then(/^I should see the number of items equals "(.*?)"$/) do |number_of_ items|
expect(page).to have_selector(:xpath, xpath_items, count: number_of_ items.to_i)
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.