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 new Capybara/ClickLinkOrButtonStyle cop #61

Merged
merged 1 commit into from
Sep 19, 2023
Merged

Add new Capybara/ClickLinkOrButtonStyle cop #61

merged 1 commit into from
Sep 19, 2023

Conversation

ydah
Copy link
Member

@ydah ydah commented Aug 7, 2023

Fix: #58


Before submitting the PR make sure the following are checked:

  • Feature branch is up-to-date with main (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Updated documentation.
  • Added an entry to the CHANGELOG.md if the new code introduces user-observable changes.
  • The build (bundle exec rake) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).

If you have created a new cop:

  • Added the new cop to config/default.yml.
  • The cop is configured as Enabled: pending in config/default.yml.
  • The cop documents examples of good and bad code.
  • The tests assert both that bad code is reported and that good code is not reported.
  • Set VersionAdded: "<<next>>" in default/config.yml.

@ydah ydah force-pushed the feature/58 branch 4 times, most recently from e355e90 to e60c0bb Compare August 8, 2023 02:40
@ydah ydah merged commit 7bef12a into main Sep 19, 2023
23 checks passed
@ydah ydah deleted the feature/58 branch September 19, 2023 14:03
@mvz
Copy link

mvz commented Sep 20, 2023

I'm not sure why it's supposed to be bad to use click_link_or_button when you don't know or care what interface element is used, but use a more specific method when you do know?

Put another way, the issue #58 says "There is no information which style is preferred.", but I don't think this is a matter of style at all!

@iainbeeston
Copy link

Can someone explain the rationale behind why using click_link and click_button is better than click_link_or_button and click_on? Maybe I'm missing something here, but I would have expected click_on and click_link_or_button to be better because your tests will be less tightly coupled to your HTML and it more closely reflects how a user would behave (there's no way a user can tell the difference between a button and a link styled to look like a button)

@ydah
Copy link
Member Author

ydah commented Sep 29, 2023

I thought strict was better when I first created this cop, but I reconsidered that you are right that click_on or click_link_or_button would indeed be less tied to the test and HTML and more faithful to how the user behaves. would you like to send a PR?

@iainbeeston
Copy link

@ydah To be honest my preference would be that this rule is disabled by default, but I appreciate that many other people would find it helpful

@ydah
Copy link
Member Author

ydah commented Oct 6, 2023

@iainbeeston Thank you for your feedback, we appreciate it. We will consider whether to enable or disable this cop by default at the time of the next major version update.

@samrjenkins
Copy link
Contributor

For the reasons mentioned above, I too have always preferred click_on.

@franzliedke
Copy link

@mvz @iainbeeston @ydah Let me open another round. 🤓

Here's why I will definitely stay with the strict mode (if my team agrees ^^): buttons and links are very different in terms of semantics. No matter whether they look the same to the user, they should not be used interchangably.

I really like that writing good Capybara tests often forces me to solve problems that also solve problems for e.g. sight-impaired users (e.g. somehow creating a unique accessible label to avoid using IDs or other technical details as selectors). With the loose default, this cop would work against that.

@mvz
Copy link

mvz commented Oct 16, 2023

For my use case 'strict' mode just means more work when the UI changes.

On the other hand, I don't want to be forced to change everywhere there is click_link to click_link_or_button.

For me, the one thing that would be useful is enforcing a choice of either click_on or click_link_or_button, rather than having a mix. This would mean still allowing click_link or click_button as well.

I see that a PR was merged changing to enforced_style: link_or_button, but I'm afraid this is equally useless to me.

@samrjenkins
Copy link
Contributor

samrjenkins commented Oct 16, 2023

With the loose default, this cop would work against that.

@franzliedke I'm not sure I follow your reasoning. How does link-button agnosticism encourage more accessible markup?

I too am a strong advocate for using Capybara tests as a prompt for improving HTML accessibility, but I normally find myself reaching for title and aria-label attributes rather then converting <a>s to <button>s or vice versa. I'm not sure I see how stricter Capybara click_ matchers helps in this regard.

