オレがRailsで困ったことをググるとだいたい先に解決してくれているでお馴染みの@jnchitoさんの大変参考にしているCapybaraの記事
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」
これには載っていないが、実際のテストを書く上で遭遇してどうやってspecファイルを書いたらいいものかこまった事象を幾つか解決したので共有したいと思う
テキストエリアに文字を入力したいけど、idがなくてfill_inが出来ない時
発生したシチュエーション
テキストエリアに文字を入力する際にはfill_inを使い以下のように指定するが、fill_inを使うにはIDを指定する必要がある。
fill_in "id名", with: "入力値"
# こう書くことが出来ない
# fill_in ".cssClassName", with: "入力値"
解決したRspecの書き方
CSSセレクタで指定してsetを使い値を入力する
find(".cssClassName").set("入力値")
# 同じクラスのものが複数ある場合は、更に絞り込んでやると入力できる
(all(".cssClassName")[2]).set("入力値")
ref: http://stackoverflow.com/questions/8534365/how-to-use-fill-in-with-find-in-capybara-if-possible
ボタンにテキストがない場合は、findで絞り込んでクリック
発生したシチュエーション
以下のようにbuttonタグ内にボタン名以外のタグを含んでいたり、動的に変わる数字を含んでいる場合
click_onでうまくクリックさせることが出来ない
#<button class="cssClassName">ボタン名</button>
# このような場合は押せる
click_on "ボタン名"
#<button class="cssClassName"><i xxxx />ボタン名</button>
#<button class="cssClassName">ボタン名(1)</button>
# こんな感じだタグ内の値だとうまくいかない
# click_on "ボタン名"
解決したRspecの書き方
findでCSSセレクタで対象のタグ絞り込んでクリックしてやる
find(".cssClassName").click
Page全体ではなく把握て絞り込んだ領域内の値で判定したい時
発生したシチュエーション
あるボタンを押して、実行結果を確認する方法として, page全体からある値があるかどうかを見るのに
have_contentを使うが、この探している値がボタンを押す前から表示されていてる場合は正しい検査ができない。
# これだと探している値はボタンを押す前から表示されているのでボタンの押す押さないにかかわらずテストが通ってしまう
expect(page).to have_content "探している値"
解決したRspecの書き方
検査対象をpage全体ではなく、特定の領域を対象にしてhave_contentを使うと良い
expect(find("#someId")).to have_content "探している値"
TinyMCEをpoltergeistで値を入力した場合
発生したシチュエーション
TinyMCE( https://www.tinymce.com/ )と言うWYSWIYGエディタに値を入力したい場合、
テキストエリアのようにfill_inで入力することが出来ない
Rspecの書き方
TinyMCEのエディタは指定したID+_ifrというID名のIFrameが作成されその中のbodyタグのなかがTextAreaの中身というような感じに構成されている
iframeで絞り込むwithin_frameを使いつつキー入力してやる必要がある
within_frame("tinymaceID_ifr") do
element = find("body")
element.native.send_keys("input sentence")
end
ref: https://github.com/teampoltergeist/poltergeist/issues/445
画面の任意の位置をクリックしたい場合
発生したシチュエーション
モーダルダイアログがあり、画面のモーダル以外の部分をクリックした場合にモーダルが消えることを確認したい場合
解決したRspecの書き方
# x, y でピクセル位置を指定
page.driver.click(x, y)
# Bodyタグをクリックしても良さそう
first("body").click
#ラベルのないチェックボックスがチェックされているか判定する
発生したシチュエーション
チェックボックスにラベルがない場合、後述するシンプルな書き方ができない
解決したRspecの書き方
チェックボックスにラベルがない場合
<input type="checkbox" id="foobar" value="yes" checked="checked">
対象のオブジェクトを取得してチェックがされているか判定する
checkbox = find("#foobar")
expect(checkbox).to be_checked
チェックボックスにラベルがある場合
<label>html
<input type="checkbox" id="foobar" value="yes" checked="checked">
ラベル名
</label>
# テストはこんな感じ
expect(page).to have_checked_field("ラベル名")
ref: http://stackoverflow.com/questions/9570588/how-to-obtain-the-value-of-a-checkbox-in-capybara
パラメタ付きのURLをチェックする
発生したシチュエーション
あるリンクを押して/foo/bar?param1=1へ遷移した時に
current_urlだと/foo/bar/ しか取れないで以下のテストをしても、テストが通らない
expect(current_url).to foo_bar_index_path(param1: 1)
# current_url => /foo/bar
# foo_bar_index_path(param1: 1) => /foo/bar?param1=1
urlの?foo=barなどが取れない
解決したRspecの書き方
URIオブジェクトを作ってから比較してあげると良い
uri = URI.parse(current_url)
expect("#{uri.path}?#{uri.query}").to eq user_index_path(param1: 1)
/user?param1=1
ref: http://stackoverflow.com/questions/5228371/how-to-get-current-path-with-query-string-using-capybara
confirm ウインドウをOKボタンを押す
動作確認してません
# OKボタン
page.driver.browser.switch_to.alert.accept
# キャンセル
page.driver.browser.switch_to.alert.dismiss
ref: http://qiita.com/sawamur@github/items/952f34ac07cc3cc7515f