RSpec+CapybaraでBootstrap 4のドロップダウンをテストする方法
現在、RSpec+Capybaraでテストコードを書こうとしています。
やりたいことはナビゲーションバーの中にあるドロップダウンをクリックして表示されたドロップダウンメニューの中にログアウトというコンテンツがあることを確かめることです。
Viewのコードは下記の通りです。
テンプレートエンジンはslimを、CSSフレームワークはBootstrap 4を使っています。
nav.navbar
ul.navbar-left
= link_to 'brand', authenticated_root_path, class: 'navbar-brand'
ul.navbar-right
li.nav-item.dropdown
= link_to '☰'.html_safe, 'http://example.com', class: 'nav-link dropdown-toggle', id: 'navbarDropdownMenuLink', 'data-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false'
.dropdown-menu aria-labelledby='navbarDropdownMenuLink'
= link_to 'ログアウト', destroy_user_session_path, method: 'delete', class: 'dropdown-item'
次に現状のテストコードは下記の通りです。
feature 'Navigation links for users', :devise do
scenario 'view navigation links' do
user = FactoryGirl.create(:user)
signin(user.email, user.password)
expect(page).to have_content 'brand'
expect(page).to have_content '☰'
end
end
上記のテストコードにドロップダウンのリンクをクリックしていない状態でhave_contentやhave_linkを追加して試してみましたが、htmlとしては存在するためか、テストがパスしてしまいました。
ドロップダウンのリンクをクリックした状態でのみ、ログアウトのリンクが表示されることを確認するにはどうすればいいでしょうか?
2017/1/27 追記
PhantomJS、Poltergeistを使用して上記の問題は解決できたのですが、これまで通っていた下記ヘルパメソッドでCapybara::Poltergeist::MouseEventFailedが発生するようになってしまいました。
def signin(email, password)
visit new_user_session_path
fill_in 'Email', with: email
fill_in 'Password', with: password
click_button 'Sign in' # ここで例外発生
end
エラーメッセージは下記の通りです。
Capybara::Poltergeist::MouseEventFailed: Firing a click at co-ordinates [411.5, 321] failed. Poltergeist detected another element with CSS selector 'html body main div.authform form#new_user.new_user' at this position. It may be overlapping the element you are trying to interact with. If you don't care about overlapping elements, try using node.trigger('click').
バージョンはPhantomJSが2.1.1、Poltergeistが1.13.0です。
Viewのコードを見ても重複は見つからず、firstやallを使って絞り込んでも同様の結果でした。
エラーメッセージに従ってclick_buttonをnode.trigger('click')に変更することで回避はできたのですが、Poltergeistを使う場合、click_buttonは使えなくなるのでしょうか?
2017/2/1 追記
上記の原因はサブミットボタンに設定していたfloatでした。
これを指定していたせいでサブミットボタンがform要素の裏側に回り込んでしまっていたため、サブミットボタンが押せない状況でした。
解決策としては以下の3つです。
- サブミットボタンに適用しているfloatを外す。
- execute_scriptでサブミットボタンに適用されているfloatをテスト時のみ外す。
- サブミットボタンにz-indexを適用する。