Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attributes as a name to the v4 blacklist for DSL definitions #81

Closed
kouno opened this issue Oct 3, 2020 · 9 comments
Closed

Add attributes as a name to the v4 blacklist for DSL definitions #81

kouno opened this issue Oct 3, 2020 · 9 comments
Labels
Bug Fix Something isn't working Feature Request

Comments

@kouno
Copy link

kouno commented Oct 3, 2020

Environment

  • Ubuntu
  • SitePrism v3.6
  • Using RSpec and Cucumber

Issue

When defining a new class inheriting from SitePrism::Page which defines a :attributes section, the default helper have_attributes from RSpec gets overwritten.

Steps to reproduce

Here is a RSpec test to showcase the issue:

RSpec.describe "have_attributes" do
  let(:struct) { Struct.new(:a, :b, :c) }

  it "checks that the object has the listed attributes" do
    expect(struct.new(1, 2, 3)).to have_attributes(a: 1, b: 2, c: 3)
  end
end

RSpec.describe "a Page implementing an attributes section" do
  let(:struct) { Struct.new(:a, :b, :c) }

  context "when it is defined" do
    let!(:page) do
      Class.new(SitePrism::Page) do
        section :attributes, '.foo' do
          element :unused_element, '.btn'
        end
      end
    end

    it "breaks `have_attributes`" do
      expect(struct.new(1, 2, 3)).to have_attributes(a: 1, b: 2, c: 3)
    end
  end

  context "after it has been defined once" do
    it "breaks `have_attributes`" do
      expect(struct.new(1, 2, 3)).to have_attributes(a: 1, b: 2, c: 3)
    end
  end
end

The matcher for have_attributes should be: https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/built-in-matchers/have-attributes-matcher.

From what I saw in the docs and in the code, SitePrism::RSpecMatchers seems to define new have_* matchers. Is this still necessary since RSpec already have the have_xxx matcher?

@luke-hill
Copy link
Collaborator

This is an intractable problem and solved by your load order being incorrect.

the RSpec defined matchers allow us to use our metaprogrammed matchers inside RSpecs metaprogrammed assertion logic.

I would look at your stack and see if you can isolate your logic. Or failing that control your load order more succinctly. You are encountering the same issue as anyone else would when overwriting any protected method name

@kouno
Copy link
Author

kouno commented Oct 5, 2020

@luke-hill First, thanks for coming back on this and taking the time to look into this! :)

However, I don't think this is a loading issue.

SitePrism can override the default RSpec matcher for have_attributes which breaks tests that have nothing to do with SitePrism. Once the class is loaded, and the matcher setup, it is not possible to go back to the previous behaviour.

I'm not sure why SitePrism defines its own matchers at all since I would expect the have_ default matchers to just work as expected in the current implementation. SitePrism defines has_ methods on the page object and should already plug nicely with RSpec.

Maybe I'm just missing a piece here on why these are necessary... Do you know why that would be?

@luke-hill luke-hill added the Needs decision This doesn't seem right label Oct 5, 2020
@luke-hill luke-hill reopened this Oct 5, 2020
@luke-hill
Copy link
Collaborator

I'm not going to lie, that area has changed a lot recently. So if you're having problems, I need you to perhaps dig a bit deeper into it as I don't have time at the moment.

If memory serves me right, this was to allow us to do complex matching. and also to add a negative matcher (Which is needed to be custom, as it deviates from RSpecs default ! behaviour).

It seems as though what you're proposing is to remove the positive matcher. Now if this has no adverse effects, and you can reconcile the unit tests / feature tests (I'm aware we have 2 failing ones on old firefox). Then I'm not against some changes being made.

I hope that helps. I'll leave this open for some discussion if needed.

@kouno
Copy link
Author

kouno commented Oct 5, 2020

If memory serves me right, this was to allow us to do complex matching. and also to add a negative matcher (Which is needed to be custom, as it deviates from RSpecs default ! behaviour).

Are you speaking of the have_no_* matchers? I know that Capybara has the right behaviour when using negations but I probably would need to crosscheck how that is implemented and if it would work as expected with SitePrism.

Reference:
https://github.com/teamcapybara/capybara/blame/f43b6499ecb2721dd97b63a7fe31ff2518b89b4c/README.md#L805-L811

@luke-hill
Copy link
Collaborator

Any thoughts on this @kouno

At the moment I'm spending a lot of time tackling some internal tech debt around capybara restrictions. Once that is finished I need to cut a stable v1 of the all_there gem. So that's gonna keep me tied up for a while.

@kouno
Copy link
Author

kouno commented Oct 14, 2020

@luke-hill I don't think there is much urgency to fix this bug yet so feel free to leave on the side for now.

I'll make a PR when I'm ready and have gotten cucumber tests running locally.

@luke-hill
Copy link
Collaborator

So re-reading this now we have 2 avenues.

  1. Add attributes to the blacklist (We are creating one), that will be released in v4. I personally think it's a very weird name for a section.
  2. Somehow Scope the RSpec matchers. I don't believe this is possible, so Refactor/general tidy in prep for 3.3 #1 looks like the only solution. For v3 we can add a deprecator in. I would probably make it passive (As I plan on cutting v4 soon). So it would be soft-deprecated in v3, and hard deprecated in v4.

I do plan on committing a bit more time to work on this where time allows. I'm also pushing a bit on the funding route now, as I've seen how it can help from other avenues.

@luke-hill luke-hill changed the title RSpec matcher have_attributes gets ovewritten have_attributes matcher can be overwritten by section matcher section, :attributes, '.locator' Feb 9, 2021
@luke-hill
Copy link
Collaborator

@kouno Having spent some time off recently, I've come back to this. I think the best thing is add this to the blacklist. Which whilst masking the issue I think is probably the best one. As it'll also allow us to be stricter with other names we don't want in the blacklist (Such as special characters e.t.c.)

@luke-hill luke-hill added Bug Fix Something isn't working Feature Request and removed Awaiting Response Needs decision This doesn't seem right labels Mar 18, 2021
@luke-hill luke-hill changed the title have_attributes matcher can be overwritten by section matcher section, :attributes, '.locator' Add attributes as a name to the v4 blacklist for DSL definitions Mar 18, 2021
@luke-hill
Copy link
Collaborator

Released in v4.0.beta - Initially disabled as a configurable option

cc/ @kouno

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Fix Something isn't working Feature Request
Projects
None yet
Development

No branches or pull requests

2 participants