The RSpec matcher tests if two HTML fragments are equivalent. Equivalency means:
- Whitespace is ignored
- Types of attribute quotes are irrelevant
- Attribute order is irrelevant
- Comments are ignored
You use it like this:
html = ...
expect(html).to match_html(<<~HTML)
<p>
Expected content
</p>
HTML
You may override options from CompareXML Show archive.org snapshot by passing keyword arguments after the HTML string:
html = ...
expect(html).to match_html(<<~HTML, ignore_text_nodes: true)
<p>
Expected content
</p>
HTML
Installing the matcher
The matcher requires these two gems in your Gemfile
:
gem 'nokogiri'
gem 'compare-xml'
Here is the matcher:
require 'nokogiri'
require 'compare-xml'
RSpec::Matchers.define :match_html do |expected_html, **options|
match do |actual_html|
expected_doc = Nokogiri::HTML5.fragment(expected_html)
actual_doc = Nokogiri::HTML5.fragment(actual_html)
# Options documented here: https://github.com/vkononov/compare-xml
default_options = {
collapse_whitespace: true,
ignore_attr_order: true,
ignore_comments: true,
}
options = default_options.merge(options).merge(verbose: true)
diff = CompareXML.equivalent?(expected_doc, actual_doc, **options)
diff.blank?
end
end
Alternatives
To use Capybara matchers like have_css
on an HTML fragment, use
Capybara.string(html)
Show archive.org snapshot
.
Posted by Henning Koch to makandra dev (2021-09-29 08:53)