我如何用Capybara 2.0testing页面标题?

尝试使用以下命令testing包含<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 

错误信息:

  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. 

我知道我忽略了痛苦的明显,但不知道它是什么? <title>标签不再被认为是“select器”吗? 要么…?!?

编辑(debugging器信息)

如果我像@shioyama那样巧妙地build议debugging器,那么很显然page.body包含了<title>My Title</title> 。 包含<h2>Welcome to My Title Project</h2>并通过的相同page.body!

它似乎可以find<title></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=\"✓\" /></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. ... 

还有什么我可以尝试在debugging器找出为什么have_selector?('标题',文本:…)失败?

那么,什么是在水豚2.0中testing一个标题的正确方法呢?

当我升级到Capybara 2.0时,我遇到了同样的问题,并通过使用Capybara.string创build了以下自定义RSpec匹配器来解决这些问题:

规格/支持/ utilities.rb

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

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

 it { should have_title("My Title") } it { should_not have_title("My Title") } 

另外,在这个问题上的对话对我来说是非常有帮助的,所以谢谢!

更新1:

如果你不想创build一个自定义的RSpec匹配器,感谢用户dimuch的 这个StackOverflow答案 ,我现在知道你可以直接调用page.source (别名page.body )上的page.source来testing不可见的DOM元素:

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

subject { page }

 its(:source) { should have_selector('title', text: 'My Title') } 

更新2:

从水豚2.1,有内置的have_title / has_title? 匹配器,在这个答案中否定了对自定义RSpec匹配器的需求。 此外,更新1中描述的its(:source) { ... }testing似乎在水豚2.1下打破; 我已经确认了have_title / has_title? 按预期工作,所以如果您打算升级,最好使用以下语法:

subject { page }

 it { should have_title("My Title") } it { should_not have_title("My Title") } 

it / scenario块中使用expect语法时:

 expect(page).to have_title("My Title") expect(page).to_not have_title("My Title") 

水豚2.1改变了对查询标题元素的支持。 所以使用select器来查询HTML文档头部的标题元素将会失败“page.should have_selector('title',:text =>'Some text')。从我所了解的首选方法在水豚2.1新API是使用“page.should have_title('一些文本')”来查询标题元素应该工作。

从版本1.x升级水豚到> 2.0时遇到同样的问题

问题是水豚忽略了匹配器中的无形文本。 解决这个问题最简单的方法是在finder上使用:visible => false选项。

例如

it { should have_selector('title', text: 'My Title', visible: false) }

另一个(全球)选项是设置:

Capybara.ignore_hidden_elements = false

我只有在使用“shared_examples_for”时才有这个问题,也许是因为其他的改变。 我也注意到,当我放置

 <title>My Title</title> 

在页面的主体(它不属于,不会呈现)中,testing通过。 不是一件好事!

这工作:

 it{should have_title("My Title")} 

(水豚2.1.0,launchy 2.3.0,nokogiri 1.5.9,rspec 2.13)

我在这里看到两个可能的问题:

  1. <title>标签出现在页面上,但文本“ My Title ”位于页面上的其他位置,而不在标签内。 这将解释为什么其他testing通过:页面上有一个<title>标签,所以have_selector('title')通过,页面上有My Title文本,所以have_text(base_title)会通过。
  2. <title>标签包含文本My Title以及其他内容,这也将解释您看到的结果:页面上有一个<title>标签,所以have_selector('title')通过,并且有文本My Title所以have_text(base_title)也通过,但是,在have_selectortext选项是严格的,因此如果它发现一个string不完全等于My Title ,它将失败。

您可以使用xpathselect器检查这两种可能性的后者: should have_xpath("//title[contains(.,'#{base_title}')]") 。 如果通过的话,那么你的标题文本可能会有一些空格或换行符,这些空格或换行符正在触发have_selector (我认为它忽略了这些,但我可能是错的)。

希望有所帮助。

我知道这已经有了一个可以接受的答案,但是对于它的价值,你可以用下面的代码来完成以下工作:

 title = first("head title").native.text expect(title).to == "What you expect it to match" 

这允许访问本地驱动程序元素; 此外,由于水豚2.0忽略不可见的文本(除了浏览器,标题是不可见的),你需要这个(或类似的解决方法)来满足这种情况。 (见https://github.com/jnicklas/capybara/issues/863