Docker で RSpec の System Spec を実行するための設定メモ

# はじめに

docker 環境で rspec の system spec を実行させるための設定に手間取ったので、メモ代わりに書いておきます。
railsが動くdocker の image に chrome をインストールするのもちょっとなあと思ったので、 [selenium/standalone-chrome-debug](https://hub.docker.com/r/selenium/standalone-chrome-debug)
を使う方法です。

確認した Rails 環境は、5.2.2 です。

ちなみに Gemfile でバージョン指定はしていませんが、Gemfile.lock を確認したところ

```
capybara (3.14.0)
rspec-rails (3.8.2)
selenium-webdriver (3.141.0)
```

となってました。

# docker-compose.yml の編集

chrome が動作するように設定を追加します。
Rails は `web` で動作します。

```yaml:docker-compose.yml
version: '3'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - bundle:/usr/local/bundle
    tty: true
    environment:
      # この環境変数を追加
      - "SELENIUM_DRIVER_URL=http://selenium_chrome:4444/wd/hub"
  # 以下の4行を追加
  selenium_chrome:
    image: selenium/standalone-chrome-debug
    logging:
      driver: none
  db:
    image: postgres:10.7-alpine
    volumes:
      - pgsqldb:/var/lib/postgresql/data
    environment:
      - "POSTGRES_USER=xxxx"
      - "POSTGRES_PASSWORD=xxxx"
volumes:
  pgsqldb:
  bundle:
```

chrome を動作させるために、selenium_chrome を追加しています。
`logging` の設定を `driver: none` にしているのは、不要なログ出力を抑制するためです。

rspec は web で実行しますが、 chrome は、selenium_chrome で動作させるため、web 側からアクセスできるように
環境変数 `SELENIUM_DRIVER_URL` を web 側に追加しています。

# Gemfile を編集する

gem ファイルに rspec-rails を追加します。
chromedriver-helper を削除します。webdrivers gem は追加しません。

```ruby:Gemfile
group :development, :test do
  ...
  gem 'rspec-rails'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
end
```

# docker 環境で、bundle install を実行する

docker 環境で追加した gem をインストールします。

```shell
$ docker-compose up -d
$ docker-compose exec web bash

# 以下は web コンテナ内で実行します。
$ bundle install
```
# rspec の初期設定をする。

続けて、rspec の初期設定をします。

```shell
# 以下は web コンテナ内で実行します。
$ bin/rails g rspec:install
```

# system spec の設定をする。

system spec の設定をするために、 `spec/rails_helper.rb` を編集し、 `spec/support/capybara.rb` を追加します。

```ruby:spec/rails_helper.rb
# 以下の1行を有効にします。
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
```

```ruby:spec/support/capybara.rb
require 'capybara/rspec'

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium, using: :headless_chrome, options: {
      browser: :remote,
      url: ENV.fetch("SELENIUM_DRIVER_URL"),
      desired_capabilities: :chrome
    }
    Capybara.server_host = 'web'
    Capybara.app_host='http://web'
  end
end
```
`spec/support/capybara.rb` 内で `selenium_chrome` 側の headless chrome を利用するための設定をしています。
web コンテナ側から selenium_chrome コンテナ の chrome を使用するために、 `options` の中で、 `url` に `SELENIUM_DRIVER_URL` 環境変数の値を設定しています。
headless chrome からは、ローカル環境ではなく、 `web` コンテナ側の rails アプリを表示してテストする必要があるため、
`Capybara.server_host` と `Capybara.app_host` を設定しています。


# 参考情報

- [Docker for Rails Developers](https://pragprog.com/book/ridocker/docker-for-rails-developers)
- [A Quick Guide to Rails System Tests in RSpec](https://medium.com/table-xi/a-quick-guide-to-rails-system-tests-in-rspec-b6e9e8a8b5f6)