Help us understand the problem. What is going on with this article?

Rspec Capybaraで実際テストを書いて困ったシチュエーションの解消法

More than 3 years have passed since last update.

オレが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

kon_yu
道産子プログラマ
http://konyu.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away