163
161

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-04

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

163
161
0

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
163
161

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?