Skip to content

Commit fc9ce6d

Browse files
authored
fix: Updates deprecated matchers info (#378)
1 parent 87ffd2a commit fc9ce6d

File tree

4 files changed

+153
-80
lines changed

4 files changed

+153
-80
lines changed

README.md

+87-79
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ clear to read and to maintain.
4949
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
5050
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
5151

52+
5253
- [Installation](#installation)
5354
- [Usage](#usage)
5455
- [With TypeScript](#with-typescript)
5556
- [Custom matchers](#custom-matchers)
5657
- [`toBeDisabled`](#tobedisabled)
5758
- [`toBeEnabled`](#tobeenabled)
58-
- [`toBeEmpty`](#tobeempty)
5959
- [`toBeEmptyDOMElement`](#tobeemptydomelement)
6060
- [`toBeInTheDocument`](#tobeinthedocument)
6161
- [`toBeInvalid`](#tobeinvalid)
@@ -76,10 +76,11 @@ clear to read and to maintain.
7676
- [`toHaveDisplayValue`](#tohavedisplayvalue)
7777
- [`toBeChecked`](#tobechecked)
7878
- [`toBePartiallyChecked`](#tobepartiallychecked)
79-
- [`toHaveDescription`](#tohavedescription)
8079
- [`toHaveErrorMessage`](#tohaveerrormessage)
8180
- [Deprecated matchers](#deprecated-matchers)
81+
- [`toBeEmpty`](#tobeempty)
8282
- [`toBeInTheDOM`](#tobeinthedom)
83+
- [`toHaveDescription`](#tohavedescription)
8384
- [Inspiration](#inspiration)
8485
- [Other Solutions](#other-solutions)
8586
- [Guiding Principles](#guiding-principles)
@@ -205,31 +206,6 @@ your tests.
205206
206207
<hr />
207208

208-
### `toBeEmpty`
209-
210-
```typescript
211-
toBeEmpty()
212-
```
213-
214-
This allows you to assert whether an element has content or not.
215-
216-
#### Examples
217-
218-
```html
219-
<span data-testid="not-empty"><span data-testid="empty"></span></span>
220-
```
221-
222-
```javascript
223-
expect(getByTestId('empty')).toBeEmpty()
224-
expect(getByTestId('not-empty')).not.toBeEmpty()
225-
```
226-
227-
> Note: This matcher is being deprecated due to a name clash with
228-
> `jest-extended`. See more info in #216. In the future, please use only:
229-
> [`toBeEmptyDOMElement`](#toBeEmptyDOMElement)
230-
231-
<hr />
232-
233209
### `toBeEmptyDOMElement`
234210

235211
```typescript
@@ -1081,58 +1057,6 @@ expect(inputCheckboxIndeterminate).toBePartiallyChecked()
10811057

10821058
<hr />
10831059

1084-
### `toHaveDescription`
1085-
1086-
```typescript
1087-
toHaveDescription(text: string | RegExp)
1088-
```
1089-
1090-
This allows you to check whether the given element has a description or not.
1091-
1092-
An element gets its description via the
1093-
[`aria-describedby` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute).
1094-
Set this to the `id` of one or more other elements. These elements may be nested
1095-
inside, be outside, or a sibling of the passed in element.
1096-
1097-
Whitespace is normalized. Using multiple ids will
1098-
[join the referenced elements’ text content separated by a space](https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_description).
1099-
1100-
When a `string` argument is passed through, it will perform a whole
1101-
case-sensitive match to the description text.
1102-
1103-
To perform a case-insensitive match, you can use a `RegExp` with the `/i`
1104-
modifier.
1105-
1106-
To perform a partial match, you can pass a `RegExp` or use
1107-
`expect.stringContaining("partial string")`.
1108-
1109-
#### Examples
1110-
1111-
```html
1112-
<button aria-label="Close" aria-describedby="description-close">
1113-
X
1114-
</button>
1115-
<div id="description-close">
1116-
Closing will discard any changes
1117-
</div>
1118-
1119-
<button>Delete</button>
1120-
```
1121-
1122-
```javascript
1123-
const closeButton = getByRole('button', {name: 'Close'})
1124-
1125-
expect(closeButton).toHaveDescription('Closing will discard any changes')
1126-
expect(closeButton).toHaveDescription(/will discard/) // to partially match
1127-
expect(closeButton).toHaveDescription(expect.stringContaining('will discard')) // to partially match
1128-
expect(closeButton).toHaveDescription(/^closing/i) // to use case-insensitive match
1129-
expect(closeButton).not.toHaveDescription('Other description')
1130-
1131-
const deleteButton = getByRole('button', {name: 'Delete'})
1132-
expect(deleteButton).not.toHaveDescription()
1133-
expect(deleteButton).toHaveDescription('') // Missing or empty description always becomes a blank string
1134-
```
1135-
11361060
### `toHaveErrorMessage`
11371061

11381062
```typescript
@@ -1187,8 +1111,36 @@ expect(timeInput).not.toHaveErrorMessage('Pikachu!')
11871111

11881112
## Deprecated matchers
11891113

1114+
### `toBeEmpty`
1115+
1116+
> Note: This matcher is being deprecated due to a name clash with
1117+
> `jest-extended`. See more info in #216. In the future, please use only
1118+
> [`toBeEmptyDOMElement`](#toBeEmptyDOMElement)
1119+
1120+
```typescript
1121+
toBeEmpty()
1122+
```
1123+
1124+
This allows you to assert whether an element has content or not.
1125+
1126+
#### Examples
1127+
1128+
```html
1129+
<span data-testid="not-empty"><span data-testid="empty"></span></span>
1130+
```
1131+
1132+
```javascript
1133+
expect(getByTestId('empty')).toBeEmpty()
1134+
expect(getByTestId('not-empty')).not.toBeEmpty()
1135+
```
1136+
1137+
<hr />
1138+
11901139
### `toBeInTheDOM`
11911140

1141+
> This custom matcher is deprecated. Prefer
1142+
> [`toBeInTheDocument`](#tobeinthedocument) instead.
1143+
11921144
```typescript
11931145
toBeInTheDOM()
11941146
```
@@ -1219,6 +1171,62 @@ expect(document.querySelector('.cancel-button')).toBeTruthy()
12191171
> replacing `toBeInTheDOM` to read through the documentation of the proposed
12201172
> alternatives to see which use case works better for your needs.
12211173
1174+
### `toHaveDescription`
1175+
1176+
> This custom matcher is deprecated. Prefer
1177+
> [`toHaveAccessibleDescription`](#tohaveaccessibledescription) instead, which
1178+
> is more comprehensive in implementing the official spec.
1179+
1180+
```typescript
1181+
toHaveDescription(text: string | RegExp)
1182+
```
1183+
1184+
This allows you to check whether the given element has a description or not.
1185+
1186+
An element gets its description via the
1187+
[`aria-describedby` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute).
1188+
Set this to the `id` of one or more other elements. These elements may be nested
1189+
inside, be outside, or a sibling of the passed in element.
1190+
1191+
Whitespace is normalized. Using multiple ids will
1192+
[join the referenced elements’ text content separated by a space](https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_description).
1193+
1194+
When a `string` argument is passed through, it will perform a whole
1195+
case-sensitive match to the description text.
1196+
1197+
To perform a case-insensitive match, you can use a `RegExp` with the `/i`
1198+
modifier.
1199+
1200+
To perform a partial match, you can pass a `RegExp` or use
1201+
`expect.stringContaining("partial string")`.
1202+
1203+
#### Examples
1204+
1205+
```html
1206+
<button aria-label="Close" aria-describedby="description-close">
1207+
X
1208+
</button>
1209+
<div id="description-close">
1210+
Closing will discard any changes
1211+
</div>
1212+
1213+
<button>Delete</button>
1214+
```
1215+
1216+
```javascript
1217+
const closeButton = getByRole('button', {name: 'Close'})
1218+
1219+
expect(closeButton).toHaveDescription('Closing will discard any changes')
1220+
expect(closeButton).toHaveDescription(/will discard/) // to partially match
1221+
expect(closeButton).toHaveDescription(expect.stringContaining('will discard')) // to partially match
1222+
expect(closeButton).toHaveDescription(/^closing/i) // to use case-insensitive match
1223+
expect(closeButton).not.toHaveDescription('Other description')
1224+
1225+
const deleteButton = getByRole('button', {name: 'Delete'})
1226+
expect(deleteButton).not.toHaveDescription()
1227+
expect(deleteButton).toHaveDescription('') // Missing or empty description always becomes a blank string
1228+
```
1229+
12221230
## Inspiration
12231231

12241232
This whole library was extracted out of Kent C. Dodds' [DOM Testing

src/__tests__/to-have-accessible-description.js

+50
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,54 @@ describe('.toHaveAccessibleDescription', () => {
5656
expect(logo).not.toHaveAccessibleDescription('The logo of Our Company')
5757
}).toThrow(/expected element not to have accessible description/i)
5858
})
59+
60+
it('handles multiple ids', () => {
61+
const {queryByTestId} = render(`
62+
<div>
63+
<div id="first">First description</div>
64+
<div id="second">Second description</div>
65+
<div id="third">Third description</div>
66+
67+
<div data-testid="multiple" aria-describedby="first second third"></div>
68+
</div>
69+
`)
70+
71+
expect(queryByTestId('multiple')).toHaveAccessibleDescription(
72+
'First description Second description Third description',
73+
)
74+
expect(queryByTestId('multiple')).toHaveAccessibleDescription(
75+
/Second description Third/,
76+
)
77+
expect(queryByTestId('multiple')).toHaveAccessibleDescription(
78+
expect.stringContaining('Second description Third'),
79+
)
80+
expect(queryByTestId('multiple')).toHaveAccessibleDescription(
81+
expect.stringMatching(/Second description Third/),
82+
)
83+
expect(queryByTestId('multiple')).not.toHaveAccessibleDescription(
84+
'Something else',
85+
)
86+
expect(queryByTestId('multiple')).not.toHaveAccessibleDescription('First')
87+
})
88+
89+
it('normalizes whitespace', () => {
90+
const {queryByTestId} = render(`
91+
<div id="first">
92+
Step
93+
1
94+
of
95+
4
96+
</div>
97+
<div id="second">
98+
And
99+
extra
100+
description
101+
</div>
102+
<div data-testid="target" aria-describedby="first second"></div>
103+
`)
104+
105+
expect(queryByTestId('target')).toHaveAccessibleDescription(
106+
'Step 1 of 4 And extra description',
107+
)
108+
})
59109
})

src/__tests__/to-have-description.js

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import {render} from './helpers/test-utils'
22

33
describe('.toHaveDescription', () => {
4+
let spy
5+
beforeAll(() => {
6+
// @deprecated intentionally hiding warnings for test clarity
7+
spy = jest.spyOn(console, 'warn').mockImplementation(() => {})
8+
})
9+
10+
afterAll(() => {
11+
spy.mockRestore()
12+
})
13+
414
test('handles positive test cases', () => {
515
const {queryByTestId} = render(`
616
<div id="description">The description</div>

src/to-have-description.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import {checkHtmlElement, getMessage, normalize} from './utils'
1+
import {checkHtmlElement, getMessage, normalize, deprecate} from './utils'
22

33
// See algoritm: https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_description
44
export function toHaveDescription(htmlElement, checkWith) {
5+
deprecate(
6+
'toBeInTheDOM',
7+
'Please use toBeInTheDocument for searching the entire document and toContainElement for searching a specific container.',
8+
)
9+
510
checkHtmlElement(htmlElement, toHaveDescription, this)
611

712
const expectsDescription = checkWith !== undefined

0 commit comments

Comments
 (0)