Node::Matchers break on Ruby 3 when using keyword arguments
jason-o-matic opened this issue · comments
Meta
Capybara Version:
3.39.1
Driver Information (and browser if relevant): n/a
Expected Behavior
expect(page).to have_css('div#foo', visible: :all)
(also have_select and have_field) shouldn't raise exceptions when there are keyword arguments in Ruby 3.
Actual Behavior
Raises exceptions like this:
Minitest::UnexpectedError: ArgumentError: wrong number of arguments (given 2, expected 1)
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/capybara-3.39.1/lib/capybara/node/matchers.rb:309:in `has_css?'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/capybara-3.39.1/lib/capybara/session.rb:773:in `has_css?'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/matchers/built_in/has.rb:68:in `predicate_matches?'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/matchers/built_in/has.rb:16:in `matches?'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/expectations/handler.rb:50:in `block in handle_matcher'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/expectations/handler.rb:27:in `with_matcher'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/expectations/handler.rb:48:in `handle_matcher'
~/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/rspec-expectations-3.9.2/lib/rspec/expectations/expectation_target.rb:65:in `to'
Steps to reproduce
Run code as noted above with keyword arguments.
I posted rspec/rspec-expectations#1329 (comment) originally, but was told it was a capybara issue, so I thought I'd post over here in the hopes of resolution.
It looks like https://github.com/rspec/rspec-expectations/blob/b79a5c9/lib/rspec/matchers/built_in/has.rb#L67 calls https://github.com/teamcapybara/capybara/blob/2fd00e5/lib/capybara/node/matchers.rb#L310 and rspec is sending positional args and capybara is expecting keyword args. https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html seems to indicate that code intended to be compatible with old and new rubies should use *args
and ruby2_keywords
. This seems like it applies to the capybara pass through methods.
Looking through https://github.com/teamcapybara/capybara/blob/2fd00e5/lib/capybara/node/matchers.rb it appears many of the matchers pass through keyword arguments instead of using ruby2_keywords
, so this issue might apply to more methods than the ones above that I ran into issues with.
These methods all pass their tests, and have been used by lots of people for ages (ruby 3.0 has been out a long time) -- Why would this have only recently become an issue?
OH -- you don't have capybaras matchers installed correctly --- If you did it wouldn't be calling RSpecs built-in has
matcher -- please make sure you've required capybara/rspec as stated in the README
Thanks for the quick reply!
Unfortunately adding capybara/rspec
isn't working. It occurs to me that an important component of this is probably that I'm using minitest with rspec-expectations. Unfortunately nothing minitest related showed up in the stack trace, which would have made it more obvious what components were involved.
Any ideas on how to make this work with minitest and rspec-expectations?
Sorry but I don't. I don't really understand why anyone would use rspec-expectations with minitest, and even if it did work you likely wouldn't get Capybaras retrying behavior, leading to highly flaky tests.