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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With