RSpec 3 matchers for testing your html (for RSpec 2 use 0.5.x version).
Add to your Gemfile in the :test group:
gem 'rspec-html-matchers'
and somewhere in RSpec configuration:
RSpec.configure do |config|
config.include RSpecHtmlMatchers
end
or just in you spec(s):
describe "my view spec" do
include RSpecHtmlMatchers
it "has tags" do
expect(rendered).to have_tag('div')
end
end
Cucumber configuration:
World RSpecHtmlMatchers
as this gem requires nokogiri, here instructions for installing it.
so perhaps your code produces following output:
<h1>Simple Form</h1>
<form action="/users" method="post">
<p>
<input type="email" name="user[email]" />
</p>
<p>
<input type="submit" id="special_submit" />
</p>
</form>
so you test it with following:
expect(rendered).to have_tag('form', :with => { :action => '/users', :method => 'post' }) do
with_tag "input", :with => { :name => "user[email]", :type => 'email' }
with_tag "input#special_submit", :count => 1
without_tag "h1", :text => 'unneeded tag'
without_tag "p", :text => /content/i
end
Example about should be self-descriptive, but if not refer to have_tag documentation
Input could be any html string. Let's take a look at these examples:
Simple examples:
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p')
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag(:p)
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p#qwerty')
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p.qwe.rty')
More complicated examples:
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p strong')
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p#qwerty strong')
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p.qwe.rty strong')
or you can use another syntax for examples above
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p') do
with_tag('strong')
end
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p#qwerty') do
with_tag('strong')
end
expect('<p class="qwe rty" id="qwerty"><strong>Para</strong>graph</p>').to have_tag('p.qwe.rty') do
with_tag('strong')
end
# all of these are equivalent:
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :with => { :class => 'qwe rty' })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :with => { :class => 'rty qwe' })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :with => { :class => ['rty', 'qwe'] })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :with => { :class => ['qwe', 'rty'] })
The same works with :without:
# all of these are equivalent:
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :without => { :class => 'qwe rty' })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :without => { :class => 'rty qwe' })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :without => { :class => ['rty', 'qwe'] })
expect('<p class="qwe rty" id="qwerty">Paragraph</p>').to have_tag('p', :without => { :class => ['qwe', 'rty'] })
expect('<p> Some content here</p>').to have_tag('p', :text => ' Some content here')
or
expect('<p> Some content here</p>').to have_tag('p') do
with_text ' Some content here'
end
expect('<p> Some content here</p>').to have_tag('p', :text => /Some content here/)
or
expect('<p> Some content here</p>').to have_tag('p') do
with_text /Some content here/
end
# mymock.text == 'Some content here'
expect('<p> Some content here</p>').to have_tag('p', :content => mymock.text)
or
expect('<p> Some content here</p>').to have_tag('p') do
with_content mymock.text
end
expect(page).to have_tag( ... )
where page is an instance of Capybara::Session
and of course you can use the without_ matchers (see the documentation).
You can find more on RubyDoc, take a look at have_tag method.
Also, please read CHANGELOG, it might be helpful.