2

I'm working my way through the Rails Tutorial book by Hartl and I'm completely stuck on one of the tests. The test (right from the book) is very simple:

require 'spec_helper'
describe UsersController do
render_views
describe "GET 'show'" do
    before(:each) do
        @user = Factory(:user)
    end
    ...
    it "should include the user's name" do
        get :show, :id => @user
        response.should have_selector('h1', :content => @user.name)
    end
end

The test fails with the following error:

UsersController GET 'show' should include the user's name Failure/Error: response.should have_selector('h1', :content => @user.name) expected following output to contain a <h1>Steve T</h1> tag:...

The page renders properly in the browser. Here is a snipped from the HTML source rendered by the browser:

<section class="round">
<h1> <img alt="Steve T" class="gravatar" src="http://gravatar.com/..." /> Steve T </h1> </section>

I can even add a call to: print response.body in the controller spec and it will output the tags properly.

Any ideas on what I may be doing wrong?

UPDATE - It seems like we have identified a potentially significant item: The HTML in the rspec test failure message is missing the body tag everything inside it.

1) UsersController GET 'show' should include the user's name Failure/Error: response.should have_selector('h1', :content => @user.name) expected following output to contain a <h1>Steve T</h1> tag: <!DOCTYPE html> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Ruby on Rails Tutorial Sample App | Steve T</title> </head></html> # ./spec/controllers/users_controller_spec.rb:33:in block (3 levels) in <top (required)>'

Does anyone know why, if the page in the browser includes the <body> tags and the inner content and if print response.body shows the content, why would the error message skip it?

Steve T
  • 31
  • 1
  • 1
  • 5
  • 2
    Note sure, but I think have_selector matches exactly? In your case, the H1 contains an embedded IMG. I suppose it would work if that IMG was not there. Tried it? And `have_selector` is a webrat matcher, I believe. You might want to try `response.should contain(@user.name)`. Or this *might* work: `response.should have_selector('h1 img', :content => @user.name)`. – Zabba Mar 13 '11 at 21:12
  • This is exactly what is happening, as far I have experienced. – Michael Oct 31 '12 at 06:37

4 Answers4

8

I had a similar problem when working through the Rails Tutorial. I forgot to include 'render_views' below the top 'describe' statement, which was causing the 'have_selector' test to fail.

atpark333
  • 81
  • 1
  • 2
3

My solution was in installing capybara, include in your Gemfile

group :development do
 gem 'capybara'
end

then do

bundle update
bundle install

than edit you code to

response.body.should have_selector('h1', :content => @user.name)

now run your tests. It should work

Anatoly Ruchka
  • 543
  • 4
  • 17
1

The test is failing because the h1 is wrapped around a <img /> so the content isn't correct and the test fails.

you could do something like this:

it "should include the user's name" do
    get :show, :id => @user
    response.should have_selector('h1')
    response.body.should contain(@user.name);
end
errorhandler
  • 1,757
  • 3
  • 22
  • 29
  • Thanks for your quick response. I modified the view file to put the image and name in separate h1 tags. Still getting the same error. The code rendered in the browser is now: `

    Steve T

    Steve T

    `
    – Steve T Mar 14 '11 at 00:54
  • it's because all h1s content is expected to be `@user.name`, is there any reason for the `` to be in a `

    `?

    – errorhandler Mar 14 '11 at 00:58
  • I just modified the view again to remove the image from the h1. Still no luck. Here is the HTML: `Steve T

    Steve T

    ` Thanks again. Your help is greatly appreciated.
    – Steve T Mar 14 '11 at 01:03
  • now that you've done that you can use `response.should have_selector('h1', :content => @user.name)` again – errorhandler Mar 14 '11 at 01:04
  • It gave the same error. I used the following code to dump the response and the @user.name to the terminal just to make sure that the variable was initialized properly.. the tag is in the html and the name prints properly between the asterisks. `it "should include the user's name" do get :show, :id => @user print response.body print '***' print @user.name print '***' response.should have_selector('h1', :content => @user.name) end` – Steve T Mar 14 '11 at 01:21
  • is @user.name in the test and @user.name in the view the same? – errorhandler Mar 14 '11 at 01:23
  • Yes. Here is the output: `... Steve T

    Steve T

    ... ***Steve T***`
    – Steve T Mar 14 '11 at 01:26
  • can you post the full rspec failure. – errorhandler Mar 14 '11 at 01:27
  • ` 1) UsersController GET 'show' should include the user's name Failure/Error: response.should have_selector('h1', :content => @user.name) expected following output to contain a

    Steve T

    tag: Ruby on Rails Tutorial Sample App | Steve T # ./spec/controllers/users_controller_spec.rb:33:in block (3 levels) in '`
    – Steve T Mar 14 '11 at 01:28
  • hmm, your layout isn't rendering the `body` tag does your layout.html.erb file have `<%= yield %>` somewhere in it? – errorhandler Mar 14 '11 at 01:32
  • Interesting... Yes, there is a `<%= yield %>` in layout.html.erb and the `body` does render in the browser and `print response.body' returns text. I wonder what is causing the discrepancy. – Steve T Mar 14 '11 at 01:35
1

It turns out that syntax mistake in the partial that loads my style sheets was essentially commenting out all the body tag content. The question is why Firefox 3 rendered the HTML anyway. I actually solved the problem inadvertently by upgrading to Firefox 4. In Firefox 4, the body of the page didn't render and the debugging tools led me to the erroneous markup

Steve T
  • 31
  • 1
  • 1
  • 5