Open
Description
Describe the feature you'd like:
Add a matcher for aria-pressed for checking button toggle states.
Suggested implementation:
A new matcher called toBePressed
Describe alternatives you've considered:
An alternative solution would be to check for the attribute aria-pressed="true"
or aria-pressed="mixed"
Teachability, Documentation, Adoption, Migration Strategy:
Docs entry:
toBePressed
toBePressed()
This allows you to check if a form element is currently pressed.
An element is pressed if it is a button having a aria-pressed="true"
or aria-pressed="mixed"
attribute.
Examples
<button data-testid="pressed-button" aria-pressed="true" />
<input data-testid="pressed-input" type="button" aria-pressed="true" />
<div data-testid="pressed-div" role="button" tabindex="0" aria-pressed="true" />
<button data-testid="pressed-button-mixed" aria-pressed="mixed" />
expect(getByTestId('pressed-button')).toBePressed()
expect(getByTestId('pressed-input')).toBePressed()
expect(getByTestId('pressed-div')).toBePressed()
expect(getByTestId('pressed-button-mixed')).toBePressed()
Activity
gnapse commentedon Mar 15, 2020
To be honest, this seems to be not too justified. The alternative way of checking it using
.toHaveAttribute
should be enough.I'm open to hear counter-arguments, in case I'm missing something. But if it's just a replacement for the corresponding
.toHaveAttribute
check, I'm not sure we'll provide it.jmvtrinidad commentedon Jan 3, 2021
adding a matcher that checks the accessibility of an element makes it easier for the dev to adopt and read test that has accessibility on the component.
gnapse commentedon Jan 4, 2021
@jmvtrinidad I hear you. However, I am torn between what you said and an explicit goal in our own guiding principles stated in the README:
We need to draw the line somewhere. Our matchers need to do something that substitutes a cumbersome way of checking.
toHaveAttribute
already does that, and seems a perfect fit for this job.If we go down this path suggested in this issue, then where does it end? If you go and check a list of existing aria attributes, then you'll see that we can soon end up having a myriad of custom matchers that are mere sugary syntax replacement for
toHaveAttribute
. Imagine havingtoHaveValueMin
,toBeExpanded
,toBeSelected
,toBeLabelledBy
,toBeDescribedBy
, etc.To illustrate the difference even further between what I'd consider good candidates over mere conveniences, consider a hypothetical matcher that I'd like and haven't made the time to propose or implement:
toHaveControlOf('elementId')
. This matcher would do two things:aria-controls
to see if it has the given'elementId'
If this matcher would perform only the step (1) above, then I would not consider it worthy of implementing. If you wanted to check that the attribute is there,
toHaveAttribute
is enough. Doing the second step actually adds some value and makes a check that would otherwise be cumbersome to do in userland.Hope this illustrates a bit the difference and what the reasoning is behind the objections to add a matcher such as
toBePressed
.jmvtrinidad commentedon Jan 7, 2021
@gnapse The example you have given totally makes sense, I will stop looking and use the
toHaveAttribute
.And maybe if someone still wants to do this maybe it can have its own library that focuses on checking the accessibility attributes with the sugary syntax.
gnapse commentedon Jan 7, 2021
Thanks. I'm going to go ahead and close this, which does not preclude the conversation to continue if someone still objects.
Conclusion: using
toHaveAttribute
is a good enough substitute for this purpose.Sawtaytoes commentedon May 26, 2022
I understand wanting to make those library simpler and wanting to draw the line, but I wanna counter your argument with a bit more detail.
None of those are necessary because
jest-dom
already has more meaningful alternatives:toBeExpanded
is handled bytoBeVisible
.toBeLabelledBy
andtoBeDescribedBy
are handled by Testing Library'squeryBy
. You can't even select the element if the values are wrong or missing (this can happen when they have ahidden
attribute I found out).toBeSelected
can also be handled bytoHaveValue
, but only for<select>
. More on this below.toHaveMinValue
should be handled by a UI test or some sort of validation checking.I also understand why we have some of the current helpers:
toBeVisible
is checking something different thanaria-hidden
such ashidden
anddisplay: none
.checked
andaria-checked
, so it makes sense to have atoBeChecked
. This is also separate fromtoHaveValue
as the value on a checkbox can be static while thechecked
property might not be.selected
andaria-selected
, but as I stated earlier, this doesn't warrant a separate expectation because you can usetoHaveValue
instead so long as it's a<select>
.Why I think
toBePressed
andtoBeSelected
make sense:toBePressed
is extremely similar totoBeChecked
except that it's only able to be defined with an ARIA attribute. IftoBeChecked
also covered the button's pressed state, I wouldn't be complaining. Although, checked has a different meaning because it includes "mixed" whereas "pressed" is onlytrue
-false
.toHaveValue
only covers<select>
, it doesn't make sense for things that are role: gridcell, option, row, or tab (a role of "tab" is very common in applications).<input>
or<select>
either. You'll find them as custom components with role button, option, tab, radio, checkbox, and switch. They're either gonna be checked, selected, or pressed.toBeChecked
when it covers only some of the types of pickers. It's very confusing to the point where I would incorrectly assumetoHaveAttribute
for the checked state.:active
state? I'm asking; not sure. It's a temporary UI state, but still "pressed".LucianHij commentedon Feb 13, 2024
I support adding the
toBePressed
functionality. If there is a need, I can code it and submit a PR @gnapse.gnapse commentedon Feb 13, 2024
Thanks for insisting. Indeed, I've changed my mind.
I now see value in this matcher due to the fact that it should also check if the element in question is a button. So the key here is: the custom matcher should respond with
false
if the element does not have thebutton
role, even if it has thearia-pressed
attribute:While these other examples should pass:
@LucianHij yes, it'd be much appreciated if you contribute this. Thanks!
LucianHij commentedon Feb 14, 2024
Yes, I will try to do it. Do you have any link to how can I setup the project and do the implementation? @gnapse
3 remaining items