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? が正規表現を受け付けます。