Dockerを導入後に、(Rspec)テストコードが完全に使い物にならなくなった件について②

#はじめに
ようやくDocker環境下でもちゃんとテストが動くようになりましたので、こちらに記録としてまとめておきます。

前回記事：https://qiita.com/tochisuke221/items/d8cef06e3248209fee17

#結論


動かなかった理由としては、やはり[こちらの記事](https://qiita.com/tochisuke221/items/d8cef06e3248209fee17)でも触れたJSがうまく作動してないことに起因しておりました。

とりあえず、一個づつコードを見ていきながら確認していければと思います。

#実際に動いた時のコード

まずはDockerfileについて、この辺はQiita上に落ちている記事を参考に作成しました。
特に今回の件では関係はなかったので、変更はなしです。

```:Dockerfile
FROM ruby:2.6.5
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn


WORKDIR /soccer_app
COPY Gemfile /soccer_app/Gemfile
COPY Gemfile.lock /soccer_app/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /soccer_app

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile
```

つぎにdocker-compose.ymlを見ていきます。
ちなみに、docker-compose.ymlについての書き方は、[こちらの記事](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)が分かりやすかったです！

このファイルも特に変更はなしです。
ちなみに、webpackerってなに？という方は、[こちらの記事](https://www.sejuku.net/blog/68146)が参考になるかと思います。
Webpackとは、CSS、JavaScript、画像などを１つのファイルとしてまとめるためのモジュールバンドラーで、node.jsのモジュールの1つです。

<イメージ>
![スクリーンショット 2021-05-15 13.58.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128031/4425c023-ed4b-a882-8aeb-e8709d6d382f.png)
（引用：https://www.sejuku.net/blog/68146）


<br>

また今回、SystemSpecに対応するため、chromeコンテナの作成をしています。
このへんについては、[こちらの記事](https://qiita.com/ddpmntcpbr/items/752b6a43727e7cccdd56)に詳しく記載してあります。

```docker-compose.yml
version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: "password"
    ports:
      - "4306:3306"

  web: &app_base
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/soccer_app
    ports:
      - "3000:3000"
    depends_on:
      - db
      - chrome 
    stdin_open: true
    tty: true
    environment:
      BASIC_AUTH_USER: ${BASIC_AUTH_USER:-default}
      BASIC_AUTH_PASSWORD: ${BASIC_AUTH_PASSWORD-default}
      SELENIUM_DRIVER_URL: http://chrome:4444/wd/hub

  webpacker:
    <<: *app_base
    command: bash -c "bundle exec bin/webpack-dev-server"
    depends_on:
      - web
    ports:
      - '3035:3035'
    tty: false
    stdin_open: false
    environment:
      BUNDLE_APP_CONFIG: ./.bundle
      NODE_ENV: development
      RAILS_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0

  chrome:    #Chromeでのテスト実行用コンテナ
    image: selenium/standalone-chrome    #Chromeがインストールされたイメージ
    ports:
      - '4444:4444'
```


このへんも特に変更はありません。


```:Gemfile
group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers', require: !ENV['SELENIUM_DRIVER_URL']
end
```
ちなみに、require: !ENV['SELENIUM_DRIVER_URL']の部分がないと、下のようにブラウザがないよ〜と怒られてしまいます。

```:terminal
Webdrivers::BrowserNotFound: Failed to find Chrome binary.
```

このへんの変更も特になかったです

```capybara.rb
Capybara.register_driver :remote_chrome do |app|
    url = ENV['SELENIUM_DRIVER_URL']
    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
  
  RSpec.configure do |config|
    config.before(:each, type: :system) do
      driven_by :rack_test
    end
  
    config.before(:each, type: :system, js: true) do
      #driven_by :selenium_chrome_headless
      Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
      Capybara.app_host = "http://#{Capybara.server_host}"
      driven_by :remote_chrome
    end
  end
  Capybara.default_driver = :rack_test
  Capybara.javascript_driver = :selenium_chrome_headless
```

よく見てみると、この辺までは、全く問題ありませんでした。


#結論はよ！！！！！！

焦らしてごめんなさい、クソ記事あるあるですね笑
こっから変更点を述べます。

まずエラー原因は以下の3
つでした。

- config/webpack/environment.jsのコードがごっそり消えてしまっていたこと

- js:trueの付け加えのほかに、テストコードの記述を変更する必要があったこと

- spec実施時に、Deviseのhelperを呼び出せるように設定してなかったこと

とりあえず、ごっそり消えていた部分は元に戻すのみでした、一応下記に記述します

```config/webpack/environment.js
const { environment } = require('@rails/webpacker')


const webpack = require('webpack')
environment.plugins.append(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    // $: 'jquery',
    // jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)

module.exports = environment

```

あと、js:trueの付け加えのほかに、テストコードの記述を変更する必要があったことというのは具体的には、モーダル画面で”はいorいいえ”を選択する際には以下のように記述する必要がありました。いや〜〜ここは自力で気づくべきでした。

```変更前_spec.rb
   click_on('退会する')
   expect(page.accept_confirm).to eq '本当に退会しますか?退会後は全てのデータが削除されます。'
  
```

```変更後_spec.rb
page.accept_confirm("本当に退会しますか?退会後は全てのデータが削除されます。") do
  click_on('退会する')
end
```

最後に、spec実施時に、Deviseのhelperを呼び出せるように設定してなかったことについては以下のように設定することで対応できました。


```rails_helper.rb
require 'devise' #追加！！！！！！！！！

# 省略

RSpec.configure do |config|
  config.include Devise::Test::IntegrationHelpers, type: :request　#追加！！！！
  config.include SignInSupport
  config.include SignOutSupport
```
追加した部分によって、specからrails_helperを通してDeviseのsigin_in等のヘルパー機能を呼び出せるようになります。ちなみに、私は自作でsign_inを作ってしまっていたので、後から名前を変更する必要がありました、、
上記については、[こちらの記事](https://qiita.com/Hyuga-Tsukui/items/57fa77df2b2942414307)を見つけましたので共有いたします。

なお、今回、エラーが出た原因がもしかしすると古いdockerイメージが残っていたとかそういう可能性がなくはなかったのでターミナルでdocker system prune を叩いてから上記の変更を行なっています。適当にコピペしても他の点でエラーが出ることがあるかもしれませんので、お気をつけください。

以上が今回の変更点です。

#[重要]振り返り

今回のエラーで良かったところ、悪かったところを考えてみます。

###良かった点
- 自分なりに仮説を持ってエラーと向き合えたことで、結果としてゴールの近い部分までは近づけていた
- 1週間かなり闇に潜っていたが諦めず、手段を選ばず、解決までもっていけた粘り強さ
- **エラーと友達になれた,もうどんなエラーも怖くない**

###悪かった点
- コードの1つ1つ細かいところまで理解せず、こういうものなんだなと、勝手に理解し本来調べるべきところを無意識的に無視していたこと

-　あと一歩だったのに、人に頼ってしまったこと（悪くはないが、自力でやりたかった、、、汗）
-　深追いしすぎた？？時間かけすぎ（1週間）

#おわりに

今回エラーをとるまでにご協力してくださった方、本当にありがとうございました。
今回のエラーで、自分の未熟さや、逆に「あれ、結構自分いいセンスしているな？」と思えたり学びあるエラー対応でした！
引き続き頑張っていきます！