Search code examples
rubycapybaraacceptance-testing

Why is this Capbara 'have_content' expectation unexpectedly passing?


I am trying to do some acceptance testing and confirm the presence of a model's various attributes being rendered on a Quote#show page. I am using code an expectation as below;

expect(page).to have_content("#{quote.industry}")

I am using FactoryGirl to Quote.create with required object attrs. Quote.industry is an enum created on the quote model with a range of options, all works and renders just fine. However wven when I comment out the diaplay of this attribute on the template the test still passes. There is no other element on the page that matches quote.industry. I cannot work out what's going on?

Secondary to actually understanding what's going on with the above, perhaps it' bad form to be interpolating a value into a Capybara matcher argument? Should one stick to giving strings to the have_content matcher? But perhaps the argument given to have_content should just be a string, as opposed to an interpolated FactoryGirl object. Is this acceptable practice?

Thanks

quote_page_spec.rb

require 'rails_helper'

feature 'quote page' do
    scenario 'renders all quote attributes' do
        quote = FactoryGirl.create(:quote)
        visit("/quotes/#{quote.id}")

        expect(page).to have_content("#{quote.industry}")
    end
end

factories/quotes.rb

FactoryGirl.define do
  factory :quote do
    sequence(:co_name) { |n| "Acme Co #{n}" }
    industry Quote.industries[:financial_services]
  end
end

models/quote.rb

class Quote < ApplicationRecord
    enum industry:          [ :financial_services, :architect, :business_consultancy ]
    enum payment_frequency: [ :annually, :monthly ]
end

show.html.erb

<div class="container">
    <div class="row">
    <div class="col-md-6">
        <table class="table table-bordered table-responsive">
          <thead>
            <tr>
              <th>Property</th>
              <th>Value</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Company name</td>
              <td><%= @quote.co_name %></td>
            </tr>
            <tr>
              <td>Company number</td>
              <td><%= @quote.co_number %></td>
            </tr>
            <tr>
              <td>Office postcode</td>
              <td><%= @quote.postcode %></td>
            </tr>
            <!-- <tr>
              <td>Industry</td>
              <td><%= @quote.industry %></td>
            </tr> -->
          </tbody>
        </table>
        </div>
    </div>
</div>

Solution

  • have_content matching (by default) does substring matching. If quote.industry is nil it will get interpolated to an empty string which is a substring of any content on the page so the test will pass.