web-dev-qa-db-ja.com

Capybara 2.0でページタイトルをテストするにはどうすればよいですか?

そのページに<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=\"&#x2713;\" /></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でタイトルをテストする適切な方法は何ですか?

19
Meltemi

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") }
_

余談ですが、この質問についての会話は、私がこの答えにたどり着くのに非常に役立ちました。ありがとうございます。

アップデート1:

カスタム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') }
_

アップデート2:

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")
_
35
Paul Fioravanti

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')」を使用して、タイトル要素が機能するかどうかを照会することです。

3
elrick

capybaraをバージョン1.xから> 2.0にアップグレードするときに同じ問題が発生しました

問題は、Capybaraがマッチャー内の非表示のテキストを無視することです。この問題に対処する最もクリーンな方法は、ファインダーで_:visible => false_オプションを使用することです。

例えば.

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

別の(グローバル)オプションは、次のように設定することです。

_Capybara.ignore_hidden_elements = false_

3
dfherr

この問題は、「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
Noddinoff

ここに2つの考えられる問題があります。

  1. _<title>_タグはページにありますが、テキスト_My Title_はタグ内ではなく、ページ上の別の場所にあります。これは、他のテストが合格する理由を説明します。ページに_<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_selector_のtextオプションは厳密であるため、 _My Title_と正確に等しくない文字列。

Xpathセレクターshould have_xpath("//title[contains(.,'#{base_title}')]")を使用して、これら2つの可能性の後者を確認できます。それが合格した場合は、タイトルテキストの周りに空白または改行があり、_have_selector_が上になっている可能性があります(これらは無視されていると思いましたが、間違っている可能性があります)。

お役に立てば幸いです。

1
Chris Salzberg

私はこれがすでに受け入れられた答えを持っていることを知っています、しかしそれが価値があるもののために、あなたはより少ないコード行で以下をすることができます:

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 を参照)

0
Steve Tipton