rspec-html-matchers

RSpec 3 matchers for testing your html (for RSpec 2 use 0.5.x version).

Gem Version
Build Status

Goals

Install

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.

Usage

so perharps your code produces following output:

<h1>Simple Form</h1>

<p>

</p>
<p>

</p>

so you test it with following:

expect(rendered).to have_tag('form', :with =&gt; { :action =&gt; '/users', :method =&gt; 'post' }) do
  with_tag "input", :with =&gt; { :name =&gt; "user[email]", :type =&gt; 'email' }
  with_tag "input#special_submit", :count =&gt; 1
  without_tag "h1", :text =&gt; 'unneeded tag'
  without_tag "p",  :text =&gt; /content/i
end

Example about should be self-descriptive, if not, please refer to have_tag documentation

Input could be any html string. Let’s take a look at these examples:

  • matching tags by css:
  # simple examples:
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p')
  expect('<p class="qwe rty">Paragraph</p>').to have_tag(:p)
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p#qwerty')
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p.qwe.rty')
  # more complicated examples:
  expect('<p class="qwe rty"><strong>Para</strong>graph</p>').to have_tag('p strong')
  expect('<p class="qwe rty"><strong>Para</strong>graph</p>').to have_tag('p#qwerty strong')
  expect('<p class="qwe rty"><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"><strong>Para</strong>graph</p>').to have_tag('p') do
    with_tag('strong')
  end
  expect('<p class="qwe rty"><strong>Para</strong>graph</p>').to have_tag('p#qwerty') do
    with_tag('strong')
  end
  expect('<p class="qwe rty"><strong>Para</strong>graph</p>').to have_tag('p.qwe.rty') do
    with_tag('strong')
  end
  • special case for classes matching:
  # all of this are equivalent:
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :with =&gt; { :class =&gt; 'qwe rty' })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :with =&gt; { :class =&gt; 'rty qwe' })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :with =&gt; { :class =&gt; ['rty', 'qwe'] })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :with =&gt; { :class =&gt; ['qwe', 'rty'] })

The same works with :without:

  # all of this are equivalent:
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :without =&gt; { :class =&gt; 'qwe rty' })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :without =&gt; { :class =&gt; 'rty qwe' })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :without =&gt; { :class =&gt; ['rty', 'qwe'] })
  expect('<p class="qwe rty">Paragraph</p>').to have_tag('p', :without =&gt; { :class =&gt; ['qwe', 'rty'] })
  • content matching:
  expect('<p> Some content&nbsp;here</p>').to have_tag('p', :text =&gt; ' Some content here')
  # or
  expect('<p> Some content&nbsp;here</p>').to have_tag('p') do
    with_text ' Some content here'
  end

  expect('<p> Some content&nbsp;here</p>').to have_tag('p', :text =&gt; /Some content here/)
  # or
  expect('<p> Some content&nbsp;here</p>').to have_tag('p') do
    with_text /Some content here/
  end

  # mymock.text == 'Some content here'
  expect('<p> Some content&nbsp;here</p>').to have_tag('p', :text =&gt; mymock.text)
  # or
  expect('<p> Some content&nbsp;here</p>').to have_tag('p') do
    with_content mymock.text
  end
  • usage with capybara and cucumber:
  expect(page).to have_tag( ... )

where page is an instance of Capybara::Session

  • also included shorthand matchers for form inputs:

    • have_form
    • with_checkbox
    • with_email_field
    • with_file_field
    • with_hidden_field
    • with_option
    • with_password_field
    • with_radio_button
    • with_button
    • with_select
    • with_submit
    • with_text_area
    • with_text_field
    • with_url_field
    • with_number_field
    • with_range_field
    • with_date_field

and of course you can use the without_ matchers,
for more info take a look at documentation

rspec 1 partial backwards compatibility:

you can match:

expect(response).to have_tag('div', 'expected content')
expect(response).to have_tag('div', /regexp matching expected content/)

RSpec 1 have_tag documentation

More info

You can find more on documentation

Also, please read CHANGELOG and issues, might be helpful.

Contribution

  1. Fork the repository
  2. Add tests for your feature
  3. Write the code
  4. Add documentation for your contribution
  5. Send a pull request

Contributors