Capybaraのアップグレードは想像したよりは楽だった
- gemのアップグレード
- featuresフォルダ
- :type => :request → :type => :feature
- Ambiguous match の修正
- within の追加
- find -> first
- within自体のエラーの修正
- 正規表現で対応
- 他
- inputのエラー (hiddenで失敗している場合がある)
- wait_until
- optionがマッチしない
- テキストで無理矢理マッチ (click_onとか)
- 随時追加
gemのアップグレード
必要に応じてGemfile
のgem 'capybara'
のバージョンを変更
$ bundle update capybara
featuresフォルダ (複数形)
acceptance, integration
など必要に応じてfeatures
にリネーム
※フォルダは複数形(これを単数形にして少しはまった)
:type => :feature (単数形) に変更
config.include Capybara::SomeModule, :type => :request
# ↓
config.include Capybara::SomeModule, :type => :feature
フォルダ名と違ってこちらは単数
config.before/after
などでも使ってたりする
基本:request
のシンボルで検索すれば良いはず
Ambiguous match の修正
within の追加
ボタンとかリンクでAmbiguous match errorが起きやすい
click_on '編集'
などは
within('#hoge') do
click_on '編集'
end
idなどが無くて within
が利用できない場合は、最初の要素で良ければ first('.edit_link').click
などを検討する
find -> first
find('.hoge').click
などをversion1で使っていたならそれは first
なのでfirst('.hoge').click
にする
within自体のエラー修正
within自体が複数マッチでエラーになることも多い。その場合は
- withinを分解してパスを追加
within('.hoge') do
first('.button').click
end
# ↓
first('.hoge .button').click
- firstなどをチェーンする
first('.hoge').first('.button').click
正規表現で対応
page.should have_content("2")
page.should have_content("Password")
# ↓
page.should have_content(/^2$/)
page.should have_content(/^Password$/)
※ 場合によっては first('.hoge').text.should match('aaa')
とかも使えるかも
他
inputのエラー (hiddenで失敗している場合がある)
first('.hoge input').set('Hello')
などうまくいっていたものが失敗することがある
input type=hiddenにマッチしていることが原因だったりする
またこれは使用しているjavascript_driverによって挙動が異なる可能性もある
デバッグ
debugger> all('.hoge input').map{|e| e[:type] }
# => ["hidden", "number", "text", "submit"]
※ input type="number, email"などもあるが、非対応ブラウザでは"text"になることもある
first('.hoge input', :visible => true).set('Hello')
でうまく行く場合もある
wait_until
wait_until
はなくなったので have_selector(selector, visible: true)
とか試してみる
optionがマッチしない
checkbox, radio, selectなどのラベルマッチは完全一致になった模様
テキストで無理矢理マッチ (click_onとか)
all()
からselect, detectとか
first('.some_form').all('input').detect{|e| e[:type] == "number" }.set(3)
first('.some_form').all('input').detect{|e| ["text", "number"].include?(e[:type]) }.set(3)
all("#hoge a.btn").detect{|b| b.text == 'キャンセル' }.click
※ all()
の一致element数が数百とかあるとパフォーマンスの影響がでるかも
※ click_on
が失敗している時などの最終手段かと
メモ
Capybara 2.0 Upgrade Guideを見てみる
- Ruby 1.8.7 互換はなくす予定
- Password/Password Confirmation みたいのは基本id使え
- なければclassでも追加してくれ
-
find(:my_id)
使ってたらfind('#my_id')
に変える -
has_content?
はsubstringsのチェックになった -
select/unselect
は完全一致 -
Capybara.timeout
とwait_until
は削除された
New feature
find(:field, '...')
- add_selectorをチェック
-
has_content?
で正規表現使える
他気付いた点
- capybara-webkitは一応自分でやったのは動いた
- webkitはseleniumの2倍くらい速い
- マニアックな操作はseleniumで解決できる場合がある
- ドラッグアンドドロップ
- 複数ウインドウ (using_sessionではなくリンクからのポップアップ)