如何使用 Capybara 2.0 测试页面标题? [英] How can I test the page title with Capybara 2.0?

查看:28
本文介绍了如何使用 Capybara 2.0 测试页面标题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试测试包含 My Title 的页面:

# spec/features/reports_spec.rb需要'spec_helper'功能档案管理"做主题{页面}描述索引页"做before(:all) { 10.times { FactoryGirl.create(:randomreport) } }after(:all) { Report.delete_all }描述当没有搜索词存在时"做{访问reports_path}之前it { should have_selector('title', text: 'My Title') } # <= 使用 Capybara 2.0 失败it { should have_selector('title') } # <= 通过it { should have_text('My Title') } # <= 通过it { should have_selector('h2', text: "Welcome") } # <= 通过结尾结尾结尾

错误信息:

 失败/错误:它 { should have_selector('title', text: base_title) }水豚::ExpectationNotMet:预计会找到带有文本我的标题"的 css标题",但没有匹配项.还找到了 "",它匹配选择器但不是所有过滤器.

我知道我忽略了明显的痛苦,但无法弄清楚它是什么?</code> 标签不再被视为选择器"了吗?!?或者...?!?</p><p><strong>编辑(调试器信息)</strong>:</p><p>如果我按照@shioyama 的巧妙建议进入调试器,很明显 page.body 包含 <code><title>My Title</title></code>.包含 <code><h2>Welcome to My Title Project</h2></code> 的相同 page.body 并通过!</p><p>它似乎在其中找到了 <code><title></code>...<code> 标签,但没有找到 My Title.但它确实在页面后面的 <a href="/" class="brand">My Title</a> 中找到了 My Title和/或在<h2>Welcome to The My Title Project</h2>:

(rdb:1) p 页#<水豚::会话>(rdb:1) p page.body"<!DOCTYPE html>
<html>
<head>
<title>我的标题</title>
<meta content='research, report, technology' name='keywords'>
<metacontent='Some Project' name='description'>

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

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

解决方案

我在升级到 Capybara 2.0 时遇到了同样的问题,并通过使用 Capybara.string:

spec/support/utilities.rb

RSpec::Matchers::define :have_title do |text|匹配做|页面|Capybara.string(page.body).has_selector?('title', text: text)结尾结尾

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

it { should have_title("My Title") }它 { should_not have_title("我的头衔") }

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

更新 1:

如果您不想创建自定义 RSpec 匹配器,感谢用户 此 StackOverflow 回答="https://stackoverflow.com/users/1416723/dimuch">dimuch 我现在知道你可以直接在 page.source(别名page.body) 测试不可见的 DOM 元素:

它应该显示正确的标题"做page.source.should have_selector('title', text: '我的标题')结尾

subject { page }:

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

更新 2:

从 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") }它 { should_not have_title("我的头衔") }

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

expect(page).to have_title("My Title")期望(页面).to_not have_title(我的标题")

Trying to test that page contains <title>My Title</title> with:

# 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

Error message:

 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.

I know I'm overlooking the painfully obvious but can't figure out what it is? Are <title> tags no longer considered 'selectors'?!? Or...?!?

Edit (debugger info):

If I drop down into the debugger as cleverly suggested by @shioyama it is clear that the page.body contains <title>My Title</title>. The same page.body that contains <h2>Welcome to My Title Project</h2> and passes!

It appears to find the <title>...</title> tag but not My Title within it. But it does find My Title later in the page within <a href="/" class="brand">My Title</a> and/or in <h2>Welcome to The My Title Project</h2>:

(rdb:1) p page
#<Capybara::Session>
(rdb:1) p page.body
"<!DOCTYPE html>
<html>
<head>
<title>My Title</title>

<meta content='research, report, technology' name='keywords'>
<meta 
content='Some Project' name='description'>
<link href="/assets/application.css"
...
</head>
<body>
<header class='navbar navbar-fixed-top 
navbar-inverse'>
<div class='navbar-inner'>
<div class='container'>

<a href="/" class="brand">My Title</a>
<div class='pull-right'>

<ul class='nav'>
<li><a href="/about">About</a></li>
<li><a href="/help">Help</a>
</li>
</ul>
<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>

<input class="search-query" id="query" name="query" 
placeholder="Search" type="text" />
</form>

</div>
</div>
</div>
</header>


<div class='container'>
<div class='hero-unit center'>
<h1>My Title</h1>

<h2>Welcome to The My Title Project</h2>
<p>Lorem ipsum dolor sit amet, consectetur 
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
...

What else could I try in the debugger to figure out why have_selector?('title', text: ...) is failing?

So, what is the proper way to test for a title in Capybara 2.0?

解决方案

I had the same issues when I upgraded to Capybara 2.0, and managed to solve them by creating the following custom RSpec matcher using Capybara.string:

spec/support/utilities.rb

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

Now, in a spec file where subject { page }, I can use:

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

As an aside, the conversation on this question was extremely helpful in getting me to this answer, so thank you!

Update 1:

If you don't want to create a custom RSpec matcher, thanks to this StackOverflow answer by user dimuch I now know that you can call have_selector directly on page.source (aliased page.body) to test for non-visible DOM elements:

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

or where subject { page }:

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

Update 2:

From Capybara 2.1, there are built-in have_title/has_title? matchers, negating the need for the custom RSpec matcher in this answer. Furthermore, the its(:source) { ... } tests described in Update 1 seem to break under Capybara 2.1; I've confirmed the have_title/has_title? work as expected, so it's probably best to go with the following syntax if you plan on upgrading:

When subject { page }:

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

When using expect syntax within an it/scenario block:

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

这篇关于如何使用 Capybara 2.0 测试页面标题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