Problem testing for empty div

October 29, 2008

Assert_Select is the main Rails tool for testing HTML output. RSpec wraps this function with its have_tag and with_tag methods. Using these methods effectively is key to writing features. However Assert_Select has some problems which caught me out recently.

What I wanted to do is make sure my cart could not be seen when empty

Scenario: Cart is hidden if empty
  Given there are 4 products
  And I am on the products page 
  And the cart is empty  
  Then I should not see the cart

The difficulty was with Then I should not see the cart. The output I get from an empty cart is

<div id='cart'>
</div>

The empty div is there so I can populate it using AJAX at some point. In rspec terms the following statements should be equivalent

response.should_not have_tag("div#cart>*")  

response.should_not have_tag("div#cart") do  
  with_tag("*")
end
  
response.should have_tag("div#cart") do  
  without_tag("*")
end

However only the first one works. Translating into Assert_Select we get

assert_select("div#cart") do
  assert_select("*",0)
end

assert_select("div#cart", 0) do
  assert_select("*")
end    

Neither of these work. See rspec bug

Update

This was invalid when given a block assert_select tries to match the element specified (in this case div#cart) and then yields the matches. so you should be doing

assert_select("div#cart") do |elements|
  elements.each {|element| assert_select("*",0)}
end

My previous code on the other hand asserts that div#cart exists and then asserts that there are no elements at the top level rather than asserting that there are no elements that are children of the match.

Thanks to Frederick Cheung for this see rails bug