Description
Describe the feature you'd like:
I'd like an assertion for the aria-errormessage
attribute. It accepts a list of id strings formatted identically to the format aria-describedby
accepts.
https://www.w3.org/TR/wai-aria-1.1/#aria-errormessage
Browser support was poor a year ago but I can't seem to find any up-to-date information on its support level. There is some chance that this is unsupported enough to be not worth implementing, but on a long enough timeline I think it'll fit well here.
Usage
<input
type="text"
id="mortgage-amount"
name="MORTGAGE_AMOUNT"
aria-label="Mortgage Amount"
aria-describedby="mortgage-amount-description"
aria-invalid="true"
aria-errormessage="mortgage-amount-error"
/>
<p id="mortgage-amount-error"> Must be a positive number </p>
expect().toHaveErrorMessage('Must be a positive number')
Suggested implementation:
The implementation would be nearly a clone of toHaveDescription
except the elements it reads come from the aria-errormessage
attribute instead of aria-describedby
It could also assert that aria-invalid
is true
I'm willing to make a PR for inclusion but I'm new to open source so I wanted to get feedback up front
Describe alternatives you've considered:
Teachability, Documentation, Adoption, Migration Strategy:
toHaveErrorMessage
toHaveErrorMessage(text: string | RegExp)
This allows you to check whether the given element has an error message or not.
An element gets its error message via the
aria-errormessage
attribute.
Set this to the id
of one or more other elements. These elements may be nested
inside, be outside, or a sibling of the passed in element.
Whitespace is normalized. Using multiple ids will
join the referenced elements’ text content separated by a space.
When a string
argument is passed through, it will perform a whole
case-sensitive match to the error message text.
To perform a case-insensitive match, you can use a RegExp
with the /i
modifier.
To perform a partial match, you can pass a RegExp
or use
expect.stringContaining("partial string")
.
Examples
<!-- with aria-errormessage and aria-invalid -->
<input type="text" aria-label="Username" aria-errormessage="username-error" aria-invalid="true"/>
<div id="username-error">
Username must not contain spaces
</div>
<!-- with just aria-errormessage -->
<input type="text" aria-label="Email" aria-errormessage="email-error" />
<div id="email-error">
Email must contain an '@' sign
</div>
<!-- with just aria-invalid -->
<input type="password" aria-label="Password" aria-invalid="true" />
// with aria-errormessage and aria-invalid
const usernameInput = getByLabelText('Username')
expect(usernameInput).toHaveErrorMessage('Error: Username must not contain spaces')
expect(usernameInput).toHaveErrorMessage(/Error/) // to partially match
expect(usernameInput).toHaveErrorMessage(expect.stringContaining('Error') // to partially match
expect(usernameInput).toHaveErrorMessage(/error/i) // to use case-insensitive match
expect(usernameInput).not.toHaveErrorMessage('Other error message')
// with just aria-errormessage
const emailInput = getByLabelText('Email')
expect(emailInput).not.toHaveErrorMessage()
expect(emailInput).not.toHaveErrorMessage('') // Missing aria-invalid will return false
// with just aria-invalid
const passwordInput = getByLabelText('Password')
expect(passwordInput).not.toHaveErrorMessage()
expect(passwordInput).toHaveErrorMessage('') // Missing or empty error message always becomes a blank string,