RSpecを実行するとWebdrivers::VersionErrorが発生する場合の対処方法

## 発生する問題

RSpecのテストを実行すると以下のようなエラーが発生する。

```
Webdrivers::VersionError:
  Unable to find latest point release version for 115.0.5790. You appear to be using a non-production version of Chrome. Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html
# ./spec/system/tasks_spec.rb:24:in `go_to_project'
# ./spec/system/tasks_spec.rb:14:in `block (2 levels) in <main>'
# ------------------
# --- Caused by: ---
# Webdrivers::NetworkError:
#   Net::HTTPClientException: 404 "Not Found" with https://chromedriver.storage.googleapis.com/LATEST_RELEASE_115.0.5790
#   ./spec/system/tasks_spec.rb:24:in `go_to_project'
```

## 原因

- chromedriverの管理方針がバージョン115から変わった
- webdrivers gemがこれに対応していない
- ローカルマシンにインストールされているChromeが115以上になるとこの問題が発生する

## 対処方法

最新版のselenium-webdriverにはドライバの管理機能が組み込まれており、これに切り替えることで問題が解決する。

### 手順

Gemfileを開いてwebdriversを削除する。
もしselenium-webdriverがGemfileに追加されていなかったら、`gem "selenium-webdriver"`の行も追加する。

```diff_ruby:Gemfile 
 group :test do
   gem "capybara"
   gem "selenium-webdriver" # もしなければこの行も追加
-  gem "webdrivers"
```

selenium-webdriverとcapybaraを最新版（selenium-webdriver4.11.0以上、capybara 3.39.2以上）にアップデートする。

```
bundle update selenium-webdriver capybara
```

これでテストを再度実行すれば正常に動くはず。

（RSpecではなく、minitestでテストを書いている場合も同様の手順で対処可能）

### 備考
capybaraをアップデートし忘れると以下のようなエラーが出るかもしれないので注意。

``` 
Failure/Error:
        def initialize(progname = 'Selenium', default_level: nil, ignored: nil, allowed: nil)
          default_level ||= $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
  
          @logger = create_logger(progname, level: default_level)
          @ignored = Array(ignored)
          @allowed = Array(allowed)
          @first_warning = false

ArgumentError:
  wrong number of arguments (given 2, expected 0..1)
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/logger.rb:51:in `initialize'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/capybara-3.38.0/lib/capybara/selenium/logger_suppressor.rb:8:in `initialize'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver.rb:99:in `new'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver.rb:99:in `logger'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/local_driver.rb:42:in `process_options'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/local_driver.rb:27:in `initialize_local_driver'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/chrome/driver.rb:34:in `initialize'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/driver.rb:47:in `new'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/driver.rb:47:in `for'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver.rb:88:in `for'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/capybara-3.38.0/lib/capybara/selenium/driver.rb:83:in `browser'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/capybara-3.38.0/lib/capybara/selenium/driver.rb:161:in `save_screenshot'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/capybara-3.38.0/lib/capybara/session.rb:747:in `block in save_screenshot'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/capybara-3.38.0/lib/capybara/session.rb:747:in `save_screenshot'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/actionpack-7.0.4/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:99:in `save_image'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/actionpack-7.0.4/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:36:in `take_screenshot'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/actionpack-7.0.4/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:45:in `take_failed_screenshot'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/actionpack-7.0.4/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb:8:in `before_teardown'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/rspec-rails-6.0.1/lib/rspec/rails/example/system_example_group.rb:110:in `call'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/rspec-rails-6.0.1/lib/rspec/rails/example/system_example_group.rb:110:in `block (2 levels) in <module:SystemExampleGroup>'
# /Users/jnito/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:457:in `instance_exec'
# 以下略
```

## 実行環境がRuby 2.7以下の場合
selenium-webdriver 4.11.0はRuby 3.0以上が必須であるため、Ruby 2.7以下の環境では上記の修正方法が使えない。その場合はwebdrivers 5.3.0以上にアップデートすると問題を回避できる。

```
# バージョン5.3.0以上にアップデート
bundle update webdrivers
```

vcr gemを使っている場合は`ignore_hosts`の設定も変更する。

```diff_ruby 
 VCR.configure do |config|
   config.cassette_library_dir = "#{::Rails.root}/spec/cassettes"
   config.hook_into :webmock
   config.ignore_localhost = true
-  config.ignore_hosts 'chromedriver.storage.googleapis.com'
+  config.ignore_hosts 'googlechromelabs.github.io', 'edgedl.me.gvt1.com'
   config.configure_rspec_metadata!
 end
```

ただし、Ruby 2.7はすでに公式サポートが終了しているため、そもそもの対応策としてRuby 3.0以上にアップデートした方がよい。

> このリリースをもって、Ruby 2.7 系列は EOL となります。即ち、Ruby 2.7.8 が Ruby 2.7 系列の最後のリリースとなる予定です。 
> https://www.ruby-lang.org/ja/news/2023/03/30/ruby-2-7-8-released/


## 何らかの理由でgemをアップデートできない場合

何らかの理由でgemをアップデートできない場合は`rails_helper.rb`（それ以外のファイルでもOK）に以下の設定を入れると、一時的に問題を回避できる。

```ruby 
Webdrivers::Chromedriver.required_version = '114.0.5735.90'
```

ただし、Chrome 115を114用のドライバで動かしているので、Chrome本体のバージョンが上がっていくと将来的に動かなくなるかもしれない。

## 動作確認環境

- rails 7.0.4
- rspec-rails 6.0.1
- selenium-webdriver 4.11.0
- capybara 3.39.2
- Ruby 3.2.0

なお、この問題はrails newした直後のRailsアプリケーションでも発生しうる問題である。この記事を執筆している時点（2023-8-5現在）ではまだリリースされていないが、修正PRはすでにmainブランチにマージされている。

https://github.com/rails/rails/pull/48847

## 参考文献

https://chromedriver.chromium.org/downloads/version-selection#h.4wiyvw42q63v

https://github.com/titusfortner/webdrivers/commit/c7a6f3b97031891692999a9b5cc69e55e8da0f17#diff-001626d2fcf09aa39f1919f799ae722aad44cea0275aae62f7497b7ecf3955d4R43

## Special thanks to
上記の情報を教えてくれた弊社ソニックガーデンの takachii 、どうもありがとう！

## PR
僕が翻訳しているRSpecの入門本「Everyday Rails - RSpecによるRailsテスト入門」でもこの対処方法を適用する形で内容をアップデートしました。
本書はLeanpubにて購入可能です。RSpecでRailsのテストを書くのが苦手な方はぜひ！

https://leanpub.com/everydayrailsrspec-jp/