makandra/spreewald

Add Ruby 3 support for all `_selector_for` using steps

begerdom opened this issue · 1 comments

I'm currently performing a Ruby upgrade to version 3.1.4 and I came accross some steps that no longer work correctly with our custom selectors defined in the selector_for method in features/support/selectors.rb that is used for determining selectors in Spreewald's web steps.

For example, the step /^I should( not)? see (?:an|the) element for (.*?)$/ can no longer handle selector inputs like ['li', text: 'Foo'] because the selector is not split into the argument list and rest keyword arguments, but everything is passed to *args, resulting in a Unused arguments error for the filtered [{ :text => 'Foo' }]. Ruby 3.x needs explicit kwargs delegation which is why this doesn't work any longer.

Then /^I should( not)? see (?:an|the) element for (.*?)$/ do |negate, locator|
  expectation = negate ? :not_to : :to
  selector = _selector_for(locator)
  patiently do
    expect(page).send(expectation, have_selector(*selector))
  end
end.overridable(:priority => -5) # priority must be lower than the "within" step

The /^(.*) within (.*[^:])$/ step does it correctly:

When /^(.*) within (.*[^:])$/ do |nested_step, parent|
  selector = _selector_for(parent)
  if selector.is_a?(String) || selector.is_a?(Array) # could also be a Capybara::Node::Element
    patiently do
      args, kwargs = deconstruct_selector(selector)
      expect(page).to have_selector(*args, **kwargs)
    end
  end
  patiently do
    with_scope(parent) { step(nested_step) }
  end
end.overridable(:priority => -1)

I had to redefine the affected steps in my application to use the deconstruct_selector method and change this behavior. It would be good, if Spreewald was capable of doing this directly.

Fixed in version 4.5.1