I have a many-to-many association between a Post and a Tag model.
Then, I have the following in my post view:
posts/show.html.erb:
<p><%= raw @post.tags.map { |t| link_to t.name, tag_path(t.name) }.join(', ') %></p>
This is the spec I wrote:
post_pages_spec.rb:
describe "show page" do
let!(:post) { FactoryGirl.create(:post, user: user,
title: "Lorem",
content: "Lorem ipsum",
category_id: category.id,
tag_list: "#{tag.id}") }
before do
sign_in user
visit post_path(post)
end
it { should have_selector('h1', text: post.title) }
it { should have_selector('title', text: post.title) }
it { should have_link(post.user.name, href: user_path(user)) }
it { should have_selector('p', text: post.content) }
it { should have_selector('p', text: post.category.name) }
it { find("p").should have_content(post.tags.map { |t| t.name }.join(", ")) }
.
.
.
I’m getting this error:
Failures:
1) Post pages show page
Failure/Error: it { find(“p”).should have_content(post.tags.map { |t| t.name }.join(“, “)) }
expected there to be content “1, tag28” in “Lorem ipsum”
# ./spec/requests/post_pages_spec.rb:28:in `block (3 levels) in ‘
The code works in the real site, but as you can see, the spec is failing. What’s the right way of writing this spec?
EDIT:
An example of the post model (just in case):
class Post < ActiveRecord::Base
include ActionView::Helpers
attr_accessible :title, :content, :category_id, :tag_list
has_many :taggings, :dependent => :destroy
has_many :tags, :through => :taggings
.
.
.
Output from live site:
<p><a href="/tags/inkscape">inkscape</a>, <a href="/tags/gimp">gimp</a></p>
Update
From the comment thread, we’ve figured out that replacing the
findwith a simplehave_selectorpasses:It’s not clear why
find('p').should have_content(...)does not work. I’ve tested the same type of view (with<p>tags wrapping a list of links) and found that thefind('p').should ...pattern works fine, so something funny is happening in your code. It may or may not be related to the issue withhave_contentin Capybara 2.0, which I discuss below.If anyone has any ideas please share them! This is the best I can offer.
Original answer
The new text matcher in Capybara 2.0 excludes content that is not visible, producing somewhat unintuitive results:
And, relevant to the case in this question, this:
See also this post: How can I test the page title with Capybara 2.0?
If
page.body.should ...is working butpage.should ...(or in another form,subject { page} ; it { should ... }) isn’t, then perhaps this is the issue. Note thatpage.bodyis an HTML string, whereaspageis aCapybara::Session, they’re totally different, although it seems in Capybara 2.0 at least you can run your expectations against either. I thinkpage.bodyincludes all HTML, hence bypassing the visibility issue.