I also agree that links and buttons should not be used interchangeably; they have different use cases. However, to the user, they provide indistinguishable UX. They are semantically different to an engineer but semantically indistinguishable to the end user.

@franzliedke
Copy link

For my use case 'strict' mode just means more work when the UI changes.

@mvz I often find this argument confusing. When behavior changes (and that is the case when changing from button to link, or vice versa), I would expect having to make changes in tests.

I am not proposing to break your use case (you can still configure Rubocop to your preference, strict is just a default), I am just throwing my 2c in to vote against making this the default. If Rubocop makes a choice on a default, then that default should push (or gently nudge) people to do "the right thing", which - to me - is always accessibility over some notion of developer comfort.

For me, the one thing that would be useful is enforcing a choice of either click_on or click_link_or_button, rather than having a mix. This would mean still allowing click_link or click_button as well.

I am confused. According to the examples in #76, the new default link_or_button allows both click_on and click_link_or_button (they are just aliases anyway). And they disallow click_link and click_button.

@franzliedke I'm not sure I follow your reasoning. How does link-button agnosticism encourage more accessible markup?

@samrjenkins I meant to express the opposite: Encouraging devs to ignore the difference between button and link has the potential to hurt accessibility. Thus, the new "loose" (non-strict) default has the potential to hurt accessibility.

However, to the user, they provide indistinguishable UX. They are semantically different to an engineer but semantically indistinguishable to the end user.

I disagree. Keyboard interaction, mouseover, ctrl+click are all different, that's also user-visible behavior.

@franzliedke
Copy link

@ydah I just realized that #76 calls the strict setting deprecated. 😱 I obviously prefer to keep strict as default, but at the very least I hope to have convinced you all to at least keep that mode available.

@samrjenkins
Copy link
Contributor

@franzliedke apologies. I mistyped. I should have asked: How does link-button agnosticism DIScourage more accessible markup?

@franzliedke
Copy link

Ah, thanks for clarifying. 🙈

Agnosticism enforces the notion that there's no difference between links and buttons; that is factually wrong and hurts accessibility.

@mvz
Copy link

mvz commented Oct 16, 2023

@franzliedke

When behavior changes (and that is the case when changing from button to link, or vice versa), I would expect having to make changes in tests.

I agree, but this should only be the case in tests where the change in behavior is relevant to thing being tested. If it is relevant, I would definitely use click_link or click_button. If it is not relevant, I would use click_on.

@franzliedke
Copy link

That's great. 👍🏼

Aren't linters supposed to provide the safe path forward, and point out potential problems. (There's always some human judgement necessary, especially when it comes to the amount and level of suggestions that Rubocop makes.) I argue for the default to be that safe path, and for anyone who wants to say "I know what I'm doing", there's rubocop:disable (or the config).

@mvz
Copy link

mvz commented Oct 16, 2023

Yes, I'm not against having to configure this cop to do what I want, and I can also see that requiring a specific action would be a good default.

What I am against is the idea that this is a matter of 'style'.

@ydah
Copy link
Member Author

ydah commented Nov 3, 2023

My apologies. I reminded myself that this cop is certainly not something that should be unified one way or the other, and that it is important to use it appropriately. How about we remove this cop for the next major version update?

@franzliedke
Copy link

I definitely like having it available, even if I don't prefer the default. 😉

@graaff
Copy link

graaff commented Jan 4, 2024

@franzliedke apologies. I mistyped. I should have asked: How does link-button agnosticism DIScourage more accessible markup?

I'm late to the party here since this only showed up in a release now, but the answer to this question is that assistive software for people with disabilities uses the distinction between links and buttons to better help explain what will happen when one is followed or pressed.

If your site is audited for WCAG 2.1 compliance using e.g. links for in-page actions will definitely get flagged and your site won't be compliant. So knowing when to use a button or a link is important even when visible there is not going to be a difference.

