Final Edit:
Thanks to @PeterAlfvin's suggestion that I focus on the application layout and the header, I was able to fix it. I haven't been able to figure out exactly what the problem was, but something in the header was causing capybara to not 'see' the rest of the page. I removed <%= render 'layouts/header' %>
, re-built the header inside application.html.erb
, and once it was working, pulled it out into a partial and replaced the render statement. I fiddled with both the old and new header files to try to figure out the problem, but no success with that yet. That makes my tests seem a bit brittle, but if the problem arises again, at least I'll know where to look.
Edit: If you feel inclined to downvote, please go ahead, but let me know what I have overlooked or failed to research, because your comment might help me figure this out.
I've searched for HOURS trying to fix this, but I can't figure out what's going on. I'm sure I'm missing something simple that will be obvious to anyone who hasn't been staring at it for the last day. That's my hope, anyway.
All of my Rspec/capybara request specs are failing, but when I view the pages in my browser, all the elements that the specs fail to find are plainly there. As far as I can tell, Capybara isn't seeing the entire page- save_and_open_page returns a nearly-blank page. The failure I see with the spec below is universal- the specs can see the page title, but not anything in the page body. I'm fairly confident that all my routes are good, because all the title tests pass when they should.
spec/requests/static_pages_spec.rb
require 'spec_helper'
describe "StaticPages" do
subject { page }
describe "About page" do
before { visit about_path }
it { save_and_open_page;
should have_selector('title', text: 'Company Name | About') }
it { should have_selector('h1', text: 'About stuff') }
it { should have_content('About paragraph') }
end
#more specs...
end
results:
5) StaticPages About page
Failure/Error: it { should have_selector('h1', text: 'About stuff') }
expected css "h1" with text "About stuff" to return something
# ./spec/requests/static_pages_spec.rb:28:in `block (3 levels) in <top (required)>'
6) StaticPages About page
Failure/Error: it { should have_content('About paragraph') }
expected there to be content "About paragraph" in "Company Name | About\n\t\n\t\t"
# ./spec/requests/static_pages_spec.rb:29:in `block (3 levels) in <top (required)>'
Here's the "view source" output of the page opened in my browser by save_and_open_page:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Company Name | About</title>
<link href="/assets/application.css" media="all" rel="stylesheet" type="text/css">
<script src="/assets/application.js" type="text/javascript"></script><!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<header class="navbar navbar-fixed-top navbar-inverse"><div class="navbar-inner">
</div></header>
</body>
</html>
So, based on the source, and the response message for spec #6, it looks like it isn't searching any content besides the page title, which would be supported by the fact that my title tests always pass, but nothing else does. I have tests that look for form elements, buttons, etc, and I've tried identifying them different ways (label, id, name), but capybara can't find any of them. Again, when I view these pages in my browser, everything is plainly visible, and labelled correctly.
When I visit the About page in my browser, this is the page source for the body, in contrast to the body content shown above:
<body>
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<a class="brand" href='/'>Company Name</a>
<ul class="nav pull-left">
<li><a href="/products">Products</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
<ul class="nav pull-right">
<li><a href="/users/sign_in">Sign in</a></li>
</ul>
</div>
</header>
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 offset2"></div>
<h1>About stuff</h1>
<p>About paragraph</p>
</div>
</div>
</body>
Gemfile:
source 'https://rubygems.org'
gem 'rails', '3.2.13'
gem 'bootstrap-sass', '2.1'
gem 'faker', '1.1.2'
gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'
gem 'jquery-rails'
gem 'devise'
gem 'foreigner'
gem 'paper_trail'
group :development, :test do
gem 'sqlite3', '1.3.7'
gem 'rspec-rails', '2.11.0'
gem 'letter_opener'
gem 'factory_girl_rails', '4.1.0'
end
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '3.2.5'
gem 'coffee-rails', '3.2.2'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '1.2.3'
end
group :test do
gem 'capybara', '1.1.2'
# gem 'rb-inotify', '0.8.8'
# gem 'libnotify, '0.5.9'
gem 'shoulda-matchers'
gem 'accept_values_for'
end
group :production do
gem 'pg', '0.12.2'
end
Any help towards sorting this out will be greatly appreciated. Please let me know if I should include any additional info.
Edit to add erb files
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<%= render 'layouts/header' %>
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 offset2">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value%></div>
<% end %>
</div>
<%= yield %>
<%= render 'layouts/footer' %>
<%= debug(params) if Rails.env.development? %>
</div>
</div>
</body>
</html>
app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<a class="brand" href='/'>Company Name</a>
<ul class="nav pull-left">
<li><%= link_to "Products", products_path %></li>
<li><%= link_to "About", about_path %></li>
<li><%= link_to "Contact", contact_path %></li>
</ul>
<% if user_signed_in? %>
<ul class="nav pull-right">
<li><strong><%= current_user.email %></strong></li>
<li><%= link_to 'Account', account_path %></li>
<li><%= link_to "Sign out", destroy_user_session_path, method: :delete %></li>
</ul>
<% else %>
<ul class="nav pull-right">
<li><%= link_to "Sign in", new_user_session_path %></li>
</ul>
<% end %>
</div>
</header>
app/views/layouts/_footer.html.erb
<footer class="footer">
<small>Company Name Price Management</small>
</footer>
app/views/static_pages/about.html.erb
<% provide(:title, 'About') %>
<h1>About stuff</h1>
<p>About paragraph</p>
save_and_open_page
in your spec and a source file of the same name. How are these two related? What does thesave_and_open_page
method do? – Peter Alfvinsave_and_open_page
and instead just doing aputs page
at that point to see if the content is the same? – Peter Alfvinsubject
anywhere for rspec. Have you triedsubject {page}
? – Peter Alfvinabout_path
is valid, I'd start modifying your_layout.html.erb
file to see if you can establish the correlation of that file to what your test produces. Right now, it's not showing any of the content of thenavbar-inner
div. You could add something to that div tag (e.g. anid
) and see if it shows up in your test. I'm assuming there's no timing issue here since capybara should "wait" until the page refreshes, but you could try a delay as well, just to rule that out. – Peter Alfvin