そのページに<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>
を含み、合格する同じ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=\"✓\" /></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でタイトルをテストする適切な方法は何ですか?
Capybara 2.0にアップグレードしたときに同じ問題が発生し、 _Capybara.string
_ を使用して次のカスタムRSpecマッチャーを作成することで問題を解決できました。
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
_
さて、_subject { page }
_のスペックファイルでは、次のものを使用できます。
_it { should have_title("My Title") }
it { should_not have_title("My Title") }
_
余談ですが、この質問についての会話は、私がこの答えにたどり着くのに非常に役立ちました。ありがとうございます。
カスタムRSpecマッチャーを作成したくない場合は、 このStackOverflowの回答 ユーザーによる dimuch _have_selector
_を直接呼び出すことができることがわかりました- _page.source
_ (別名_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) { ... }
テストは、Capybara2.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")
_
Capybara 2.1は、title要素のクエリのサポートを変更しました。したがって、この方法でhtmlドキュメントの先頭にあるtitle要素をクエリするためにhaveセレクターを使用すると、「page.should have_selector( 'title'、:text => 'Some text')」が失敗します。 capybara 2.1の新しいAPIは、「page.should have_title( 'Some text')」を使用して、タイトル要素が機能するかどうかを照会することです。
capybaraをバージョン1.xから> 2.0にアップグレードするときに同じ問題が発生しました
問題は、Capybaraがマッチャー内の非表示のテキストを無視することです。この問題に対処する最もクリーンな方法は、ファインダーで_:visible => false
_オプションを使用することです。
例えば.
it { should have_selector('title', text: 'My Title', visible: false) }
別の(グローバル)オプションは、次のように設定することです。
_Capybara.ignore_hidden_elements = false
_
この問題は、「shared_examples_for」を使用している場合にのみ発生しました。おそらく他の変更が原因です。私が置いたときに私も気づいた
_<title>My Title</title>
_
これはうまくいきました:
it{should have_title("My Title")}
(capybara 2.1.0、launchy 2.3.0、nokogiri 1.5.9、rspec 2.13)
ここに2つの考えられる問題があります。
<title>
_タグはページにありますが、テキスト_My Title
_はタグ内ではなく、ページ上の別の場所にあります。これは、他のテストが合格する理由を説明します。ページに_<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
オプションは厳密であるため、 _My Title
_と正確に等しくない文字列。Xpathセレクターshould have_xpath("//title[contains(.,'#{base_title}')]")
を使用して、これら2つの可能性の後者を確認できます。それが合格した場合は、タイトルテキストの周りに空白または改行があり、_have_selector
_が上になっている可能性があります(これらは無視されていると思いましたが、間違っている可能性があります)。
お役に立てば幸いです。
私はこれがすでに受け入れられた答えを持っていることを知っています、しかしそれが価値があるもののために、あなたはより少ないコード行で以下をすることができます:
title = first("head title").native.text
expect(title).to == "What you expect it to match"
これにより、ネイティブドライバー要素にアクセスできます。さらに、Capybara 2.0は非表示のテキスト(ブラウザ以外ではタイトルは非表示)を無視するため、このケースを満たすには、これ(または同様の回避策)が必要になります。 ( https://github.com/jnicklas/capybara/issues/86 を参照)