Capybara/RSpec 'has_css' не работает, но has_css делает

В приложении Rails 3.2.14 с Ruby 2, используя rspec-rails 2.14.0 и capybara 2.1.0, следующий признак спецификации вызывает сбой:

require 'spec_helper'

feature 'View the homepage' do
  scenario 'user sees relevant page title' do
    visit root_path
    expect(page).to have_css('title', text: "Todo")
  end
end

Сообщение об ошибке:

 1) View the homepage user sees relevant page title
 Failure/Error: expect(page).to have_css('title', text: "Todo")
 Capybara::ExpectationNotMet:
   expected to find css "title" with text "Todo" but there were no matches. Also
   found "", which matched the selector but not all filters.

Элемент title и правильный текст находятся на отображаемой странице

Но когда я изменяю эту строку в спецификации функции:

expect(page).to have_css('title', text: "Todo")

:

page.has_css?('title', text: "Todo")

то тест проходит. [Изменить - но см. Ответ ниже от @JustinKo, что этот тест не является хорошим тестом, поскольку он всегда пройдет)

Как мне получить форму have_css(...)? Это проблема конфигурации?

Здесь соответствующая часть моего Gemfile:

group :development, :test do
  gem 'rspec-rails' 
  gem 'capybara'
end

И мой spec/spec_helper.rb настроен следующим образом:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|

  # out of the box rspec config code ommitted

  config.include Capybara::DSL
end

Кто-нибудь знает, что я могу делать неправильно?

Ответ 1

По умолчанию Capybara ищет только "видимые" элементы. Элемент head (и его элемент title) на самом деле не считается видимым. Это приводит к тому, что элемент title игнорируется в has_css.

Вы можете заставить Capybara также рассмотреть невидимые элементы с помощью опции :visible => false.

expect(page).to have_css('title', :text => 'Todo', :visible => false)

Однако было бы проще использовать метод have_title:

expect(page).to have_title('Todo')