はじめに
この投稿は、E2Eテストを書く際にハマった箇所の備忘録です
環境
- Rails 5
- rspec-rails (3.5.1)
- poltergeist (1.10.0)
- capybara (2.8.0)
- etc
feature specを書く
前述の環境にある通り、rspec, capybara, poltergeistの組み合わせでfeature specを書くことにしました
既存の環境だったため、なぜこの組み合わせにしたかは言及しません(できません)
ハマりポイント
checkboxをcheckできない
「capybara checkbox」なんかでググると以下のような例がでてきます。
check("id")
find("#id").click
cssを大していじっておらず、シンプルなデフォルトのチェックボックスを使用している場合は、上記の例で動作します。
ただし!
大抵の場合は通用しません。
解決方法
find("id", visible: false).trigger("click")
iframe内のelementを操作しようとして、Capybara::ElementNotFound
手動でWEBブラウザから見る限り存在するidやクラスに対して、
指定したfill_inなどを実行した際にエラーが生じたとき、このエラーの可能性がある
Capybara::ElementNotFound:
Unable to find field "XXX"
外部からjsを読み込んでいる場合(下記のようなソース)の場合、
<script type="text/javascript" src="example1.js"></script>
ブラウザに渡すbodyには、下記のように変換される
<iframe src=以下略>
</iframe>
解決方法
within_frameを用いる
他のwithin~は範囲を絞るだけ(ないものはない)だが、within_frameはframeを展開して、
その中の要素を指定することができる
での動作を記述することができる
within_frame("XXX") do
# この中では、frameで展開される要素を取得できる
# body.inspectで確認可能
end
たまにCapybara::ElementNotFoundが発生する
"たまに"というのが重要
動的にjsをロードし、その要素を操作している場合、このようになることがある
原因はjsのロードが間に合っていないこと
解決方法
とりあえずsleepする
というのでも解決しますが、その場しのぎ的な上、
テストの可読性が下がったり、必要以上にテスト実行時間が伸びるため、おすすめしません
番外~デバッグで役にたったもの~
body.inspect
とりあえずputsして、認識しているbodyを吐いてもらうのに利用
page.save_screenshot
スクショをとってくれる
とりあえず:full => true
動作が追いついているか(jsのロードが終わっているか)など確認できる
save_and_open_page
htmlを保存しつつ、いっそブラウザで開いてしまえ
といったときに利用
静的に、すぐにchromeの検証ができる
セレクタ応用
within_frame(find(:xpath, '//iframe[contains(@src, "URL")]')) do
end
within_frame(find(:css, 'iframe[src^="URL"]')) do
end