【capybara + selenium-webdriver v4.9.1】ArgumentError: wrong number of arguments (given 2, expected 0..1)のエラーの対処法

日本語で解決策の記事が見当たらなかったので。

プロジェクトに結合テストを導入しようとCapybaraとselenium-webdriver環境でテストを書いていたが、
2023年5月9日辺りから急にCapybaraのコードで以下のようなエラーが出るようになりました。

```
Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit "path"
          
          ArgumentError:
            wrong number of arguments (given 2, expected 0..1)
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/logger.rb:51:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/selenium/logger_suppressor.rb:8:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:99:in `new'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:99:in `logger'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/bridge.rb:619:in `execute'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/bridge.rb:53:in `create_session'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:317:in `block in create_bridge'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:316:in `create_bridge'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:74:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/driver.rb:37:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:57:in `new'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:57:in `for'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:88:in `for'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/selenium/driver.rb:83:in `browser'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:48:in `block in register_selenium'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:47:in `register_selenium'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:35:in `block in register'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/session.rb:105:in `driver'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/session.rb:91:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:421:in `new'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:421:in `block in session_pool'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:317:in `current_session'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/dsl.rb:46:in `page'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/dsl.rb:52:in `visit'

     1.2) 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)
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/logger.rb:51:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/selenium/logger_suppressor.rb:8:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:99:in `new'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:99:in `logger'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/bridge.rb:619:in `execute'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/bridge.rb:53:in `create_session'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:317:in `block in create_bridge'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:316:in `create_bridge'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:74:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/remote/driver.rb:37:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:57:in `new'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver/common/driver.rb:57:in `for'
          # /opt/bundle/ruby/3.0.0/gems/selenium-webdriver-4.9.1/lib/selenium/webdriver.rb:88:in `for'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/selenium/driver.rb:83:in `browser'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:48:in `block in register_selenium'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:47:in `register_selenium'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/driver.rb:35:in `block in register'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/session.rb:105:in `driver'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/session.rb:91:in `initialize'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:421:in `new'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:421:in `block in session_pool'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara.rb:317:in `current_session'
          # /opt/bundle/ruby/3.0.0/gems/capybara-3.39.0/lib/capybara/dsl.rb:46:in `page'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:95:in `save_image'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:33:in `take_screenshot'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb:45:in `take_failed_screenshot'
          # /opt/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb:16:in `before_teardown'
```

私の場合Docker環境でrailsアプリとブラウザ（chrome）のコンテナをたてていて、環境はこんな感じです
```:バージョン
Ruby 3.02
rails 6.1.6
rspec-rails 6.0.2
capybara 3.39.0
selenium-webdriver 4.9.1
```
```:Gemfile
group :development, :test do
  gem 'rspec-rails', '~> 6.0.0'
  gem 'factory_bot_rails'
end

group :test do
  gem 'spring-commands-rspec'
  gem 'capybara'
  gem 'selenium-webdriver'
end
```

# 結論：selenium-webdriverのバージョン4.9.1のバグが原因
2023年4月8or9日あたりにリリースされたselenium-webdriver v4.9.1が原因。
なので①selenium-webdriverのバージョンを下げる ②Selenium::WebDriver.loggerの記述を追加する ③修正が反映されるまで待つ　のどれかをすると解決です。
バージョン指定していなかったのがいけませんでしたね。。。

# selenium-webdriverのバージョンを下げる
```:Gemfile
group :development, :test do
  gem 'rspec-rails', '~> 6.0.0'
  gem 'factory_bot_rails'
end

group :test do
  gem 'spring-commands-rspec'
  gem 'capybara'
  # こちら↓をバージョン指定
  gem 'selenium-webdriver', '4.9.0'
end
```
# Selenium::WebDriver.loggerの記述を追加する
回避策ではありますが、こんな方法もあるそうです。
```ruby:a_spec.rb
it "a" do
  Selenium::WebDriver.logger
  visit "path"
  ...
end
```

# 何が原因なのか
Capybaraのissueに書かれてますが、ruby3.2で導入された*という委譲記法を使うと、通常の引数とキーワード引数が完全に分離されるんですが、それを意図していないコードだったのが原因のようです。だから「予想よりも多く引数が渡されてるよ！」というエラーが出てるんですね。

これについては下記の記事を読んだ方が早いでしょう。
[Capybaraのissue](https://github.com/teamcapybara/capybara/issues/2666)
[委譲記法について](https://zenn.dev/igaiga/books/rails-practice-note/viewer/ruby_argument_literals)

lib/capybara/selenium/logger_suppressor.rbに書かれているinitializeメソッドの引数を見ると*が使われているのがわかります。
```
def initialize(*)
  @suppress_for_capybara = false
  super
end
```

# 参考記事
https://github.com/teamcapybara/capybara/pull/2667
https://github.com/teamcapybara/capybara/issues/2666
https://zenn.dev/igaiga/books/rails-practice-note/viewer/ruby_argument_literals