Rail3 Tutorial testing(chapter 5): click_link error
Cross posted to: http://www.ruby-forum.com/topic/2140862#new
Here is the error I am getting:
.....F
Failures:
1) LayoutLinks should have the right links on the layout
Failure/Error: click_link "Sign up"
Could not find link with text or title or id "Sign up"
# ./spec/requests/layout_links_spec.rb:37:in `block (2 levels) in
<top (required)>'
Finished in 0.28358 seconds
6 examples, 1 failure
Here is the test file for LayoutLinks. The last 'it block' has the click_link that is giving me the problem:
#spec/requests/layout_links_spec.rb:
require 'spec_helper'
describe "LayoutLinks" do
it "should have a Home page at: /" do
get '/'
response.should have_selector('title', :content => "Home")
end
it "should have an About page at: /about" do
get '/about'
response.should have_selector('title', :content => "About")
end
it "should have a Contact page at: /contact" do
get '/contact'
response.should have_selector('title', :content => "Contact")
end
it "should have a Help page at: /help" do
get '/help'
response.should have_selector('title', :content => "Help")
end
it "should have a Sign up page at: /signup" do
get "/signup"
response.should have_selector('title', :content => "Sign up")
end
it "should have the right links on the layout" do
visit root_path
click_link "About"
response.should have_selector('title', :content => "About")
click_link "Contact"
response.should have_selector('title', :content => "Contact")
click_link "Help"
response.should have_selector('title', :content => "Help")
click_link "Sign up"
response.should have_selector('title', :content => "Sign up")
click_link "Home"
response.should have_selector('title', :content => "Home")
end
The other click_link tests pass. It's only the 'Sign up' link that is giving me the problem. The only difference I can discern is that the page with the 'Sign up' link is handled by a different controller: Users#new v. Pages (the controllers are below).
Here are my routes:
config/routes.rb:
SampleApp::Application.routes.draw do
get "users/new"
match '/signup', :to => 'users#new'
match '/about', :to => 'pages#about'
match '/contact', :to => 'pages#contact'
match '/help', :to => 'pages#help'
root :to => 'pages#home'
end
Here is the application layout:
app/views/layouts/application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title><%= title() %></title>
<%= csrf_meta_tag %>
<%= render 'layouts/stylesheets' %>
</head>
<body>
<div class="container">
<%= render 'layouts/header' %>
<section class="round">
<%= yield %>
</section>
<%= render 'layouts/footer' %>
</div>
</body>
</html>
Here is the Home page that contains the 'Sign Up' link, which is inserted at the 'yield' in the application layout above:
app/views/pages/home.html.erb:
<h1>Me</h1>
<p>Hi, this is my website.</p>
<%= link_to "Sign up", signup_path, :class => "signup_button round" %>
Here are my controllers:
app/controllers/users_controller.rb:
class UsersController < ApplicationController
def new
@title = "Sign up"
end
end
app/controllers/pages_controller.rb:
class PagesController < ApplicationController
def home
@title = "Home"
end
def contact
@title = "Contact"
end
def about
@title = "About"
end
def help
@title = "Help"
end
end
When I manually click on the 'Sign up' link on the Home page, it successfully displays the page:
app/views/users/new.html.erb
<h1>Users#new</h1>
<p>Find me in app/views/users/new.html.erb</p>
And if I click on View Source for the Home page, the 'Sign up' link is there (not to be confused with the "Sign in" link):
<!DOCTYPE html>
<html>
<head>
<title>My website | Home</title>
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="i/PD5uKjp87ArBPcr51a82KeW/5peacAJ6M908f3sP8="/>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="/stylesheets/blueprint/screen.css?1310454155" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/blueprint/print.css?1310454155" media="print" rel="stylesheet" type="text/css" />
<!--[if lt IE 8]>
<link href="/stylesheets/blueprint/ie.css?1310454155" media="screen" rel="stylesheet" type="text/css" />
<![endif]-->
<link href="/stylesheets/custom.css?1310632912" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<header>
<a href="/"><img alt="Autumn" class="round" height="140" src="/images/autumn.jpg?1310626333" width="300" /></a>
<nav class="round">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/help">Help</a></li>
<li><a href="#">Sign in</a></li>
</ul>
</nav>
</header>
<sect开发者_运维技巧ion class="round">
<h1>Me</h1>
<p>Hi, this is my website.</p>
<a href="/signup" class="signup_button round">Sign up</a>
</section>
<footer>
<nav class="round">
<ul>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="http://news.railstutorial.org/">News</a></li>
</ul>
</nav>
</footer>
</div>
</body>
</html>
click_link actually changes the page that the test is examining, i.e. 'visit root_path' is no longer the current page after you've done a click_link. My "Sign up" link only appears on the Home page, while the other links are on every page. Hence, navigating away from the Home page, and then asking the test to click the "Sign up" link didn't work.
The solution is to put this:
click_link "Sign up"
response.should have_selector('title', :content => "Sign up")
right after:
visit root_path
or after:
click_link "Home"
response.should have_selector('title', :content => "Home")
The order of your tests when using a lot of click_link tests is important. As 7stud pointed out, click_link simulates actually clicking on the link and going wherever the link points to.
Make sure the link you're testing exists on the page you're on, otherwise you'll get an error.
You can do what the other answer suggested, or
visit root_path
and then
click_link "Sign up"
精彩评论