Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capybara: How To Assert A Given Number of Elements Exist

I've upgraded my whole stack from a Rails 3.0 based project to 3.1. I have specs passing but my features are now being a bit picky. The issue I'm currently having is this step:

Then /^I should see (\d+) menu item(?:s)? within "([^"]*)"$/ do |count, selector|
  page.find(:css, selector, :count => count.to_i)
end

And in the feature itself, I might put:

Then I should see 5 menu items within "tr#menu_item_row"

The message I get is:

Then I should see 5 menu items within "tr#menu_item_row"                                      # features/step_definitions/admin_menu_steps.rb:1
  Ambiguous match, found 5 elements matching css "tr#menu_item_row" (Capybara::Ambiguous)
  ./features/step_definitions/admin_menu_steps.rb:2:in `/^I should see (\d+) menu item(?:s)? within "([^"]*)"$/'
  features/admin_menu.feature:30:in `Then I should see 5 menu items within "tr#menu_item_row"'

As far as I can tell, the 5 elements match the 5 that were actually found. Did I write this code wrong or has something major changed? Thanks!

like image 225
Steve Ross Avatar asked Jun 08 '13 20:06

Steve Ross


People also ask

How do you know if an element is in capybara?

In order to simply check whether an element is present, without errors raised, you can use #has_css? . It will return a Boolean – but will wait as well. If the element does not exist, it will take the configured Capybara. default_wait_time for this check to return false , which is usually several seconds.

What is Capybara testing?

Capybara is a web-based test automation software that simulates scenarios for user stories and automates web application testing for behavior-driven software development. It is written in the Ruby programming language.


1 Answers

If you want to check 5 elements you shouldn't use #find as by default since Capybara 2.0 this method always throws an exception if it finds more or less than one element. This was an intentional and (I believe) a good change.

To assert that 5 elements are present an appropriate method is a rspec matcher:

expect(page).to have_css(selector, count: count.to_i)

I don't recommend to set match to prefer_exact as recommended by @fontno as in most of situations you want Capybara to throw an exception if find finds more than one element.

like image 91
Andrei Botalov Avatar answered Sep 20 '22 16:09

Andrei Botalov