はじめに
最近のWebサイトであれば、JavaScriptを利用していないページを探すほうが難しいかと思います。
そんな中で単純にRailsのSystem Specによる検証だけだと、テストを通ったのでリリースしたら実は以下のようなJavaScriptエラーが発生していたみたいな見落としが起こることが時々ありますよね。
解決方法としての理想はJavaScriptが影響する全ての箇所を網羅するようなテストを書くことかもしれませんが、現実的にはそこまで書けないというケースが多いかと思います。
また、全てを網羅していたつもりでも実際には漏れがあって本番環境のコンソールにJavaScriptエラーが表示されていたみたいなことは起こりえます。
そこで今回の記事ではRailsのSystem SpecでJavaScriptエラーを検出する方法を紹介します。
設定例
module Capybara
module Matchers
class JsNoErrorMatcher
def matches?(page)
errors = page.driver.browser.manage.logs.get(:browser)
errors.find_all { |error| error.level == 'WARNING' }.each do |error|
STDERR.puts 'WARN: javascript warning'
STDERR.puts error.message
end
@severe_errors = errors.find_all { |error| error.level == 'SEVERE' }
@severe_errors.empty?
end
def description
'have no js errors'
end
def failure_message
@severe_errors.map(&:message).join("\n")
end
end
def have_no_js_errors
JsNoErrorMatcher.new
end
end
end
RSpec.configure do |config|
config.include Capybara::Matchers, type: :system
driven_by :selenium, using: :headless_chrome
config.after(:each, type: :system) do |example|
if example.metadata[:skip_js_error]
# ログリセット
page.driver.browser.manage.logs.get(:browser)
else
expect(page).to have_no_js_errors
end
end
end
※説明を簡単にする為に1ファイルにまとめて書いていますが実際は分けたほうが綺麗だと思います。
使い方
これまで通りSystem Specを実行することで、JavaScriptエラーが発生した場合には、発生したエラーメッセージが表示されてテストが失敗するようになります。
もしも外部のスクリプトに依存している等の理由により、エラーを無視するしかないみたいなケースでは以下のように書くことで特定のテストだけJavaScriptエラーの検証をスキップすることが出来ます。
it 'ログインできること', skip_js_error: true do
visit root_path
# ...
end
まとめ
というわけで、この記事では「System SpecでJavaScriptエラーを検出する方法」を紹介しました。
既存のテストに設定を足すだけで、JavaScriptエラーに気付けるようになったり、不安定なテストの原因が特定しやすくなったりと役立つことが多いかと思います。