teamcapybara / capybara

Acceptance test framework for web applications

Home Page:http://teamcapybara.github.io/capybara/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.