diff --git a/README.md b/README.md
index bcb1393..7f93c4f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
jest-native
-
+
-
+
Custom jest matchers to test the state of React Native.
@@ -117,15 +117,18 @@ toBeDisabled();
Check whether or not an element is disabled from a user perspective.
This matcher will check if the element or its parent has a `disabled` prop, or if it has
-`accessibilityStates={['disabled']}`.
+`accessibilityState={{disabled: true]}.
+
+It also works with `accessibilityStates={['disabled']}` for now. However, this prop is deprecated in
+React Native [0.62](https://reactnative.dev/blog/2020/03/26/version-0.62#breaking-changes)
#### Examples
```javascript
const { getByTestId } = render(
- ,
);
@@ -148,7 +151,7 @@ Works similarly to `expect().not.toBeDisabled()`.
```javascript
const { getByTestId } = render(
- e} />
+ e} />
,
);
diff --git a/src/__tests__/to-be-disabled.js b/src/__tests__/to-be-disabled.js
index 5dc536c..f64e2cf 100644
--- a/src/__tests__/to-be-disabled.js
+++ b/src/__tests__/to-be-disabled.js
@@ -1,7 +1,6 @@
import React from 'react';
import {
Button,
- Text,
TouchableHighlight,
TouchableOpacity,
TouchableWithoutFeedback,
@@ -10,92 +9,77 @@ import {
} from 'react-native';
import { render } from '@testing-library/react-native';
-test('.toBeDisabled', () => {
- const { queryByTestId, queryByText, queryByTitle, queryByDisplayValue } = render(
-
-
-
-
- highlight
-
-
- opacity
-
-
- without
-
- ,
- );
-
- expect(queryByTestId('view')).toBeDisabled();
- expect(() => expect(queryByTestId('view')).not.toBeDisabled()).toThrowError();
-
- expect(queryByTitle('button')).toBeDisabled();
- expect(() => expect(queryByTitle('button')).not.toBeDisabled()).toThrowError();
-
- expect(queryByTestId('textInput')).toBeDisabled();
- expect(queryByDisplayValue('textInput')).toBeDisabled();
- expect(() => expect(queryByTestId('textInput')).not.toBeDisabled()).toThrowError();
- expect(() => expect(queryByDisplayValue('textInput')).not.toBeDisabled()).toThrowError();
-
- expect(queryByTestId('highlight')).toBeDisabled();
- expect(queryByText('highlight')).toBeDisabled();
- expect(() => expect(queryByTestId('highlight')).not.toBeDisabled()).toThrowError();
- expect(() => expect(queryByText('highlight')).not.toBeDisabled()).toThrowError();
-
- expect(queryByTestId('opacity')).toBeDisabled();
- expect(queryByText('opacity')).toBeDisabled();
- expect(() => expect(queryByTestId('opacity')).not.toBeDisabled()).toThrowError();
- expect(() => expect(queryByText('opacity')).not.toBeDisabled()).toThrowError();
-
- expect(queryByTestId('without')).toBeDisabled();
- expect(queryByText('without')).toBeDisabled();
- expect(() => expect(queryByTestId('without')).not.toBeDisabled()).toThrowError();
- expect(() => expect(queryByText('without')).not.toBeDisabled()).toThrowError();
+const ALLOWED_COMPONENTS = {
+ View,
+ Button,
+ TextInput,
+ TouchableHighlight,
+ TouchableOpacity,
+ TouchableWithoutFeedback,
+};
+
+describe('.toBeDisabled', () => {
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled prop for element ${name}`, () => {
+ const { queryByTestId } = render();
+
+ expect(queryByTestId(name)).toBeDisabled();
+ expect(() => expect(queryByTestId(name)).not.toBeDisabled()).toThrowError();
+ });
+ });
+
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled in accessibilityStates for element ${name}`, () => {
+ const { queryByTestId } = render(
+ ,
+ );
+
+ expect(queryByTestId(name)).toBeDisabled();
+ expect(() => expect(queryByTestId(name)).not.toBeDisabled()).toThrowError();
+ });
+ });
+
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled in accessibilityState for element ${name}`, () => {
+ const { queryByTestId } = render(
+ ,
+ );
+
+ expect(queryByTestId(name)).toBeDisabled();
+ expect(() => expect(queryByTestId(name)).not.toBeDisabled()).toThrowError();
+ });
+ });
});
-test('.toBeEnabled', () => {
- const { queryByTestId, queryByText, queryByTitle, queryByDisplayValue } = render(
-
-
-
-
- highlight
-
-
- opacity
-
-
- without
-
- ,
- );
-
- expect(queryByTestId('view')).toBeEnabled();
- expect(() => expect(queryByTestId('view')).not.toBeEnabled()).toThrowError();
-
- expect(queryByTitle('button')).toBeEnabled();
- expect(() => expect(queryByTitle('button')).not.toBeEnabled()).toThrowError();
-
- expect(queryByTestId('textInput')).toBeEnabled();
- expect(queryByDisplayValue('textInput')).toBeEnabled();
- expect(() => expect(queryByTestId('textInput')).not.toBeEnabled()).toThrowError();
- expect(() => expect(queryByDisplayValue('textInput')).not.toBeEnabled()).toThrowError();
-
- expect(queryByTestId('highlight')).toBeEnabled();
- expect(queryByText('highlight')).toBeEnabled();
- expect(() => expect(queryByTestId('highlight')).not.toBeEnabled()).toThrowError();
- expect(() => expect(queryByText('highlight')).not.toBeEnabled()).toThrowError();
-
- expect(queryByTestId('opacity')).toBeEnabled();
- expect(queryByText('opacity')).toBeEnabled();
- expect(() => expect(queryByTestId('opacity')).not.toBeEnabled()).toThrowError();
- expect(() => expect(queryByText('opacity')).not.toBeEnabled()).toThrowError();
-
- expect(queryByTestId('without')).toBeEnabled();
- expect(queryByText('without')).toBeEnabled();
- expect(() => expect(queryByTestId('without')).not.toBeEnabled()).toThrowError();
- expect(() => expect(queryByText('without')).not.toBeEnabled()).toThrowError();
+describe('.toBeEnabled', () => {
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled prop for element ${name} when undefined`, () => {
+ const { queryByTestId } = render();
+
+ expect(queryByTestId(name)).toBeEnabled();
+ expect(() => expect(queryByTestId(name)).not.toBeEnabled()).toThrowError();
+ });
+ });
+
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled in accessibilityStates for element ${name} when not included`, () => {
+ const { queryByTestId } = render();
+
+ expect(queryByTestId(name)).toBeEnabled();
+ expect(() => expect(queryByTestId(name)).not.toBeEnabled()).toThrowError();
+ });
+ });
+
+ Object.entries(ALLOWED_COMPONENTS).forEach(([name, Component]) => {
+ test(`handle disabled in accessibilityState for element ${name} when false`, () => {
+ const { queryByTestId } = render(
+ ,
+ );
+
+ expect(queryByTestId(name)).toBeEnabled();
+ expect(() => expect(queryByTestId(name)).not.toBeEnabled()).toThrowError();
+ });
+ });
});
test('matcher misses', () => {
diff --git a/src/to-be-disabled.js b/src/to-be-disabled.js
index 253d450..2b7b2b0 100644
--- a/src/to-be-disabled.js
+++ b/src/to-be-disabled.js
@@ -1,4 +1,4 @@
-import { compose, defaultTo, includes, path } from 'ramda';
+import { compose, defaultTo, includes, path, propEq, anyPass } from 'ramda';
import { matcherHint } from 'jest-matcher-utils';
import { checkReactElement, getType, printElement } from './utils';
@@ -22,13 +22,19 @@ function isElementDisabledByParent(parent) {
function isElementDisabled(element) {
const propDisabled = path(['props', 'disabled'], element);
- const stateDisabled = compose(
+ const hasStatesDisabled = compose(
includes('disabled'),
defaultTo([]),
path(['props', 'accessibilityStates']),
- )(element);
+ );
+ const hasStateDisabled = compose(
+ propEq('disabled', true),
+ defaultTo({}),
+ path(['props', 'accessibilityState']),
+ );
+ const stateDisabled = anyPass([hasStatesDisabled, hasStateDisabled])(element);
- return Boolean(DISABLE_TYPES.includes(getType(element)) && (propDisabled || stateDisabled));
+ return DISABLE_TYPES.includes(getType(element)) && (Boolean(propDisabled) || stateDisabled);
}
function isAncestorDisabled(element) {