From 14d163045d486322113c305d7ef34abe790d6a70 Mon Sep 17 00:00:00 2001
From: Vladislav Katsura <33201468+missilev@users.noreply.github.com>
Date: Thu, 11 Jun 2020 17:46:23 +0300
Subject: [PATCH] feat: [toBeValid/toBeInvalid] Check aria-invalid on any
element (#259)
---
README.md | 15 ++++----
src/__tests__/to-be-invalid.js | 64 ++++++++++++++++++++++++++++++++++
src/to-be-invalid.js | 19 ++++++----
3 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 22901ce8..b7428b99 100644
--- a/README.md
+++ b/README.md
@@ -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)
@@ -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
@@ -1162,6 +1160,7 @@ Thanks goes to these people ([emoji key][emojis]):
+
This project follows the [all-contributors][all-contributors] specification.
diff --git a/src/__tests__/to-be-invalid.js b/src/__tests__/to-be-invalid.js
index 9929d53d..66ed8749 100644
--- a/src/__tests__/to-be-invalid.js
+++ b/src/__tests__/to-be-invalid.js
@@ -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(`
+
+ -
+ -
+ -
+ -
+
+ `)
+
+ 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', () => {
@@ -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(`
+
+ -
+ -
+ -
+ -
+
+ `)
+
+ 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()
+ })
})
diff --git a/src/to-be-invalid.js b/src/to-be-invalid.js
index 388c9f63..cb476827 100644
--- a/src/to-be-invalid.js
+++ b/src/to-be-invalid.js
@@ -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,
@@ -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,