Hartl Chapter 5. Section 5.27 - ruby-on-rails

I'm currently working through Hartl. In Chapter 5 i'm adding Hartl's code from listing 5.27 (below) to my spec/requests/static_pages_spec.rb
require 'spec_helper'
describe "Static pages" do
subject { page }
describe "Home page" do
before { visit root_path }
it { should have_selector('h1', text: 'Sample App') }
it { should have_selector('title', text: full_title('')) }
it { should_not have_selector 'title', text: '| Home' }
end
describe "Help page" do
before { visit help_path }
it { should have_selector('h1', text: 'Help') }
it { should have_selector('title', text: full_title('Help')) }
end
describe "About page" do
before { visit about_path }
it { should have_selector('h1', text: 'About') }
it { should have_selector('title', text: full_title('About Us')) }
end
describe "Contact page" do
before { visit contact_path }
it { should have_selector('h1', text: 'Contact') }
it { should have_selector('title', text: full_title('Contact')) }
end
end
Whe I run the $ bundle exec rspec spec/requests/static_pages_spec.rb test, Terminal returns this error:
Failures:
1) Static pages Home page
Failure/Error: it { should have_selector('title', text: full_title('')) }
NoMethodError:
undefined method `full_title' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x007fb4b44504c8>
# ./spec/requests/static_pages_spec.rb:11:in `block (3 levels) in <top (required)>'
2) Static pages Help page
Failure/Error: it { should have_selector('title', text: full_title('Help')) }
NoMethodError:
undefined method `full_title' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2:0x007fb4b46a9008>
# ./spec/requests/static_pages_spec.rb:19:in `block (3 levels) in <top (required)>'
3) Static pages About page
Failure/Error: it { should have_selector('title', text: full_title('About Us')) }
NoMethodError:
undefined method `full_title' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_3:0x007fb4b4430290>
# ./spec/requests/static_pages_spec.rb:26:in `block (3 levels) in <top (required)>'
4) Static pages Contact page
Failure/Error: it { should have_selector('title', text: full_title('Contact')) }
NoMethodError:
undefined method `full_title' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_4:0x007fb4b40e57e8>
# ./spec/requests/static_pages_spec.rb:33:in `block (3 levels) in <top (required)>'
Finished in 0.21306 seconds
9 examples, 4 failures
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:11 # Static pages Home page
rspec ./spec/requests/static_pages_spec.rb:19 # Static pages Help page
rspec ./spec/requests/static_pages_spec.rb:26 # Static pages About page
rspec ./spec/requests/static_pages_spec.rb:33 # Static pages Contact page
Any ideas?

Do you have this line in your spec_helper.rb file?
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
Do you have a spec/support/utilities.rb file that looks like this?
include ApplicationHelper
def sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token
end
Do you have a app/helpers/application_helper.rb file that looks like this?
module ApplicationHelper
# Returns the full title on a per-page basis.
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
end
If so, I think your error should go away.

Hi there I also following Michael's tutorial for Rails 3.2 version and get the same error... try this with your current version of capybara
I changed the :text to :content and got it works, so it looks like this:
it { should have_selector('title', content: full_title('')) }
Hope it helps, cheers!

The exercise in Chapter 5 reads
"eliminate the need for the full_title test helper in Listing 5.26 by
writing tests for the original helper method, as shown in Listing
5.37. (You will have to create both the spec/helpers directory and the application_helper_spec.rb file.) Then include it into the test using
the code in Listing 5.38."
http://ruby.railstutorial.org/chapters/filling-in-the-layout.html#sec-layout_exercises
Does that mean I only need "include ApplicationHelper" my utilites.rb file since spec/helpers/application_helper_spec.rb now contains
require 'spec_helper'
describe ApplicationHelper do
describe "full_title" do
it "should include the page title" do
full_title("foo").should =~ /foo/
end
Having this setup I am still getting an error when I run my RSpec test. They only way I can get it to pass is having full_title defined in utilites.rb

The current formatting should look like this for your tests to pass:
it { should have_title(full_title('Help')) }
it { should have_title(full_title('About')) }
it { should have_title(full_title('Contact')) }

Considering this post is two years old, I assume you have figured this out. Nevertheless, try adding
RSpec.configure do |config|
...
config.include ApplicationHelper
...
end
within spec\requests\spec_helper.rb

Related

Rspec / Capybara issues -- Capybara won't visit page

