Capybara 2.0 Upgrade Guide - Funding Gates の意訳です。
capybara の 2.0.0 beta がリリースされたらしく、上記エントリでは重要な変更点とアップグレードの仕方について解説してくれています。
good news と bad news
- 2.0.0 にアップグレードしたら、現在のテストが一部通らなくなるかもしれなません
- 一度 2.0.0 でテストが通るようになったら、そのまま 1.1.2 に戻すことも出来ます。まだ 2.0.0 が肌に合わないようならまだ切り戻すことができます。
互換性
capybara-webkit や poltergeist はまだ Capybara 2.0 に対応していません。ひとまず selenium ドライバを使いましょう。
How to Upgrade
2.0.0 beta は約一ヶ月前にリリースされました。beta よりも master ブランチを使うのをオススメします。
group :test do
gem 'capybara', git: 'https://github.com/jnicklas/capybara'
end
これまでのテストを壊す可能性のある箇所が二つあります。data-method と 曖昧なマッチです。一つずつ紹介していきます。
“data-method” はデフォルトでは無効
(2012/8/30追記) pull request が取り込まれたので、capybara 2.0.0 では下記の記述は無効となりました。Capybara 2.0.0 でも 1.1.2 と同様の挙動をします。
デフォルトの RackTest ドライバ(js: true としなければ使われます)は、設定しない限り data-method 属性を無視するようになりました。 例えば、下記のようなリンクがあったとします
= link_to "Delete", article_path(@article), method: :delete
Capybara 1.1.2 では、 `click_on 'Delete'` は JavaScript が必要なのに関わらずうまくいきますが、Capybara 2.0.0 では :respect_data_method を有効にしないとそのような挙動にはなりません。
require 'capybara/rails'
require 'capybara/rspec'
# Override default rack_test driver to respect data-method attributes.
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new(app, :respect_data_method => true)
end
このエントリの著者([@jo_liss](https://twitter.com/jo_liss))が Issue を上げているので、 2.0.0 のリリース時には :respect_data_method の設定は必要なくなっているかも。
曖昧マッチ
find メソッドは、一つ以上の要素が見つかったときにエラーを発生させるようになりました。( click_on や fill_in なども同じ)
Capybara 1.1.2 では、単純に最初にマッチした要素が選択されますが、現在は曖昧さを排除しないといけません。
下記のコードはテストを壊す可能性がある例です。
fill_in 'Password', with: 'secret'
fill_in 'Password confirmation', with: 'secret'
2.0.0 では最初の fill_in は fail になります。理由は “Password” が “Password” のラベルと “Password confirmation” のラベルと両方にマッチするからです。つまり曖昧だからです。
これを直すには name 属性か id 属性に対してマッチさせるのがよいです。fill_in 'password', with: 'serect' のように。よい name や id がなかったら、補助として “.js-password” と “.js-password-confirmation” クラスを追加するとよいです。(“js-“ プレフィックスは Github styleguide で推奨されているクラスです)(追記: GitHub Styleguide は現在は404になっているようです><)
find('.js-password').set 'secret'
find('.js-password-confirmation').set 'secret'
“.js-“ クラスをテキストの代わりに使うことは、テストを壊れにくくするよいプラクティスです。
以前の挙動が絶対に必要であれば、first メソッドを使うとよいです。
click_on 'ambiguous' # old
first(:link, 'ambiguous').click # new
Minor changes
これらの変更はなにかおかしな事が無ければ、アップグレードしても影響しないと考えられます。
has_content?XPath のcontains(...)を使わずに、textの部分文字列をチェックします。これはつまりスペースの標準化と、headやscriptなどの非表示要素抑制を改善します。selectとunselectは部分文字列のマッチを許可しなくなりました。Capybara.server_boot_timeoutとCapybara.prefer_visible_elementsは必要なくなったので削除されました。Capybara.timeoutとwait_untilは削除されました。。 Selenium ドライバの:resynchronizeオプションも同様です。通常、page.should have_contentやpage.should have_cssで何らかのページ上の変化を探すためには、Ajax リクエストが返ってくるのを待たなければなりません。これらのチェックは Ajax リクエストに対して門のように振る舞い(訳注:Ajax と普通のリクエストの挙動を共通にさせるってことかな)、条件が真になるまで繰り返します。もしうまく動かないようなら、独自のwait_forヘルパメソッドを定義することが出来ます(例: gist)find(:my_id)のようなシンボルシンタックスはなくなるかもしれません。find('#my_id')が推奨されます。
Goodies
アップグレードしてもテストを壊さない、新しい追加要素がありますよ。
find(:field, '...')のような多くの新しいセレクタ。これらは複雑なノードを見つけるのに便利です。lib/capybara/selector.rb 中のadd_selectorをチェックしてみましょう。- has_content? が正規表現を受け付けます。