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

Allow aria-invalid on any element #259

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 7 additions & 8 deletions README.md
Expand Up @@ -274,10 +274,9 @@ expect(
toBeInvalid()
```

This allows you to check if a form element, or the entire `form`, is currently
invalid.
This allows you to check if an element, is currently invalid.

An `input`, `select`, `textarea`, or `form` element is invalid if it has an
An element is invalid if it has an
[`aria-invalid` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute)
with no value or a value of `"true"`, or if the result of
[`checkValidity()`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)
Expand Down Expand Up @@ -359,14 +358,13 @@ expect(getByTestId('supported-role-aria')).toBeRequired()
toBeValid()
```

This allows you to check if the value of a form element, or the entire `form`,
is currently valid.
This allows you to check if the value of an element, is currently valid.

An `input`, `select`, `textarea`, or `form` element is valid if it has no
[`aria-invalid` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute)
An element is valid if it has no
[`aria-invalid` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute)s
or an attribute value of `"false"`. The result of
[`checkValidity()`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)
must also be `true`.
must also be `true` if it's a form element.

#### Examples

Expand Down Expand Up @@ -1162,6 +1160,7 @@ Thanks goes to these people ([emoji key][emojis]):

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors][all-contributors] specification.
Expand Down
64 changes: 64 additions & 0 deletions src/__tests__/to-be-invalid.js
Expand Up @@ -80,6 +80,38 @@ describe('.toBeInvalid', () => {
expect(() => expect(queryByTestId('valid')).toBeInvalid()).toThrowError()
expect(() => expect(invalidFormNode).not.toBeInvalid()).toThrowError()
})

test('handles any element', () => {
const {queryByTestId} = render(`
<ol data-testid="valid">
<li data-testid="no-aria-invalid" > </li>
<li data-testid="aria-invalid" aria-invalid> </li>
<li data-testid="aria-invalid-value" aria-invalid="true"> </li>
<li data-testid="aria-invalid-false" aria-invalid="false"> </li>
</ol>
`)

expect(queryByTestId('valid')).not.toBeInvalid()
expect(queryByTestId('no-aria-invalid')).not.toBeInvalid()
expect(queryByTestId('aria-invalid')).toBeInvalid()
expect(queryByTestId('aria-invalid-value')).toBeInvalid()
expect(queryByTestId('aria-invalid-false')).not.toBeInvalid()

// negative test cases wrapped in throwError assertions for coverage.
expect(() => expect(queryByTestId('valid')).toBeInvalid()).toThrowError()
expect(() =>
expect(queryByTestId('no-aria-invalid')).toBeInvalid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid')).not.toBeInvalid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid-value')).not.toBeInvalid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid-false')).toBeInvalid(),
).toThrowError()
})
})

describe('.toBeValid', () => {
Expand Down Expand Up @@ -129,4 +161,36 @@ describe('.toBeValid', () => {
expect(() => expect(queryByTestId('valid')).not.toBeValid()).toThrowError()
expect(() => expect(invalidFormNode).toBeValid()).toThrowError()
})

test('handles any element', () => {
const {queryByTestId} = render(`
<ol data-testid="valid">
<li data-testid="no-aria-invalid" > </li>
<li data-testid="aria-invalid" aria-invalid> </li>
<li data-testid="aria-invalid-value" aria-invalid="true"> </li>
<li data-testid="aria-invalid-false" aria-invalid="false"> </li>
</ol>
`)

expect(queryByTestId('valid')).toBeValid()
expect(queryByTestId('no-aria-invalid')).toBeValid()
expect(queryByTestId('aria-invalid')).not.toBeValid()
expect(queryByTestId('aria-invalid-value')).not.toBeValid()
expect(queryByTestId('aria-invalid-false')).toBeValid()

// negative test cases wrapped in throwError assertions for coverage.
expect(() => expect(queryByTestId('valid')).not.toBeValid()).toThrowError()
expect(() =>
expect(queryByTestId('no-aria-invalid')).not.toBeValid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid')).toBeValid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid-value')).toBeValid(),
).toThrowError()
expect(() =>
expect(queryByTestId('aria-invalid-false')).not.toBeValid(),
).toThrowError()
})
})
19 changes: 12 additions & 7 deletions src/to-be-invalid.js
Expand Up @@ -10,15 +10,23 @@ function isElementHavingAriaInvalid(element) {
)
}

function isSupportsValidityMethod(element) {
return FORM_TAGS.includes(getTag(element))
}

function isElementInvalid(element) {
return !element.checkValidity()
const isHaveAriaInvalid = isElementHavingAriaInvalid(element)
if (isSupportsValidityMethod(element)) {
return isHaveAriaInvalid || !element.checkValidity()
} else {
return isHaveAriaInvalid
}
}

export function toBeInvalid(element) {
checkHtmlElement(element, toBeInvalid, this)

const isInvalid =
isElementHavingAriaInvalid(element) || isElementInvalid(element)
const isInvalid = isElementInvalid(element)

return {
pass: isInvalid,
Expand All @@ -37,10 +45,7 @@ export function toBeInvalid(element) {
export function toBeValid(element) {
checkHtmlElement(element, toBeValid, this)

const isValid =
!isElementHavingAriaInvalid(element) &&
FORM_TAGS.includes(getTag(element)) &&
!isElementInvalid(element)
const isValid = !isElementInvalid(element)

return {
pass: isValid,
Expand Down