rspec-html-matchers is an open-source Ruby gem that drops RSpec 3 matchers — have_tag, with_tag, without_tag, with_text, and form-input shorthands — into view specs and Cucumber steps for asserting the structure and content of HTML output, parsed with Nokogiri.
What is rspec-html-matchers?
rspec-html-matchers is an RSpec gem designed for testing complex HTML output. It takes an HTML string or a Capybara::Session page as input and produces RSpec expectation results with developer-friendly failure messages. The gem is built on Nokogiri and is framework-agnostic — anything that can be turned into an HTML string can be tested. The project is maintained on GitHub by kucaahbe with a number of listed contributors, and the 0.5.x version line supports RSpec 2.
Key Features
The matchers cover tag selection, attribute checks, text checks, and form inputs, all sharing a syntax similar to the have_tag matcher from rspec-rails 1.x with its own syntactic sugar.
- Nokogiri-powered parsing — HTML is parsed into a real document, so matching reflects document structure instead of relying on string regexes.
- CSS-style tag selection —
have_tag('p#qwerty'),have_tag('p.qwe.rty'), and descendant selectors likehave_tag('p strong')are supported. - Attribute matching with :with and :without — the
:withoption matches attributes such as an input's :name and :type;:withoutasserts absence, and class matching ignores class order and accepts arrays of class names. - Text and rendered-text matching —
:textaccepts a string, a regexp, or any object whose string value is compared, such as a mock; the:seenoption matches text content the way a user sees it, ignoring surrounding whitespace. - Nested matcher blocks — inside a
have_tagblock you can usewith_tag,without_tag, andwith_text, including a:countoption such as:count => 1to assert exactly one match. - Form and input shorthand matchers — more than a dozen include
have_form,with_checkbox,with_email_field,with_radio_button,with_submit,with_text_area,with_text_field, pluswithout_variants for each. - Capybara and Cucumber integration — pass a Capybara::Session to
expect(page).to have_tag(...), or register the module in Cucumber withWorld RSpecHtmlMatchers. - RSpec 1 partial backward compatibility — legacy assertions such as
expect(response).to have_tag('div', 'expected content')still work.
Who is it for?
This gem suits teams writing RSpec-based tests against HTML views, partials, or pages rendered by Rails or Capybara.
- Rails view spec authors — assert that
renderedtemplates contain the expected form actions, field types, and counts without switching to assert_select. - Cucumber step definition writers — include RSpecHtmlMatchers in the World to use have_tag assertions directly on the Capybara page object.
- Developers testing complex HTML fragments — the gem targets complex output; for simple matching the README points to assert_select, rspec-rails's built-in matchers, and Capybara's matchers instead.
- Teams still on RSpec 2 — the 0.5.x release line keeps the matchers available for older suites.
What can you do with rspec-html-matchers?
The README's examples show three common testing scenarios for the gem.
- View spec authors: verify a rendered form's action, method, and field counts with a nested
have_tag('form')block containingwith_tagandwithout_tagassertions. - Cucumber step writers: assert the page contains a specific structure, such as an email input named
user[email]with typeemail, usingexpect(page).to have_tag(...). - HTML fragment testers: match tag attributes through CSS selectors (for example, requiring every image has an alt by matching
img[alt!='']) and compare text content to regexes or mock objects.
How does it work?
Setup takes three steps: install the gem, include the module, and write matcher expectations.
- Add
gem 'rspec-html-matchers'to your Gemfile's:testgroup. - Include the module in RSpec configuration via
config.include RSpecHtmlMatchers, or in individual specs withinclude RSpecHtmlMatchers; for Cucumber, addWorld RSpecHtmlMatchers. - Pass the rendered HTML string or Capybara page to
expect(...).to have_tag(...), optionally with a block of nested matchers.
FAQ
Is rspec-html-matchers free?
Yes, it is an open-source Ruby gem distributed through RubyGems and developed publicly on GitHub. You add it to your Gemfile and install it with Bundler, and the repository accepts pull requests with tests, code, and documentation.
Does rspec-html-matchers work with RSpec 2?
Yes, but you need the 0.5.x version of the gem. The current main line targets RSpec 3, while the 0.5.x release exists specifically for RSpec 2 users.
Can I use rspec-html-matchers with Capybara?
Yes. The matchers accept a Capybara::Session instance, so you can write expect(page).to have_tag(...) in feature specs or Cucumber steps. You can also register the matchers in Cucumber's World to use them in step definitions.
What is the difference between :text and :seen?
:text compares the parsed text content of a tag against a string, regexp, or object value, including encoded characters such as non-breaking spaces. :seen matches text as rendered for the user, so whitespace around content is ignored when comparing.
Is rspec-html-matchers a replacement for assert_select?
For simple matching, no — the README recommends assert_select, rspec-rails's built-in view matchers, or Capybara's matchers. This gem exists for complex HTML output where nested tag and attribute assertions are more readable.








