我如何用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)
我在这里看到两个可能的问题:
-
<title>
标签出现在页面上,但文本“My Title
”位于页面上的其他位置,而不在标签内。 这将解释为什么其他testing通过:页面上有一个<title>
标签,所以have_selector('title')
通过,页面上有My Title
文本,所以have_text(base_title)
会通过。 -
<title>
标签包含文本My Title
以及其他内容,这也将解释您看到的结果:页面上有一个<title>
标签,所以have_selector('title')
通过,并且有文本My Title
所以have_text(base_title)
也通过,但是,在have_selector
的text
选项是严格的,因此如果它发现一个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 )