RSpec / Capybara ? (from The RSpec Book): Why might "should have_selector" silently pass when nested?

I'm going through The RSpec Book, and (specifically around page 333) I encountered a problem. Basically, whenever I use "should have_selector" in a nested form, it silently passes when it SHOULD fail.

I've been copying the code exactly as from the book. Now, there is one major difference - I'm using Capybara while the book is using Webrat. Why? I've had bigger problems with Webrat. In fact, when I switch to Webrat by putting it in the Gemfile, I get this unidentified method error in which has_selector isn't recognized (which is doubly odd because this happens where I call have_selector...)

Anyway, here's the code:

-------new.html.erb_spec.rb-------

require 'spec_helper'

describe "messages/new.html.erb" do

  let(:message) do     mock_model("Message").as_new_record.as_null_object   end

  before do     assign :message, message   end

  it "renders a form to create a message" do     render     rendered.should have_selector("form",       :method => "post",       :action => messages_path     ) do |form|       form.should have_selector("input", :type => "submit") # this should be failing right now!!!     end   end

  # this should be failing right now!!!   it "renders a text field for the message title" do     message.stub(:title => "the title")     render     rendered.should have_selector("form") do |form|       form.should have_selector("input",         :type => "submit",         :name => "message[title]",         :value => "the title"       )     end   end

  # this should be failing right now!!!   it "renders a text area for the message text" do     message.stub(:text => "the message")     render     rendered.should have_selector("form") do |form|       form.should have_selector("textarea",         :name => "message[text]",         :content => "the message"       )     end   end end

-----new.html.erb------

<%= form_for @message do |f| %>

# nothing is in here, so those nested "should have_selector" statements should fail

<% end %>

Thanks in advance!

The examples in the book use webrat, which has a has_selector matcher that supports nesting. The capybara have_selector matcher does not support nesting (yet). You don't get any feedback because Ruby lets you pass a block to any method, and leaves it to the method to handle it or ignore it. In this case it's being ignored.

HTH, David

Thank you. But then what should be the work around for this with Capybara? I was leaning toward using capybara...

Actually, do you recommend webrat over capybara? I just want one with good documentation and stick with one for the sake of getting used to the syntax.

Now... One last thing. I notice that when I try webrat, has_content? no longer works. I'm guessing has_content? is specific to Capybara... is "should contain" the equivalent in webrat?

Thanks again.

Thank you. But then what should be the work around for this with Capybara? I was leaning toward using capybara...

rendered.should have_selector("form input[@type='submit']")

You can also use assert_select which ships with Rails and supports nesting if you prefer.

Actually, do you recommend webrat over capybara? I just want one with good documentation and stick with one for the sake of getting used to the syntax.

That's tricky. Capybara is under regular development and has a growing user base. Webrat has been around longer and already supports the matchers you're looking for, but hasn't had a commit in 5 months. I'm using Capy on new projects if you want to take that as a recommendation.

Now... One last thing. I notice that when I try webrat, has_content? no longer works. I'm guessing has_content? is specific to Capybara... is "should contain" the equivalent in webrat?

Yep.

Thank you. But then what should be the work around for this with Capybara? I was leaning toward using capybara...

Actually, do you recommend webrat over capybara? I just want one with good documentation and stick with one for the sake of getting used to the syntax.

Cucumber has dropped Webrat in favour of Capybara. So, if you are likely to use Cucumber for integration testing, alongside RSpec for the unit tests, then I would choose Capybara, otherwise you will be stuck with the old cuke gem that uses Webrat.

There were also some issues with Webrat (details of which I can't recall right now, possibly to do with Devise) but they went away when I switched to Capybara a few months back. Also, the switch was painless.

So, FWIW, I would recommend Capybara.

Regards

Paul