Dockerでブラウザテストを実行するための環境構築手順

RailsアプリケーションをDocker化する際にブラウザテスト関係でつまったのでメモをしておきます。
なお、テストは`RSpec`, ブラウザテストツールは`Capybara`、Dockerのベースイメージは`ruby:2.4.4`を利用しています。

## 現状確認
ローカルのRailsアプリケーションではブラウザテストは問題なく実行できるがDokcer上でブラウザ関連のテストを実行しようとすると、以下のようなエラーが出るという状態

```
$ bundle exec rspec spec/features/sample_spec.rb

Selenium::WebDriver::Error::WebDriverError:
             Unable to find chromedriver. Please download the server from http://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH. More info at https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver.
```

## chromedriverのインストール

```
### chromedriverのダウンロード
$ CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`
$ wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip

### ダウンロードファイルの解凍
$ apt-get install unzip 
$ unzip chromedriver_linux64.zip
$ rm chromedriver_linux64.zip

### rubyのパスに配置
$ which ruby
-> /usr/local/bin/ruby
$ mv chromedriver /usr/local/bin/

### chromedriver確認
$ which chromedriver
-> /usr/local/bin/chromedriver
$ (chromedriver -v)
-> ChromeDriver 2.46.628388 (4a34a70827ac54148e092aafb70504c4ea7ae926)
```

## Chromeをインストールするために、署名鍵を追加
```
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
$ sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
```
なお、署名鍵がないと以下のようなエラーが発生し、google-chrome-stableをインストールできないので注意

```
$ apt-get install google-chrome-stable

パッケージ google-chrome-stable は使用できませんが、別のパッケージから参照されます。
これは、パッケージが欠落しているか、廃止されたか、または別のソース
からのみ利用可能であることを意味します。

E: パッケージ 'google-chrome-stable' にはインストール候補がありません
```

## Chromeのインストール

署名鍵を追加したら、google-chrome-stableが無事インストールできるようになっている

```
$ apt-get update
$ apt-get install google-chrome-stable
```

## Capybaraのオプションの修正
必要なツールをダウンロードできたので再度実行してみる。しかし、以下のようなエラーがでる

```
$ bundle exec rspec spec/features/sample_spec.rb

Selenium::WebDriver::Error::UnknownError:
            unknown error: Chrome failed to start: exited abnormally
              (unknown error: DevToolsActivePort file doesn't exist)
              (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
              (Driver info: chromedriver=2.46.628388 (4a34a70827ac54148e092aafb70504c4ea7ae926),platform=Linux 4.9.125-linuxkit x86_64)
```

https://sites.google.com/a/chromium.org/chromedriver/help/chrome-doesn-t-start によると、`--no-sandbox` のオプションをつけないといけないらしい。

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

これで無事に動く。

```
$ bundle exec rspec spec/features/sample_spec.rb

[GoogleCloudLoggingOnFork] Not initialized, project_id is blank.
Run options: exclude {:searchkick=>true}
....

Finished in 1 minute 23.42 seconds (files took 30.46 seconds to load)
4 examples, 0 failures
```


## 参考
- https://www.karelie.net/install-chrome-debian-9/
- https://sites.google.com/a/chromium.org/chromedriver/help/chrome-doesn-t-start
- https://qiita.com/t-koshi/items/97adab8628d201e85d10
- https://qiita.com/hoshitocat/items/c48bfdce867fc852e829

## さいごに
ツイッター(<a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>)やってます。フォローしてもらえるとうれしいです！