please help solve the problem. i use rails4 + rspec + capybara.
my page has title-element:
<!DOCTYPE html>
<html lang="ru">
<head>
<title>I am learning Rails</title>
<link rel="stylesheet" media="all" href="/assets/albums.self855.css?body=1" data-turbolinks-track="true" />
......
.........
........
rspec test:
require 'spec_helper'
describe ImagesController, type: :controller do
describe "index action" do
it 'render title-element on root page' do
visit '/'
#page.should have_selector 'head title', :visible => false
page.should have_selector('head title',
:text => "Складик картинок")
end
end
end
i run in console:
rspec spec
but console displays follow error messages:
...F
Failures:
1) ImagesController index action render title-element on root page
Failure/Error: page.should have_selector('head title',
expected to find css "head title" with text "I am learning Rails" but there were no matches
# ./spec/controllers/images_controller_spec.rb:37:in `block (3 levels) in <top (required)>'
Finished in 0.94045 seconds (files took 1.95 seconds to load)
4 examples, 1 failure
Failed examples:
rspec ./spec/controllers/images_controller_spec.rb:30 # ImagesController index action render title-element on root page
The title element isn't displayed on the page so it's not found by capybaras normal finders, however there is a title matcher you can use
page.should have_title('your title')
Updated Answer:
Turns out that, there is already a have_title [Capybara RSpec matcher]
which you can use to solve your problem.
describe ImagesController, type: :controller do
describe "index action" do
it 'render title-element on root page' do
visit '/'
expect(page).to have_title "Складик картинок"
end
end
end
Related
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 am working my way through Ruby on Rails 2nd Ed., Hartl. In section 3.3.3 my tests failed after I removed some static text with some embedded Ruby. The test was passing previously no problem.
rspec
require 'spec_helper'
describe "Home 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 title 'Home'" do
visit '/static_pages/home'
page.should have_selector('title', :text => "Ruby on Rails Tutorial Sample App | Home")
end
end
end
home.html.erb
<% provide (:title, 'Home') %>
<!DOCTYPE html>
<html>
<head>
<title>Ruby on Rails Tutorial Sample App | <%= yield(:title) %></title>
</head>
<body>
<h1>Sample App</h1>
<p>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</p>
</body>
</html>
error from console
C:\Sites\rails_projects\sample_app>bundle exec rspec spec/requests/static_pages_spec.rb
?[31mF?[0m?[31mF?[0m?[32m.?[0m?[32m.?[0m?[32m.?[0m?[32m.?[0m
Failures:
1) Home pages Home page should have the h1 'Sample App'
?[31mFailure/Error:?[0m ?[31mvisit '/static_pages/home'?[0m
?[31mActionView::Template::Error:?[0m
? [31mC:/Sites/rails_projects/sample_app/app/views/static_pages/home.html.erb:1: syntax error,
unexpected ',', expecting ')'?[0m
?[31m...putBuffer.new; provide (:title, ' Home') ?[0m
?[31m... ^?[0m
? [31mC:/Sites/rails_projects/sample_app/app/views/static_pages/home.html.erb:1: syntax error,
unexpected ')', expecting keyword_end?[0m
?[31m....new; provide (:title, ' Home') ?[0m
?[31m... ^?[0m
?[36m # <internal:prelude>:10:in `synchronize'?[0m
?[36m # ./spec/requests/static_pages_spec.rb:7:in `block (3 levels) in <top (required)>'?[0m
2) Home pages Home page should have the title 'Home'
?[31mFailure/Error:?[0m ?[31mvisit '/static_pages/home'?[0m
?[31mActionView::Template::Error:?[0m
? [31mC:/Sites/rails_projects/sample_app/app/views/static_pages/home.html.erb:1: syntax error,
unexpected ',', expecting ')'?[0m
?[31m...putBuffer.new; provide (:title, ' Home') ?[0m
?[31m... ^?[0m
? [31mC:/Sites/rails_projects/sample_app/app/views/static_pages/home.html.erb:1: syntax error,
unexpected ')', expecting keyword_end?[0m
?[31m....new; provide (:title, ' Home') ?[0m
?[31m... ^?[0m
?[36m # <internal:prelude>:10:in `synchronize'?[0m
?[36m # ./spec/requests/static_pages_spec.rb:12:in `block (3 levels) in <top (required)>'?[0m
Finished in 0.51562 seconds
?[31m6 examples, 2 failures?[0m
Failed examples:
?[31mrspec ./spec/requests/static_pages_spec.rb:6?[0m ?[36m# Home pages Home page should have the h1 'Sample App'?[0m
?[31mrspec ./spec/requests/static_pages_spec.rb:11?[0m ?[36m# Home pages Home page should have the title 'Home'?[0m
Any help is appreciated
I think you need to remove the whitespace prior to the parenthesis
provide (:title, 'Home')
should be
provide(:title, 'Home')
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.
I have the following helper method (app/helpers/application_helper.rb):
module ApplicationHelper
#Return a title on a per-page basis
def title
base_title = "Ruby on Rails Tutorial Sample App"
if #title.nil?
base_title
else
"#{base_title} | #{#title}"
end
end
end
and here's the erb ( app/views/layouts/application.html.erb):
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
I ran an rspec test to see if this helper method works and it seems that it can't find title.
Here's the error message:
Failures:
1) PagesController GET 'home' should be successful
Failure/Error: get 'home'
ActionView::Template::Error:
undefined local variable or method `title' for #<#<Class:0x991ecb4>:0x991315c>
# ./app/views/layouts/application.html.erb:4:in `_app_views_layouts_application_html_erb__248109341_80250010__979063050'
# ./spec/controllers/pages_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
2) PagesController GET 'home' should have the right title
Failure/Error: get 'home'
ActionView::Template::Error:
undefined local variable or method `title' for #<#<Class:0x991ecb4>:0x9d7d094>
# ./app/views/layouts/application.html.erb:4:in `_app_views_layouts_application_html_erb__248109341_82566280__979063050'
# ./spec/controllers/pages_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
Can anyone tell me what I did wrong?
UPDATE:
I included the helper by doing the following:
describe PagesController do
include ApplicationHelper
render_views
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
it "should have the right title" do
get 'home'
response.should have_selector("title",
:content => "Ruby on Rails Tutorial Sample App | Home")
end
end
//and some more
However I am still getting the same error
In your views, the helpers are not included by default.
You can mock out the helper methods using the template object:
template.should_receive(:title).and_return("Title")
You can then test your helpers separately.
Alternatively you can include your helpers in your view spec by simply doing:
include ApplicationHelper
EDIT
describe PagesController do
include ApplicationHelper
describe "GET 'home'" do
it "should be successful" do
controller.template.should_receive(:title).and_return("Title")
get 'home'
response.should be_success
end
end
end
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?
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.
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
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
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