Ok so I'm kinda new, but have somewhat of an idea of what I'm doing, but this one just has me stumped for the past couple hours, so any help is very much appreciated. I'm building a site and have been using Rspec and Capybara to test my site as I'm moving along. I ended up needing to remove turbolinks to improve functionality for my jscripts. The next time I try to run tests, literally 50% of my test suite just magically broke. I've narrowed it down to that the commonality between all the failures was that the "visit" either appeared in or just before the code block. So basically removing Turbolinks somehow blew Capybara up or Rspec. I'm really having some trouble figuring this one out. I tried updating the gems, that didn't work. I guess the next step is either skip the TDD concept, which I don't want to do, or start uninstalling the gems and do a reinstall and pray that that doesn't render my app useless... Any help anyone can provide is much appreciated, and if you're in NYC I'll buy you a beer.
There are also other tests that are failing that don't require any sort of authentication, just to check the page for title and content and those are failing to. I bring that up only to say I don't think that FactoryGirl is causing the problem.
Cheers.
The errors
2) User pages profile page
Failure/Error: before { visit user_path(user) }
NoMethodError:
undefined method `user_path' for #<RSpec::ExampleGroups::UserPages::ProfilePage:0x00000004290410>
# ./spec/requests/user_pages_spec.rb:10:in `block (3 levels) in <top (required)>'
3) User pages profile page
Failure/Error: before { visit user_path(user) }
NoMethodError:
undefined method `user_path' for #<RSpec::ExampleGroups::UserPages::ProfilePage:0x00000004207c00>
# ./spec/requests/user_pages_spec.rb:10:in `block (3 levels) in <top (required)>'
4) User pages signup page
Failure/Error: before { visit signup_path }
NameError:
undefined local variable or method `signup_path' for #<RSpec::ExampleGroups::UserPages::SignupPage:0x000000041b3088>
# ./spec/requests/user_pages_spec.rb:18:in `block (3 levels) in <top (required)>'
The test suite code
require 'spec_helper'
describe "User pages" do
subject { page }
#Profile tests
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_content(user.name) }
it { should have_title(user.name) }
end
#Signup page tests
describe "signup page" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
describe "signup" do
before { visit signup_path }
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar00"
fill_in "Confirmation", with: "foobar00"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
end
end
try to remove your visiting pages from before blocks .
So , you just need :
describe "signup page" do
feature "should have content 'Sign up' "
visit signup_path
it { should have_content('Sign up') }
end
feature "should have full title 'Sign up' "
visit signup_path
it { should have_title(full_title('Sign up')) }
end
end
And you need to do like this in every describe block .
Ok so to anyone else that runs into this issue, I did some more digging it's not a so uncommon occurrence for Capybara to get weird at times. But I got the route errors to fix and pass green by adding "config.include Rails.application.routes.url_helpers" to the spec_helper.rb file.
Rspec.configure do |config|
*
*
*
config.include Rails.application.routes.url_helpers
end
Unfortunately I can't provide any insight why that line needed to be added, when previously it was not needed. I'll have to leave that answer to someone with more knowledge than myself.

Hartl RoR Tutorial Chapter 5 Exercise 1: Failing test: it_should_behave_like and should_not have_title

I'm having problems with Hartl's RoR Tutorial Chapter 5 Exercise 1.
The exercise sets up the test spec. given in TEST SPEC below.
When I run "bundle exec rspec spec/", I get the error given in ERROR below.
If I comment out both:
it_should_behave_like "all static pages"
it { should_not have_title('| Home') }
the test passes...
QUESTION: What's wrong with it_should_behave_like and should_not have_title
**ERROR**
o DRb server is running. Running in local process instead ...
WARNING: Nokogiri was built against LibXML version 2.8.0, but has dynamically loaded 2.7.8
F...F......
Failures:
1) Static pages Home page
Failure/Error: it { should_not have_title('| Home') }
NoMethodError:
undefined method `has_title?' for #<Capybara::Session>
# ./spec/requests/static_pages_spec.rb:18:in `block (3 levels) in <top (required)>'
**TEST SPEC**
require 'spec_helper'
describe "Static pages" do
subject { page }
shared_examples_for "all static pages" do
it { should have_content(heading) }
it { should have_title(full_title(page_title)) }
end
describe "Home page" do
before { visit root_path }
let(:heading) { 'Sample App' }
let(:page_title) { '' }
it_should_behave_like "all static pages"
it { should_not have_title('| Home') }
end
.......
.......
.......
Try updating Capybara to the version 2.1.0 in your Gemfile. have_title is one of the new selectors.
Check out this answer for more information