I really hope that this default can be reverted so that the default will be to be explicit about using links or buttons and thus create more accessible websites.

@ermolaev
Copy link

ermolaev commented Jan 9, 2024

now false positive if finding link by href

click_link(href: seo_link)

# Capybara/ClickLinkOrButtonStyle: Use click_link_or_button or click_on instead of click_link.
Failure/Error: click_on(href: seo_link)
ArgumentError:
     Invalid option(s) :href, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :disabled

@jgarber623
Copy link

Similar to @ermolaev's comment above, I'm seeing the same error from Capybara when following this cop's advice:

# Test passes
# Capybara/ClickLinkOrButtonStyle complains
click_button title: "Delete"
# Test fails
# Capybara/ClickLinkOrButtonStyle happy
click_on title: "Delete"

The exception (same as @ermolaev's):

     Failure/Error: click_on title: 'Delete'
     
     ArgumentError:
       Invalid option(s) :title, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :disabled

From that, it's not entirely clear to me if this is an issue with this cop's guidance or in Capybara itself. The various methods appear equivalent and I'm having trouble tracing the source of the ArgumentError in the Capybara::Node::Actions class:

# Lines 25–28
def click_link_or_button(locator = nil, **options)
  find(:link_or_button, locator, **options).click
end
alias_method :click_on, :click_link_or_button

# Lines 41–43
def click_link(locator = nil, **options)
  find(:link, locator, **options).click
end

# Lines 57–59
def click_button(locator = nil, **options)
  find(:button, locator, **options).click
end

@ydah
Copy link
Member Author

ydah commented Jan 15, 2024

I think proceeding in the direction of deleting Capybara/ClickLinkOrButtonStyle while creating a transition destination as follows. If you have any opinions, I would like to hear them.

jgarber623 pushed a commit to CargoSense/rubocop-cargosense that referenced this pull request May 6, 2024
This rule's default enforce style, `link_or_button` [1], introduced a
number of problems [2]. Specifically, I noticed issues switching to
`click_on` from `click_button` [3]. The hack solution is to ignore or
disable the rule in some places but not in others. Not great.

As a result, the rule is slated for removal [4] and replacement [5] by
a new rule. In the interim, configuring this rule to enforce a strict
use of `click_button` and `click_link` is preferential (and, honestly,
more communicative).

In this author's opinion, user interface specs should be explicit about
the markup under test.

[1] https://docs.rubocop.org/rubocop-capybara/cops_capybara.html#capybaraclicklinkorbuttonstyle
[2] rubocop/rubocop-capybara#61
[3] rubocop/rubocop-capybara#61 (comment)
[4] rubocop/rubocop-capybara#81
[5] rubocop/rubocop-capybara#99
jgarber623 pushed a commit to CargoSense/rubocop-cargosense that referenced this pull request May 6, 2024
## Description

This rule's default enforce style, `link_or_button` [1], introduced a
number of problems [2]. Specifically, I noticed issues switching to
`click_on` from `click_button` [3]. The hack solution is to ignore or
disable the rule in some places but not in others. Not great.

As a result, the rule is slated for removal [4] and replacement [5] by a
new rule. In the interim, configuring this rule to enforce a strict use
of `click_button` and `click_link` is preferential (and, honestly, more
communicative).

In this author's opinion, user interface specs should be explicit about
the markup under test.

[1]
https://docs.rubocop.org/rubocop-capybara/cops_capybara.html#capybaraclicklinkorbuttonstyle
[2] rubocop/rubocop-capybara#61
[3] rubocop/rubocop-capybara#61 (comment)
[4] rubocop/rubocop-capybara#81
[5] rubocop/rubocop-capybara#99

## Commits

- Configure `Capybara/ClickLinkOrButtonStyle`
- Bump version to v1.1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

click_on vs click_link and click_button
8 participants