Reputation: 4797
In my ruby on Rails 4.2 app, on a page I have a conditional back end rule that translates into the page front end in a change in class
<div id="content">
<i class='<% if x=true %>glyphicon glyphicon-thumbs-down<% else> glyphicon glyphicon-thumbs-up ><% end %>' </i>
this is the message.
</div>
How to check presence with rspec 3/capybara that the page contains the class glyphicon-thumbs-down OR the class glyphicon-thumbs-up ?
I tried the code below but it fails:
it "should sheck one of the 2 classes presence" do
expect(page).to have_css '.glyphicon-thumbs-down' || expect(page).to have_css '.glyphicon-thumbs-up'
end
I am getting the following error message:
syntax error, unexpected tIDENTIFIER, expecting keyword_end (SyntaxError)
Upvotes: 10
Views: 11699
Reputation: 68
Maybe you can try to use option :count, in expect method like this:
it 'should contains 2 same selector' do
expect(page).to have_css '.some-class', count: 2
end
Upvotes: 1
Reputation: 49950
Firstly, you're checking for a class name so you need a .
in front of the class names to make it a CSS class selector. Then, you could use the RSpec or
matcher combinator
expect(page).to have_css('.glyphicon-thumbs-down').or(have_css '.glyphicon-thumbs-up')
but it has the downside of the first one retrying/waiting for Capybara.default_max_wait_time
seconds before checking the second. You could specify a 0/false wait time if you know the page is already loaded and therefore don't need retrying/waiting
expect(page).to have_css('.glyphicon-thumbs-down', wait: false).or(have_css '.glyphicon-thumbs-up', wait: false)
However, it's probably fine to just check for either element using the normal CSS ,
expect(page).to have_css('.glyphicon-thumbs-down, .glyphicon-thumbs-up')
Upvotes: 7
Reputation: 15954
Multiple OR-ed css selectors can be specified separated by a comma. Try the following:
it "should sheck one of the 2 classes presence" do
expect(page).to have_css '#content i.glyphicon-thumbs-down,#content i.glyphicon-thumbs-up'
end
(I added the #content
and i
selectors so that the query is more specific.)
However, instead of doing this I would recommend trying to make the test behave in a precisely defined way and test for just a single class in the spec. Have a look at this SO question and its answers for various ways to stub or preset the random number generator in tests.
Upvotes: 12
Reputation: 26788
Your error is from this line:
expect(page).to have_css 'glyphicon-thumbs-down' || expect(page).to have_css 'glyphicon-thumbs-up'
You just need to add some parens then it will be valid syntax:
expect(page).to(have_css('glyphicon-thumbs-down')) || expect(page).to(have_css('glyphicon-thumbs-up'))
that won't fix your issue though, because if the left condition fails then rspec will exit and not run the second half.
A working approach could be to evaluate the condition to a boolean variable, then pass it to a single rspec expectation. Doing this requires using the core Capybara method has_css to test for css presence, not have_css? from the rspec matchers package:
selectors = ['.glyphicon-thumbs-down', '.glyphicon-thumbs-up']
glyph_exists = selectors.any? do |selector|
page.has_css? selector
end
expect(glyph_exists).to be true
Note also that I've added .
to the selector strings which is necessary since it's a css class.
Upvotes: 1