Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec with Capybara have_css matcher is not working

In Cucumber, with Rspec and Capybara I have a test to check that a button has a class. Here it is

expect(@some_button).to have_css(".in-cart")

it fails, but

@some_button['class']

returns

'btn product in-cart'

so the button definitely has the 'in-cart' class.

As a temporary measure I've changed my test to be;-

expect(@some_button['class']).to match /in-cart/

Which is obviously insane. But why should 'have_css', or 'has_css?' return false for a DOM element that clearly has the expected class?

Also page.all('.in-cart') includes the button, so Capybara can definitely find it.

Incidentally I also tried 'button.in-cart', 'in-cart',expect (etc).to have_selector, expect(etc.has_selector?('.in-cart')).to be_truthy and all combinations.

like image 748
John Small Avatar asked Jun 08 '15 05:06

John Small


2 Answers

have_css matcher is expected to be applied to the parent container instead of the actual element

# your view
<div id="container">
  <div class="in_cart product"></div>
</div>

# your step definition
parent = page.find('div#container')
expect(parent).to have_css(".in-cart")
# => returns true, as there is nested div.in_cart
expect('div#container div').to have_css(".in-cart")
# => returns false, as there is no such selector inside of the latter div

As of matching attributes of the exact object, you've got to stick with simple quering by key

element = page.find('div#container div')
element['class'].should include('in-cart')
expect(element['class']).to match /in-cart/

Same logic applies to all of the RSpecMatchers.

like image 65
twonegatives Avatar answered Oct 09 '22 00:10

twonegatives


In newer versions of Capybara/Rspec, by default, expect(page) will query the entire page looking for a match; however, sometimes we may not want that and instead will prefer to target a specific class/region of the page. For those cases, narrow down the context of page using within:

within('.container') do
  expect(page).to have_css(".in-cart")
end

Assuming, the parent has a class container Capybara will only search within this element.

like image 44
Sam3k Avatar answered Oct 09 '22 00:10

Sam3k