【🔴RSpecエラー】「Docker」+「Rails6」環境で、RSpecの結合テスト(SYSTEM）時にブラウザが起動しないについて

# ✅当方の環境
- 開発環境 : Docker
- ruby 2.7.5
- rails 6.1.5

# ✅Gemの内容（必要なもののみ）
```言語:Gemfile
＜中略＞

group :development, :test do
  gem 'pry-rails'
  gem "rspec-rails", "~> 4.0.1"
  gem 'factory_bot_rails', '~> 5.0'
end

＜中略＞

group :test do
  gem 'capybara', '~> 3.28'
  gem 'selenium-webdriver', '~> 3.142'
  # gem 'webdrivers', '~> 4.1'　
　#「webdrivers」は、Docker上では使用しません。（以前は、chromedriver-helperという名称）
end

＜中略＞
```
# ✅ よくあるエラー
- 「Docker」環境でSYSTEMテストを実行する際に発生するエラーを列挙しています。
```
Selenium::WebDriver::Error::WebDriverError:
Failure/Error: raise Error::WebDriverError, self.class.missing_text unless path
     1.2) Failure/Error: raise Error::WebDriverError, self.class.missing_text unless path

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

     1.1) Failure/Error: visit root_path

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

     1.2) Failure/Error: raise Capybara::DriverNotFoundError, "no driver called #{mode.inspect} was found, available drivers: #{other_drivers.join(', ')}"

          Capybara::DriverNotFoundError:
            no driver called :remote_chrome was found, available drivers: :rack_test, :selenium, :selenium_headless, :selenium_chrome, :selenium_chrome_headless
```

# ✅ エラー発生原因

:::note alert
- <font color="Red">Dockerコンテナで使用する Rubyイメージには、システムスペックを実行する際に必要なブラウザ（Google Crome）がインストールされておらず、システムスペックを実行できません。</font>
- ローカル上のブラウザ（Google Crome）が起動しないのは、コンテナ環境とローカル環境は、あくまで別空間上で発生しているテストだから
- Rubyイメージに、ブラウザをインストールする方法もありますが、システムスペックは開発環境で実行し、本番環境では実行しないため、イメージ容量が増えてしまう点など、不要なブラウザのインストールは避けたい。
- <font color="Red">そこで、ブラウザを別のコンテナとして起動することで、このエラーを解決しようと思います。</font>
:::
# ✅解決法
## 🔴「docker-compose.yml」修正
- 修正する箇所は抜粋しています。
```diff_ruby:docker-compose.yml
  web_or_app:
    environment:
      RAILS_ENV: development
      TZ: Asia/Tokyo
+     SELENIUM_DRIVER_URL: http://selenium_chrome:4444/wd/hub
    depends_on:
      - db
+     - chrome
+chrome:
+   image: selenium/standalone-chrome-debug
+   ports:
+     - 4444:4444
```

## 🔴「Gemfile」修正
- 修正する箇所は抜粋しています。
```diff_ruby:Gemfile
group :test do
  gem 'capybara', '~> 3.28'
  gem 'selenium-webdriver', '~> 3.142'
-  # gem 'webdrivers', '~> 4.1'　
-  #「webdrivers」は、Docker上では使用しません。（以前は、chromedriver-helperという名称）
end
```

## 🔴「rails_helper.rb」修正
```ruby:spec/rails_helper.rb
# 初期設定ではコメントアウトされているので、コメントを外す
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
```
## 🔴capybaraの設定ファイル作成
- すでに作成してある方は、スキップ
```
mkdir spec/support
touch spec/support/capybara.rb
```

## 🔴「capybara.rb」の修正
```ruby:spec/support/capybara.rb
RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end

  config.before(:each, type: :system, js: true) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
end

# Chrome
Capybara.register_driver :remote_chrome do |app|
  url = 'http://chrome:4444/wd/hub'
  caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
    'goog:chromeOptions' => {
      'args' => [
        'no-sandbox',
        'headless',
        'disable-gpu',
        'window-size=1680,1050'
      ]
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end
```
:::note 
Docker上で、Chomeブラウザを起動させる方法は以上です。
「bundle exec rspec」コマンドで、SYSTEMスペックが正常に動作するか確認してみてください
:::

# ✅Rspecメモ
## 🔴Deviceのユーザ認証をテストする場合

:::note alert
controllerのテストを実行していく中で、sign_inなどのdeviseのヘルパーを使う機会が出てきます。
なぜRSpecのコードを書いていくときに、deviseのヘルパーが必要かというと、アクセス権限でログインしてないユーザーを許可していない場合があるからです。
ユーザーの編集ページはログインしてないときは、アクセスできないなど、「spec/rails_helper.rbにdevise」のヘルパーを使えるようにコードを追加します。
:::

```ruby:spec/rails_helper.rb
<中略>

RSpec.configure do |config|

#追記
config.include Devise::Test::IntegrationHelpers, type: :system

end

<中略>
```

## 🔴SYSTEMスペックテストまでの流れ
- テストファイル作成
```
mkdir spec/system
touch spec/system/tops_spec.rb
```
- テストファイル修正
```ruby:spec/system/tops_spec.rb
require 'rails_helper'

RSpec.describe 'Top', type: :system do
  it 'shows greeting' do
    # root_pathへアクセス
    visit root_path
    # ページ内に'Hello World!'が含まれているかを検証
    expect(page).to have_content 'このページはトプページです'
  end
end
```
- Rspecテスト実行
```
bundle exec rspec
```


## 🔴便利な設定
- 出力結果で「成功」時も出力する設定
```.rspec
--require spec_helper
--format documentation #追記
```

- specファイルの自動生成機能OFF
```ruby:config/application.rb
equire_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)

module Myapp
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    ### 追記 ######################################
    config.generators do |g|
      g.test_framework :rspec,
                       view_specs: false,
                       helper_specs: false,
                       controller_specs: false,
                       routing_specs: false,
                       request_specs: false
    end
    ##############################################
  end
end
```

- Rails初期設定のtestフォルダを削除
```
rm -rf test
```
- スクリーンショット保存機能
```
tmp/screenshots
```

# ✅エラー参考資料
- [【Rails6】Docker環境でRSpecのシステムスペックを実行する](https://qiita.com/masarashi/items/84761a4e8de494f4d073)
- [【Rails6】Docker環境でRSpecのシステムスペックを実行する](https://jpdebug.com/p/1237349)
- [Docker で RSpec の System Spec を実行するための設定メモ]( [【Rails6】Docker環境でRSpecのシステムスペックを実行する](https://jpdebug.com/p/1237349))