自分がCapybaraで一番ハマったのは、画面の初期化や、Ajaxやアニメーションなどの遅延を待たずに、どんどんclickなどを行おうとして意図しない結果になってしまうこと。
ブラウザから自分で試してみてもうまく行くので、自動テストをうまく行かせるためだけのデバッグ作業となり、作業のための作業、これは無駄以外のなんでもない。腹立たしい。
だから、情報共有。
findで要素が準備OKになるまで待たせる
本家の
でも書かれているが、Capybaraにはこういう非同期JavaScriptの問題への対処として、findや、have_content実行時にまだ要素が見つからない場合は、設定した時間(初期値2秒)待ってからリトライをしてくれる。
この機能を使って、clickする、have_xxx で検証するなどの前に、findでちゃんと存在するまでcapybaraに待たせる事が重要。
基本的に非表示要素がfindやhave_selectorなどにヒットしたりしないようにする
feature/support/env.rb にて以下のように設定する。
Capybara.ignore_hidden_elements = true
こうしないと
- 実際に押す事が想定されないタイミングでもリンクがクリックされてしまう
- 意図したタイミング以外で検証してしまう
などで、意図しない状態が生まれる。
たとえば、
- アニメーション完了後に初期化
- その初期化された要素に対してクリックをさせる
という動きを想定していても、アニメーション完了前にクリックにいってしまう。
jQueryのshow()みたいな、時間が短いアニメーションだと、アニメーションの存在にすら気づかずハマったりする。
非表示要素がfindなどにヒットしないことにより、上記のwaiting動作が働き、表示されるまで待ってから押させるようにして解消する。
windowやimgのonloadの初期化を待ってくれない
windowのonloadや、 $('img.hoge').load(function(){ ...
のような画像のロードは
ハンドラーが呼び出される前に、capybaraの処理はがんがん走ってしまう。
できるだけ、DOM readyで初期化するようにすること。
または、画像がloadされるまで待つ、とかそういうcapybara側の処理(cucumberであればstep_difinitionなど)を自作するなどして、意識的に待たせないといけない。
画面遷移を待ってくれない
もしfindで検証したい要素がない場合は待ってくれるが、絞り込み検索画面など、画面遷移前と遷移後がほぼ画面構造が同じ場合、画面遷移がされる前にfindは通過してしまう。
ページタイトルをユニークにするなどしてまずそこで検証をかけると妥当なwaitが発生して回避できる。
以上...
気をつけるべき事はまだ、増えそうだけど、順次増やしていくか ^^;