Rails E2Eテストで poltergeist から Headless Chrome へと乗り換える

(image)Rails E2Eテストで poltergeist から Headless Chrome へと乗り換える
目次

RailsのCapybaraを使ったE2Eテスト(feature spec)をこの度、poltergeistからHeadless Chromeに乗り換えてみたのでそのときのメモ。

対応 Pull Request

今回対応したPull Requestはこちら。

Use headless Chrome instead of PhantomJS(poltergeist) by toshimaru · Pull Request #211 · toshimaru/RailsTwitterClone · GitHub

思ったよりも差分はコンパクトにまとまりました。

Install selenium-webdriver

まずはpoltergeist gemの代わりに、selenium-webdriverをインストール。

-  gem "poltergeist"
+  gem "selenium-webdriver"

Change Capybara.javascript_driver

次にCapybara.javascript_driver:poltergeistから:selenium_chrome_headlessに変更します。

- require "capybara/poltergeist"
- Capybara.javascript_driver = :poltergeist
+ require "selenium-webdriver"
+ Capybara.javascript_driver = :selenium_chrome_headless

ちなみに:selenium_chrome_headlessの設定は下記の変更の中でcapybara内に取り込まれています。

Capybara.register_driver :selenium_chrome_headless do |app|
  browser_options = ::Selenium::WebDriver::Chrome::Options.new
  browser_options.args << '--headless'
  browser_options.args << '--disable-gpu'
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end

via. add default selenium chrome driver registrations · teamcapybara/capybara@0275eab · GitHub

Install chromedriver

On MacOS

chromedriver が必要になってくるが、Macの場合はbrewで入れちゃうのが一番ラクです。

$ brew cask install chromedriver
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.

==> Satisfying dependencies
==> Downloading https://chromedriver.storage.googleapis.com/2.41/chromedriver_mac64.zip
######################################################################## 100.0%
==> Verifying checksum for Cask chromedriver
==> Installing Cask chromedriver
==> Extracting nested container chromedriver
==> Linking Binary 'chromedriver' to '/usr/local/bin/chromedriver'.
🍺  chromedriver was successfully installed!

注意事項

  • brew install chromedriverではinstallできないので注意(brew cask経由にすること)
  • chromedriver-helper gem が入っているとうまく動かない場合があるので注意

On CircleCI

CircleCI上では、ruby:x.x-node-browsersのCircleCI公式Ruby Dokcer Imageを使っていればきちんと動作しました。

  docker:
    - image: circleci/ruby:2.5-node-browsers

上記の設定の場合、Ruby2.5のnode-browsersバージョンをベースイメージとして使用しています。

On TravisCI

これが今回の対応で一番ハマった設定でした。いろいろ試しましたが下記のエラーがなかなか解決できませんでした。

Failures:

  1) Authentication authorization screenshot
     Failure/Error: before { visit signin_path }

     Selenium::WebDriver::Error::WebDriverError:
        Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
     # ./spec/features/authentication_pages_spec.rb:9:in `block (3 levels) in <top (required)>'

本当はsudo: falseの設定で動かしたかったのですがそれだと上手くいかなかったのでsudoで起動させてchromium-chromedriverをテスト前にInstallしてパスを通すという方法でテストを通しました。

sudo: required
language: ruby
before_install:
  - sudo apt-get install -y chromium-chromedriver
  - ln -s /usr/lib/chromium-browser/chromedriver ~/bin/chromedriver

(もう少しスマートなやり方をご存知の方は教えていただけると嬉しいです🙏)

追記(2019年9月17日)

sudo 無しでも下記のような設定でいけました。

dist: bionic
addons:
  chrome: stable
  apt:
    packages:
      - chromium-chromedriver

参考Pull Request: No sudo on TravisCI by toshimaru · Pull Request #524 · toshimaru/RailsTwitterClone

参考リンク