LoginSignup
2

More than 5 years have passed since last update.

feature specでjsを動かすときのハマりどころ

Last updated at Posted at 2018-06-21

はじめに

この投稿は、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などを実行した際にエラーが生じたとき、このエラーの可能性がある

rspec実行結果
Capybara::ElementNotFound:
       Unable to find field "XXX"

外部からjsを読み込んでいる場合(下記のようなソース)の場合、

js読み込みを行うソース例
<script type="text/javascript" src="example1.js"></script>

ブラウザに渡すbodyには、下記のように変換される

body.inspectの内容
<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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2