How can I use assert_select in a Rails functional test to check for multiple elements of the same type, differing only by text?
I have a Rails view that outputs HTML similar to this:
<html>
<body>
<h1>Keywords</h1>
<h2>EN</h2>
<h3>Accepted</h3>
<ul>
<li>Foo</li>
</ul>
<h3>Rejected</h3>
<ul>
<li>Bar</li>
</ul>
<h2>SV</h2>
<h3>Accepted</h3>
<ul>
<li>Föö</li>
</ul>
<h3>Rejected</h3>
<ul>
<li>Bär</li>
</ul>
</body>
</html>
I'd like to use assert_select
to ensure that I have <h2>
tags for each language:
languages.each do |language|
assert_select 'body > h2', :text => language.upcase
end
But this fails:
<"DE"> expected but was
<"SV">.
<false> is n开发者_Go百科ot true.
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/assertions/selector_assertions.rb:299:in `assert_select'
~/foo/test/functional/api/keywords_controller_test.rb:123:in `test_html'
I know that I can use assert_match %q{<h2>#{language.upcase}</h2>}
in my block, but that feels so crufty when assert_select
exists.
Any ideas?
I found a hacktacular solution (thanks to the HTML::Tag class in scrapi post on the QuarkRuby blog), using the undocumented HTML::Tag
class that is yielded by assert_select
in block form:
# Count the <h2> tags and accumulate their text content
h2_texts = nil
assert_select('body > h2', :count => languages.size) do |elements|
h2_texts = elements.map {|element| element.children.first.content }
end
languages.each do |language|
assert h2_texts.include?(language.upcase), "<h2> tag for #{language} exists"
end
I guess assert_select
just can't do this, or it can and it is not documented. I guess I'll have to UTSL...
精彩评论