尝试使用以下内容测试该页面包含<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>
代码不再被视为“选择者”吗?!?要么...?!?
编辑(调试器信息):
如果我按照@shioyama的巧妙建议进入调试器,很明显page.body包含<title>My Title</title>
。包含<h2>Welcome to My Title Project</h2>
并传递的同一页面。
它似乎找到了<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=\"✓\" /></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.
...
我还可以在调试器中尝试找出为什么有have_selector?('title',text:...)失败?
那么,在Capybara 2.0中测试标题的正确方法是什么?
答案 0 :(得分:35)
当我升级到Capybara 2.0时遇到了同样的问题,并设法通过使用Capybara.string
创建以下自定义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") }
顺便说一下,关于这个问题的对话对我这个答案非常有帮助,谢谢!
如果您不想创建自定义RSpec匹配器,感谢用户this StackOverflow answer的dimuch我现在知道您可以直接在page.source
上致电have_selector
(别名page.body
)来测试不可见的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') }
从Capybara 2.1开始,内置have_title
/ has_title?
匹配器,在此答案中无需使用自定义RSpec匹配器。此外,更新1中描述的its(:source) { ... }
测试似乎在Capybara 2.1下打破;我已按预期确认have_title
/ has_title?
工作,因此如果您计划升级,最好采用以下语法:
subject { page }
时:
it { should have_title("My Title") }
it { should_not have_title("My Title") }
在expect
/ it
块中使用scenario
语法时:
expect(page).to have_title("My Title")
expect(page).to_not have_title("My Title")
答案 1 :(得分:3)
Capybara 2.1改变了对查询标题元素的支持。因此,使用选择器以这种方式查询html doc头部中的title元素将失败“page.should have_selector('title',:text =&gt;'some text')。从我理解的首选在capybara中的方法2.1新的API是使用“page.should have_title('Some text')”来查询title元素应该有效。
答案 2 :(得分:3)
我将capybara从版本1.x升级到&gt;时遇到了同样的问题。 2.0
问题是Capybara在其匹配器中忽略了隐形文本。解决此问题的最简单方法是在finder上使用:visible => false
选项。
e.g。
it { should have_selector('title', text: 'My Title', visible: false) }
另一个(全局)选项是设置:
Capybara.ignore_hidden_elements = false
答案 3 :(得分:2)
我在使用'shared_examples_for'时遇到此问题,可能是因为其他更改。我还注意到,当我将
<title>My Title</title>
放在页面主体中(它不属于且不会渲染)时,测试通过了。不是一件好事!
这有效:
it{should have_title("My Title")}
(水豚2.1.0, launchy 2.3.0, nokogiri 1.5.9, rspec 2.13)
答案 4 :(得分:1)
我在这里看到两个可能的问题:
<title>
标记,但文字My Title
位于页面上的其他位置,而不在标记内。这可以解释为什么其他测试通过:页面上有一个<title>
标记,have_selector('title')
通过,页面上有My Title
文字,have_text(base_title)
通过。 <title>
标记包含文字My Title
以及其他内容,这也可以解释您看到的结果:页面上有<title>
标记,因此{{1}传递,并且文本have_selector('title')
因此My Title
也传递,但have_text(base_title)
中的text
选项是严格的,因此如果它找到一个字符串,它将失败并不完全等于have_selector
。您可以使用xpath选择器检查后两种可能性:My Title
。如果它通过了,那么你的标题文本周围可能会有一些空格或换行符should have_xpath("//title[contains(.,'#{base_title}')]")
绊倒(我认为它忽略了那些,但我可能错了)。
希望有所帮助。
答案 5 :(得分:0)
我知道这已有一个已接受的答案,但是对于它的价值,你可以用更少的代码行完成以下工作:
title = first("head title").native.text
expect(title).to == "What you expect it to match"
这允许访问本机驱动程序元素;此外,由于Capybara 2.0忽略了不可见的文本(标题除浏览器外不可见),您需要这个(或类似的解决方法)来满足这种情况。 (见https://github.com/jnicklas/capybara/issues/863)