Out of the box,
assert_select works only with HTML documents. If you try it on an XML document (like, say, an RSS or Atom feed), you’ll more than likely see warnings about the document being malformed. It’s easy enough to work around, though.
The trick is to define your own
HTML::Document instance before calling
assert_select. When you define your own instance, you can pass some optional parameters that make
HTML::Document play nicely with XML:
1 2 3 4
def xml_document @xml_document ||= HTML::Document.new(@response.body, false, true) end
The second parameter says whether you want to parse the document in strict mode or not. “False” is the default; if you set it to “true”, you’ll get an exception (instead of a warning) whenever the parser hits what looks like a malformed document.
The third parameter says whether or not the document is an XML document or not. It defaults to “false”, meaning that, by default, only HTML documents are parsed. Here, we set it to “true”.
Once you’ve defined your custom document, you just need to define your
1 2 3 4 5
def assert_xml_select(*args, &block) @html_document = xml_document assert_select(*args, &block) end
assert_select method then will reuse the existing
html_document value. Nothing to it! Just put these two methods in your
test/test_helper.rb file, and you’re all set.
(Caveat: the above won’t work if you’re trying to use
assert_select on XML returned via RJS, since when
assert_select parses the RJS response to extract the document, it builds it’s own html document.)
Update: Jerry Vos and Jeff Talbot pointed out the the version of assert_xml_select I originally had was not passing the block through, so nested assert_xml_select calls were not being invoked. I’ve updated the code, above, to pass the block through. Thanks for catching that, guys!