Getting the following errors when I run 'bundle exec rspec spec/requests/static_pages_spec.rb:
9 examples, 2 failures
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:56 # Static pages Contact page should have the title 'Contact page'
rspec ./spec/requests/static_pages_spec.rb:51 # Static pages Contact page should have the content 'Contact page'
I can't figure out how to get the two tests to pass here.
Trying to get through the tutorial here, learning, very new (I believe this is the code):
describe "Contact page" do
it "should have the content 'Contact'" do
visit '/static_pages/contact'
expect(page).to have_content('Contact')
end
it "should have the title 'Contact'" do
visit '/static_pages/contact'
expect(page).to have_content("Ruby on Rails Tutorial Sample App | Contact")
end
end
end
Additionally, the html file:
<% provide(:title, 'Contact') %>
<h1>Contact</h1>
<p>
Contact Ruby on Rails Tutorial about the sample app at the
contact page.
</p>
You're expecting the title with have_content and expecting the content with have_title.
Try
expect(page).to have_title('Contact')
and
expect(page).to have_content("Ruby on Rails Tutorial Sample App | Contact")
Actually you need to reword this last one a little because this is not the content you have in the view but you get the idea.
Related
Background
I want to write the following test for my Ruby on Rails application.
Log in as user.
Visit edit user page.
Click link in nav to go to About Us page.
Actually visit the About Us page and confirm its the correct template.
The reason is that I found a bug where for the link About Us I have it be referential for '/welcome/about/' and so it goes to /users/welcome/about which doesn't exist.
My Code
My test code is as follows:
test 'welcome page from user page works' do
log_in_as(#user)
get edit_user_path(#user)
assert_select "a", { :text=> "About Us" }
click_on ("About Us")
assert_template 'welcome/about'
end
Error Message
ERROR["test_welcome_page_from_user_page_works", WelcomePageTest, 1.42307711095782]
test_welcome_page_from_user_page_works#WelcomePageTest (1.42s)
Capybara::ElementNotFound: Capybara::ElementNotFound: Unable to find link or button "About Us"
test/integration/welcome_page_test.rb:13:in `block in <class:WelcomePageTest>'
Finished in 1.42605s
1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
Since there is 1 assertion this makes me think that the assertion the link exists pasts but somehow click_link can't find it?
EDIT This was my final code for the test:
test 'welcome page from user page works' do
log_in_as(#user)
visit edit_user_path(#user)
click_on ("About Us")
assert_template 'welcome/about'
end
Note I also changed the routes to be just hardcoded in:
get 'about' => 'welcome#about'
For capybara use the visit method instead of get
visit edit_user_path(#user)
I've been working through Michael Hartl's Rails tutorial, and for some reason I've gotten stuck on the first exercise in section 3. I've checked and rechecked my code to ensure that it matches his, but I still get this error:
Failures:
1) Static pages Contact page should have the content 'Contact'
Failure/Error: expect(page).to have_content('Contact')
expected #has_content?("Contact") to return true, got false
# ./spec/requests/static_pages_spec.rb:48:in `block (3 levels) in <top (required)>'
2) Static pages Contact page should have the title 'Contact'
Failure/Error: expect(page).to have_title("Ruby on Rails Tutorial Sample App | Contact")
expected #has_title?("Ruby on Rails Tutorial Sample App | Contact") to return true, got false
# ./spec/requests/static_pages_spec.rb:53:in `block (3 levels) in <top (required)>'
Finished in 0.09624 seconds
8 examples, 2 failures
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:46 # Static pages Contact page should have the content 'Contact'
rspec ./spec/requests/static_pages_spec.rb:51 # Static pages Contact page should have the title 'Contact'
Here is my code
static_pages_spec.rb
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the content 'Sample App'" do
visit '/static_pages/home'
expect(page).to have_content('Sample App')
end
it "should have the title 'Home'" do
visit '/static_pages/home'
expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home")
end
end
describe "Help page" do
it "should have the content 'Help'" do
visit '/static_pages/help'
expect(page).to have_content('Help')
end
it "should have the title 'Help'" do
visit '/static_pages/help'
expect(page).to have_title("Ruby on Rails Tutorial Sample App | Help")
end
end
describe "About page" do
it "should have the content 'About Us'" do
visit '/static_pages/about'
expect(page).to have_content('About Us')
end
it "should have the title 'About Us'" do
visit '/static_pages/about'
expect(page).to have_title("Ruby on Rails Tutorial Sample App | About Us")
end
end
describe "Contact page" do
it "should have the content 'Contact'" do
visit '/static_pages/about'
expect(page).to have_content('Contact')
end
it "should have the title 'Contact'" do
visit '/static_pages/about'
expect(page).to have_title("Ruby on Rails Tutorial Sample App | Contact")
end
end
end
application.html.erb, which is saved under app/views/layouts
<!DOCTYPE html>
<html>
<head>
<title>Ruby on Rails Tutorial Sample App | <%= yield(:title) %></title>
<%= stylesheet_link_tag "application", media: "all",
"data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
contact.html.erb
<% provide(:title, 'Contact') %>
<h1>Contact</h1>
<p>
Contact Ruby on Rails Tutorial about the sample app at the
contact page.
</p>
routes.rb
SampleApp::Application.routes.draw do
get "static_pages/home"
get "static_pages/help"
get "static_pages/about"
get "static_pages/contact"
end
static_pages_controller.rb
class StaticPagesController < ApplicationController
def home
end
def help
end
def about
end
def contact
end
end
With the limited information you're providing (I know it's hard to diagnose when you're a beginner, it gets easier). It looks like you're telling your test to check your about page and checking for content that only exists in your contact page.
I'm plodding through Mike Hartl's Rails Tutorial and in section 4.4 it appears that it had me change the rspec request file from the format of:
page.should have_selector('title', :text => "#{base_title}")
to
expect(page).to have_title("Ruby on Rails Tutorial Sample App")
I now get two undefined method errors where I use ".to have_title" and ".to_not have_title". I shutdown and restarted Webrick, Spork, and Guard just in case, but it still doesn't work.
Capybara version 1.1.2
Rspec version 2.11.1
Please let me know if any other info is needed.
Apparently the tutorial has changed recently.
Accessing the page through google cache reveals the original version (which works fine for me):
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the h1 'Sample App'" do
visit '/static_pages/home'
page.should have_selector('h1', :text => 'Sample App')
end
it "should have the base title" do
visit '/static_pages/home'
page.should have_selector('title',
:text => "Ruby on Rails Tutorial Sample App")
end
it "should not have a custom page title" do
visit '/static_pages/home'
page.should_not have_selector('title', :text => '| Home')
end
end
.
.
.
end
May be the issue with your version. Go through https://github.com/jnicklas/capybara/issues/863
expect(first('title').native.text).to eq "my title"
I had this problem, I realised eventually I had switched to following the code for rails version 4, rather than 3.2.
to test what version of rails you are using, type the command
rails -v
Then on the tutorial page, use the navigator on the right to select the right rails version. Seems simple, but hopefully it will save grief for others with this issue.
I have this test from michael hartl book:
require 'spec_helper'
describe "Static pages" do
let(:base_title) { "Ruby on Rails Tutorial Sample App" }
describe "Home page" do
it "should have the h1 'Sample App'" do
visit '/static_pages/home'
page.should have_selector('h1', :text => 'Sample App')
end
it "should have the title 'Home'" do
visit '/static_pages/home'
page.should have_selector('title', :text => "#{base_title} | Home")
end
end
end
And the view:
<% provide(:title, 'Home') %>
<h1>Sample App</h1>
<p>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</p>
When I run the test it says:
....
Finished in 1.91 seconds
4 examples, 0 failures
Randomized with seed 42247
.F...
Failures:
1) Static pages Home page should have the title 'Home'
Failure/Error: page.should have_selector('title', :text => "#{base_title} | Home")
expected #has_selector?("title", {:text=>"Ruby on Rails Tutorial Sample App | Home"}) to return true, got false
# ./spec/requests/static_pages_spec.rb:16:in `block (3 levels) in <top (required)>'
Finished in 1.91 seconds
5 examples, 1 failure
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:14 # Static pages Home page should have the title 'Home'
Randomized with seed 17491
But It should pass, because when I view the page in browser the title is: Ruby on Rails Tutorial Sample App | Sample App, which is correct!
Make sure you're using capybara 1.1.2 in your Gemfile. Starting from 2.0 capybara does not works for title testing (https://github.com/jnicklas/capybara/issues/844)
...
group :test do
gem 'capybara', '1.1.2'
end
For the time being, you should do what #dimuch suggests and make sure you specify the same Capybara version Michael Hartl uses in the tutorial (1.1.2).
If you want to upgrade to Capybara 2.0 in the future and keep your tests for titles, have a look at this StackOverflow answer for a guide to creating a RSpec matcher that will do what you're expecting.
Using capubara 2.0 you should use
page.should have_title("The title")
But in aint work if you dont add
<style type="text/css">head, head title { display: block }</style>
To your application.html
page.title # => "The title"
page.has_title?("The title") # => true
page.should have_title("The title")
I've been using the following and they have been posting green. I dropped have_selector and went with have_title.
it { should have_title( full_title('Sign up') ) }
-- and --
it { should have_title(user.name) }
This is with capybara 2.2.0.
The author, Michael Hartl, says:
Here the rule:
get "static_pages/home"
maps requests for the URI /static_pages/home to the home action in the StaticPages controller.
How? The type of request is given, the url is given, but where is the mapping to a controller and action? My tests all pass, though.
I also tried deleting all the actions in the StaticPagesController, which just looks like this:
class StaticPagesController < ApplicationController
def home
end
def about
end
def help
end
def contact
end
end
...and my tests still pass, which is puzzling. No, I deleted all my actions like this:
class StaticPagesController < ApplicationController
end
The 2nd edition of the book(online) is really frustrating. Specifically, the section about making changes to the Guardfile is impossible to follow. For instance, if I instruct you to edit this file:
blah blah blah
dog dog dog
beetle beetle beetle
jump jump jump
and make these changes:
blah blah blah
.
.
.
go go go
.
.
.
jump jump jump
...would you have any idea where the line 'go go go' should be in the code?
And the hint for exercise 3.5-1 is flat out wrong. If the author would put up a comment section at the end of every chapter, the rails community could self-edit the book.
Tests:
require 'spec_helper'
describe "StaticPages" do
let(:base_title) { "Ruby on Rails Tutorial Sample App" }
describe "Home page" do
it "should have the h1 'Sample App'" do
visit '/static_pages/home'
page.should have_selector('h1', :text => 'Sample App')
end
it "should have the title 'Home'" do
visit "/static_pages/home"
page.should have_selector(
'title',
:text => "#{base_title} | Home")
end
end
describe 'Help page' do
it "should have the h1 'Help'" do
visit "/static_pages/help"
page.should have_selector('h1', :text => 'Help')
end
it "should have the title 'Help'" do
visit '/static_pages/help'
page.should have_selector(
'title',
:text => "#{base_title} | Help")
end
end
describe 'About page' do
it "should have the h1 'About'" do
visit '/static_pages/about'
page.should have_selector('h1', :text => 'About')
end
it "should have the title 'About'" do
visit '/static_pages/about'
page.should have_selector(
'title',
:text => "#{base_title} | About")
end
end
describe 'Contact page' do
it "should have the h1 'Contact'" do
visit '/static_pages/contact'
page.should have_selector('h1', :text => 'Contact')
end
it "should have the title 'Contact'" do
visit '/static_pages/contact'
page.should have_selector(
'title',
:text => "#{base_title} | Contact")
end
end
end
As you can see here:
http://guides.rubyonrails.org/routing.html#http-verb-constraints
it is just a shorthand for
match 'static_pages/home' => 'static_pages#home', :via => :get
Basically Rails infers from your url static_pages/home that you are referring to the StaticPagesController's home action.
Also, when you 'deleted' all your actions, you left the action definitions - which is what the test checks. It just checks if it can go to the home action of your staticpages controller. It doesn't matter if it does nothing, as long as it exists(at least that's what I think your tests does - care to post the tests also?)
If you delete
...
def home
end
...
from your controller, I'm pretty sure your tests will fail
I found an answer to this conundrum. First of all, this is a rails 'problem' not an rspec problem; if I add a route to routes.rb such as:
get "static_pages/dog"
...and then enter the url
http://localhost:3000/static_pages/dog
in my browser, rails complains:
Unknown action
The action 'dog' could not be found for StaticPagesController
Then if I add the dog action to the controller, then create a view,
everything works fine and dandy.
But if I then delete the dog action, and then use the same url,
http://localhost:3000/static_pages/dog
in my browser, this time I get a different result--instead of getting an error the view displays.
As it turns out, that inconsistent behavior is a rails 'feature' called default rendering, explained here:
http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action
According to the docs, all that's needed to render a page is a route and a view--the action is optional.