Ruby on Rails Tutorial Chapter 5 Failure/Error it {should have_selector

I'm working on the Ruby on Rails Tutorial (chapter 5) and I'm getting an error. My code is at....
https://github.com/Hjack/sample_app_new
I'm getting the following error...
hakimus-MacBook-Air:sample_app_new hakimujackson$ bundle exec rspec spec/requests/static_pages_spec.rb
Rack::File headers parameter replaces cache_control after Rack 1.5.
...FFFFFF
Failures:
1) Help page
Failure/Error: it { should have_selector('h1', text: 'Help')}
expected css "h1" with text "Help" to return something
# ./spec/requests/static_pages_spec.rb:20:in `block (2 levels) in <top (required)>'
2) Help page
Failure/Error: it { should have_selector('title', text: full_title('Help'))}
expected css "title" with text "Ruby on Rails Tutorial Sample App | Help" to return something
# ./spec/requests/static_pages_spec.rb:21:in `block (2 levels) in <top (required)>'
3) About page
Failure/Error: it { should have_selector('h1', text: 'About')}
expected css "h1" with text "About" to return something
# ./spec/requests/static_pages_spec.rb:28:in `block (2 levels) in <top (required)>'
4) About page
Failure/Error: it { should have_selector('title', text: full_title('About Us'))}
expected css "title" with text "Ruby on Rails Tutorial Sample App | About Us" to return something
# ./spec/requests/static_pages_spec.rb:29:in `block (2 levels) in <top (required)>'
5) Contact page
Failure/Error: it { should have_selector('h1', text: 'Contact')}
expected css "h1" with text "Contact" to return something
# ./spec/requests/static_pages_spec.rb:36:in `block (2 levels) in <top (required)>'
6) Contact page
Failure/Error: it { should have_selector('title', text: full_title('Contact'))}
expected css "title" with text "Ruby on Rails Tutorial Sample App | Contact" to return something
# ./spec/requests/static_pages_spec.rb:37:in `block (2 levels) in <top (required)>'
Finished in 0.21916 seconds
9 examples, 6 failures
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:20 # Help page
rspec ./spec/requests/static_pages_spec.rb:21 # Help page
rspec ./spec/requests/static_pages_spec.rb:28 # About page
rspec ./spec/requests/static_pages_spec.rb:29 # About page
rspec ./spec/requests/static_pages_spec.rb:36 # Contact page
rspec ./spec/requests/static_pages_spec.rb:37 # Contact page
Here is my spec.rb file...
require 'spec_helper'
describe "StaticPages" do
subject { page }
describe "Home page" do
before { visit root_path }
it { should have_selector('h1', text: 'Sample App')}
it { should have_selector('title', text: full_title(''))}
it { should_not have_selector 'title', text: '| Home'}
end
end
describe "Help page" do
before { visit help_path }
it { should have_selector('h1', text: 'Help')}
it { should have_selector('title', text: full_title('Help'))}
end
describe "About page" do
before { visit about_path }
it { should have_selector('h1', text: 'About')}
it { should have_selector('title', text: full_title('About Us'))}
end
describe "Contact page" do
before { visit contact_path}
it { should have_selector('h1', text: 'Contact')}
it { should have_selector('title', text: full_title('Contact'))}
end
I'm not sure what I'm doing wrong. I'd appreciate any help.
Thanks!!!
The problem is in your spec file --
describe "StaticPages" do
subject { page }
describe "Home page" do
before { visit root_path }
it { should have_selector('h1', text: 'Sample App')}
it { should have_selector('title', text: full_title(''))}
it { should_not have_selector 'title', text: '| Home'}
end
end
You are ending the rspec context too soon -- move the last 'end' to the bottom of your spec, and your tests should all pass.
cheers!

Rails/RSpec - writing tests for original helper methods

