如何使用Capybara 2.0测试页面标题?

Mel*_*emi 19 rspec ruby-on-rails capybara

试图测试该页面包含<title>My Title</title>:

# spec/features/reports_spec.rb
require 'spec_helper'

feature "Archive Management" do
  subject { page }

  describe "Index Page" do
    before(:all) { 10.times { FactoryGirl.create(:randomreport) } }
    after(:all) { Report.delete_all }

    describe "when no search terms present" do
      before { visit reports_path }

      it { should have_selector('title', text: 'My Title') } # <= Fails w/Capybara 2.0
      it { should have_selector('title') }                   # <= passes
      it { should have_text('My Title') }                    # <= passes
      it { should have_selector('h2', text: "Welcome") }     # <= passes
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

错误信息:

 Failure/Error: it { should have_selector('title', text: base_title) }
 Capybara::ExpectationNotMet:
   expected to find css "title" with text "My Title" but there were no matches. Also found "", which matched the selector but not all filters.
Run Code Online (Sandbox Code Playgroud)

我知道我忽略了痛苦的明显,但无法弄清楚它是什么?<title>标签是否不再被视为"选择器"?!?要么...?!?

编辑(调试器信息):

如果我按照@shioyama的巧妙建议下载到调试器中,很明显page.body包含<title>My Title</title>.包含<h2>Welcome to My Title Project</h2>并传递的相同page.body !

它似乎找到了<title>... </title>标签但不在My Title其中.但它确实会My Title在页面内部<a href=\"/\" class=\"brand\">My Title</a>和/或之后找到<h2>Welcome to The My Title Project</h2>:

(rdb:1) p page
#<Capybara::Session>
(rdb:1) p page.body
"<!DOCTYPE html>\n<html>\n<head>\n<title>My Title</title>\n
<meta content='research, report, technology' name='keywords'>\n<meta 
content='Some Project' name='description'>\n<link href=\"/assets/application.css\"
...
</head>\n<body>\n<header class='navbar navbar-fixed-top 
navbar-inverse'>\n<div class='navbar-inner'>\n<div class='container'>\n
<a href=\"/\" class=\"brand\">My Title</a>\n<div class='pull-right'>\n
<ul class='nav'>\n<li><a href=\"/about\">About</a></li>\n<li><a href=\"/help\">Help</a>
</li>\n</ul>\n<form accept-charset=\"UTF-8\" action=\"/reports\" 
class=\"navbar-search\" method=\"get\"><div style=\"margin:0;padding:0;display:inline\">
<input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div>\n
<input class=\"search-query\" id=\"query\" name=\"query\" 
placeholder=\"Search\" type=\"text\" />\n</form>\n\n</div>\n</div>\n</div>\n</header>\n\n
<div class='container'>\n<div class='hero-unit center'>\n<h1>My Title</h1>\n
<h2>Welcome to The My Title Project</h2>\n<p>Lorem ipsum dolor sit amet, consectetur 
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
...
Run Code Online (Sandbox Code Playgroud)

我还可以在调试器中尝试找出为什么has_selector?('title',text:...)失败?

那么,在Capybara 2.0中测试标题的正确方法是什么?

Pau*_*nti 35

当我升级到Capybara 2.0时,我遇到了同样的问题,并设法通过创建以下自定义RSpec匹配器来解决它们Capybara.string:

规格/支持/ utilities.rb

RSpec::Matchers::define :have_title do |text|
  match do |page|
    Capybara.string(page.body).has_selector?('title', text: text)
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,在spec文件中subject { page },我可以使用:

it { should have_title("My Title") }
it { should_not have_title("My Title") }
Run Code Online (Sandbox Code Playgroud)

顺便说一句,关于这个问题的对话对我这个答案非常有帮助,谢谢!

更新1:

如果您不想创建自定义RSpec匹配器,感谢用户dimuch的这个StackOverflow答案我现在知道您可以直接调用(别名)来测试不可见的DOM元素:have_selectorpage.sourcepage.body

it "should show the correct title" do
  page.source.should have_selector('title', text: 'My Title')
end
Run Code Online (Sandbox Code Playgroud)

或者在哪里subject { page }:

its(:source) { should have_selector('title', text: 'My Title') }
Run Code Online (Sandbox Code Playgroud)

更新2:

从Capybara 2.1开始,有内置have_title/ has_title?匹配器,在这个答案中无需定制RSpec匹配器.此外,its(:source) { ... }Update 1中描述的测试似乎在Capybara 2.1中有所突破; 我已经按预期确认了have_title/ has_title?work,所以如果您打算升级,最好使用以下语法:

时间subject { page }:

it { should have_title("My Title") }
it { should_not have_title("My Title") }
Run Code Online (Sandbox Code Playgroud)

在/ block中使用expect语法时:itscenario

expect(page).to have_title("My Title")
expect(page).to_not have_title("My Title")
Run Code Online (Sandbox Code Playgroud)