I'm on the chapter 5 exercises for Michael Hartl's Rails Tutorial and am trying to wrap my head around how Rails/Rspec is testing a helper method full_title in app/helpers/application_helper.rb. All of my tests are in spec/requests/static_pages_spec.rb and within them, I'm calling full_title to cut down on code bloat.
So, in order to test the original full_title I create a test in spec/helpers/application_helpers_spec.rb and include it via spec/support/utilities.rb. The code is passing, but I want to understand the process (order to operations) to what is going on. Thank you.
Can I think of it like this?
Rspec begins to run static_pages_spec.rb (including utilities.rb)
Rspec sees the full_title method in static_pages_spec.rb
Rspec begins to run application_helper_spec.rb
Rspec sees describe "full_title" do in application_helper_spec.rb
Rspec looks up original full_title method and finishes test for application_helper_spec.rb
Rspec finishes tests in static_pages_spec.rb, iterating through above process whenfull_title` is called.
static_pages_spec.rb
require 'spec_helper'
describe "Static pages" do
subject { page }
shared_examples_for "all static pages" do
it { should have_selector('h1', text: heading) }
it { should have_selector('title', text: full_title(page_title)) }
end
describe "Home page" do
before { visit root_path }
let(:heading) { 'Sample App' }
let(:page_title) { '' }
it_should_behave_like "all static pages"
it { should_not have_selector 'title', text: '| Home' }
end
describe "Help page" do
before { visit help_path }
let(:heading) { 'Help' }
let(:page_title) { 'Help' }
it_should_behave_like "all static pages"
end
describe "About page" do
before { visit about_path }
let(:heading) { 'About' }
let(:page_title) { 'About Us' }
it_should_behave_like "all static pages"
end
describe "Contact page" do
before { visit contact_path }
let(:heading) { 'Contact' }
let(:page_title) { 'Contact' }
it_should_behave_like "all static pages"
end
it "should have the right links on the layout" do
visit root_path
click_link "About"
page.should have_selector 'title', text: full_title('About Us')
click_link "Help"
page.should have_selector 'title', text: full_title('Help')
click_link "Contact"
page.should have_selector 'title', text: full_title('Contact')
click_link "Home"
page.should have_selector 'title', text: full_title('')
click_link "Sign up now!"
page.should have_selector 'title', text: full_title('Sign up')
click_link "sample app"
page.should_not have_selector 'title', text: full_title('| Home')
end
end
application_helper_spec.rb
require 'spec_helper'
describe ApplicationHelper do
describe "full_title" do
it "should include the page title" do
full_title("foo").should =~ /foo/
end
it "should include the base title" do
full_title("foo").should =~ /^Ruby on Rails Tutorial Sample App/
end
it "should not include a bar for the home page" do
full_title("").should_not =~ /\|/
end
end
end
application_helper.rb
module ApplicationHelper
#Returns the full title on a per-page basis.
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
end
Think about it this way:
The 'full_title' called in static_pages_spec.rb (including utilities.rb) is running the 'full_title' method described in application_helper.rb.
The application_helper_spec.rb is validating the string/value (page_title) passed through full_title.
If I'm not mistaken, it does this each time the full_title method is called in your tests.

Ruby on Rails Tutorial - Getting Errors, pulling my hair out

Im following [Michael Hartl's tutorial][1] and did the exercises in Chapter 7, and now have 4 errors that I cant figure out how to fix for the life of me. When I test the production app manually, the errors dont exist at all. So I don't know if there is something wrong with my text development or something, but Im at a total loss so I thought I'd post here to see if my total noobness is blinding me...thanks for your help!
Here's the 4 error messages I'm getting:
Failures:
1) signup with invalid information after submission
Failure/Error: it { should have_selector('title', text: "Sign up") }
expected css "title" with text "Sign up" to return something
# ./spec/requests/user_pages_spec.rb:38:in `block (4 levels) in <top (required)>'
2) signup with invalid information after submission
Failure/Error: it { should have_content('error') }
expected there to be content "error" in "after submission"
# ./spec/requests/user_pages_spec.rb:39:in `block (4 levels) in <top (required)>'
3) signup after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:60:in `block (3 levels) in <top (required)>'
4) signup after saving the user
Failure/Error: it { should have_selector('div.alert.alert-success', text: 'Welcome') }
expected css "div.alert.alert-success" with text "Welcome" to return something
# ./spec/requests/user_pages_spec.rb:61:in `block (3 levels) in <top (required)>'
Finished in 6.8 seconds
10 examples, 4 failures
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:38 # signup with invalid information after submission
rspec ./spec/requests/user_pages_spec.rb:39 # signup with invalid information after submission
rspec ./spec/requests/user_pages_spec.rb:60 # signup after saving the user
rspec ./spec/requests/user_pages_spec.rb:61 # signup after saving the user
Here's the code on my user_pages_spec.rb:
require 'spec_helper'
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup page" do
before { visit signup_path }
it { should have_selector('h1', text: 'Sign up') }
it { should have_selector('title', text: full_title('Sign up')) }
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('h1', text: user.name) }
it { should have_selector('title', text: user.name) }
end
end
describe "signup" do
before { visit signup_path }
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
describe "after submission" do
before { click_button submit }
it { should have_selector('title', text: "Sign up") }
it { should have_content('error') }
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email('user#example.com') }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
end
end
[1]: http://ruby.railstutorial.org/
Here's the template code for views/users/show.html.erb
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
</aside>
</div>
and then here's the users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
end
Allright y'all,
I dont know if not answering my question was some sort of torturous initiation for noobs in this forum, but after almost 24 hours and a good night sleep, I solved the problem!
After a few G searches, I found that I could be stopping some of the variables from passing through by having "end" in the wrong places. It turns out there were 2 main areas where I was doing this. Once I found and fixed those, all the errors went away.
I will now pat myself on the back. I hope this helps any total noobs who run into this same problem in the future.

Resources