|  | 
| 16 | 16 | [![downloads][downloads-badge]][npmtrends] | 
| 17 | 17 | [![MIT License][license-badge]][license] | 
| 18 | 18 | 
 | 
| 19 |  | -[](#contributors) | 
|  | 19 | +[](#contributors) | 
| 20 | 20 | [![PRs Welcome][prs-badge]][prs] | 
| 21 | 21 | [![Code of Conduct][coc-badge]][coc] | 
| 22 | 22 | 
 | 
| @@ -82,7 +82,8 @@ facilitate testing implementation details). Read more about this in | 
| 82 | 82 | * [Custom Jest Matchers](#custom-jest-matchers) | 
| 83 | 83 |   * [`toBeInTheDOM`](#tobeinthedom) | 
| 84 | 84 |   * [`toHaveTextContent`](#tohavetextcontent) | 
| 85 |  | -  * [Custom Jest Matchers - Typescript](#custom-jest-matchers-typescript) | 
|  | 85 | +  * [`toHaveAttribute`](#tohaveattribute) | 
|  | 86 | +  * [Custom Jest Matchers - Typescript](#custom-jest-matchers---typescript) | 
| 86 | 87 | * [`TextMatch`](#textmatch) | 
| 87 | 88 | * [`query` APIs](#query-apis) | 
| 88 | 89 | * [Examples](#examples) | 
| @@ -138,6 +139,7 @@ test('Fetch makes an API call and displays the greeting when load-greeting is cl | 
| 138 | 139 |   expect(axiosMock.get).toHaveBeenCalledTimes(1) | 
| 139 | 140 |   expect(axiosMock.get).toHaveBeenCalledWith(url) | 
| 140 | 141 |   expect(getByTestId('greeting-text')).toHaveTextContent('hello there') | 
|  | 142 | +  expect(getByTestId('ok-button')).toHaveAttribute('disabled') | 
| 141 | 143 |   // snapshots work great with regular DOM nodes! | 
| 142 | 144 |   expect(container.firstChild).toMatchSnapshot() | 
| 143 | 145 | }) | 
| @@ -347,33 +349,55 @@ expect(getByTestId('count-value')).toHaveTextContent('2') | 
| 347 | 349 | expect(getByTestId('count-value')).not.toHaveTextContent('21') | 
| 348 | 350 | // ... | 
| 349 | 351 | ``` | 
|  | 352 | +
 | 
|  | 353 | +### `toHaveAttribute` | 
|  | 354 | +
 | 
|  | 355 | +This allows you to check wether the given element has an attribute or not. You | 
|  | 356 | +can also optionally check that the attribute has a specific expected value. | 
|  | 357 | +
 | 
|  | 358 | +```javascript | 
|  | 359 | +// add the custom expect matchers | 
|  | 360 | +import 'react-testing-library/extend-expect' | 
|  | 361 | + | 
|  | 362 | +// ... | 
|  | 363 | +const {getByTestId} = render( | 
|  | 364 | +  <button data-testid="ok-button" type="submit" disabled> | 
|  | 365 | +    OK | 
|  | 366 | +  </button>, | 
|  | 367 | +) | 
|  | 368 | +expect(getByTestId('ok-button')).toHaveAttribute('disabled') | 
|  | 369 | +expect(getByTestId('ok-button')).toHaveAttribute('type', 'submit') | 
|  | 370 | +expect(getByTestId('ok-button')).not.toHaveAttribute('type', 'button') | 
|  | 371 | +// ... | 
|  | 372 | +``` | 
|  | 373 | +
 | 
| 350 | 374 | ### Custom Jest Matchers - Typescript | 
| 351 | 375 | 
 | 
| 352 |  | -When you use custom Jest Matchers with Typescript,  you will need to extend the type signature of `jest.Matchers<void>`, then cast the result of `expect` accordingly. Here's a handy usage example: | 
|  | 376 | +When you use custom Jest Matchers with Typescript, you will need to extend the type signature of `jest.Matchers<void>`, then cast the result of `expect` accordingly. Here's a handy usage example: | 
| 353 | 377 | 
 | 
| 354 | 378 | ```typescript | 
| 355 | 379 | // this adds custom expect matchers | 
| 356 |  | -import 'react-testing-library/extend-expect'; | 
|  | 380 | +import 'react-testing-library/extend-expect' | 
| 357 | 381 | interface ExtendedMatchers extends jest.Matchers<void> { | 
| 358 |  | -  toHaveTextContent: (htmlElement: string) => object; | 
| 359 |  | -  toBeInTheDOM: () => void; | 
|  | 382 | +  toHaveTextContent: (htmlElement: string) => object | 
|  | 383 | +  toBeInTheDOM: () => void | 
| 360 | 384 | } | 
| 361 | 385 | test('renders the tooltip as expected', async () => { | 
| 362 | 386 |   const { | 
| 363 | 387 |     // getByLabelText, | 
| 364 | 388 |     getByText, | 
| 365 | 389 |     //  getByTestId, | 
| 366 |  | -    container | 
| 367 |  | -  } = render(<Tooltip label="hello world">Child</Tooltip>); | 
|  | 390 | +    container, | 
|  | 391 | +  } = render(<Tooltip label="hello world">Child</Tooltip>) | 
| 368 | 392 |   // tests rendering of the child | 
| 369 |  | -  getByText('Child'); | 
|  | 393 | +  getByText('Child') | 
| 370 | 394 |   // tests rendering of tooltip label | 
| 371 |  | -  (expect(getByText('hello world')) as ExtendedMatchers).toHaveTextContent( | 
| 372 |  | -    'hello world' | 
| 373 |  | -  ); | 
|  | 395 | +  ;(expect(getByText('hello world')) as ExtendedMatchers).toHaveTextContent( | 
|  | 396 | +    'hello world', | 
|  | 397 | +  ) | 
| 374 | 398 |   // snapshots work great with regular DOM nodes! | 
| 375 |  | -  expect(container.firstChild).toMatchSnapshot(); | 
| 376 |  | -}); | 
|  | 399 | +  expect(container.firstChild).toMatchSnapshot() | 
|  | 400 | +}) | 
| 377 | 401 | ``` | 
| 378 | 402 | 
 | 
| 379 | 403 | ## `TextMatch` | 
| @@ -715,10 +739,12 @@ light-weight, simple, and understandable. | 
| 715 | 739 | Thanks goes to these people ([emoji key][emojis]): | 
| 716 | 740 | 
 | 
| 717 | 741 | <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | 
|  | 742 | +
 | 
| 718 | 743 | <!-- prettier-ignore --> | 
| 719 | 744 | | [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=kentcdodds "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=kentcdodds "Tests") | [<img src="https://avatars1.githubusercontent.com/u/2430381?v=4" width="100px;"/><br /><sub><b>Ryan Castner</b></sub>](http://audiolion.github.io)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=audiolion "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/8008023?v=4" width="100px;"/><br /><sub><b>Daniel Sandiego</b></sub>](https://www.dnlsandiego.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=dnlsandiego "Code") | [<img src="https://avatars2.githubusercontent.com/u/12592677?v=4" width="100px;"/><br /><sub><b>Paweł Mikołajczyk</b></sub>](https://github.com/Miklet)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=Miklet "Code") | [<img src="https://avatars3.githubusercontent.com/u/464978?v=4" width="100px;"/><br /><sub><b>Alejandro Ñáñez Ortiz</b></sub>](http://co.linkedin.com/in/alejandronanez/)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=alejandronanez "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1402095?v=4" width="100px;"/><br /><sub><b>Matt Parrish</b></sub>](https://github.com/pbomb)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Apbomb "Bug reports") [💻](https://github.com/kentcdodds/react-testing-library/commits?author=pbomb "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=pbomb "Documentation") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=pbomb "Tests") | [<img src="https://avatars1.githubusercontent.com/u/1288694?v=4" width="100px;"/><br /><sub><b>Justin Hall</b></sub>](https://github.com/wKovacs64)<br />[📦](#platform-wKovacs64 "Packaging/porting to new platform") | | 
| 720 | 745 | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | 
| 721 |  | -| [<img src="https://avatars1.githubusercontent.com/u/1241511?s=460&v=4" width="100px;"/><br /><sub><b>Anto Aravinth</b></sub>](https://github.com/antoaravinth)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Code") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Tests") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3462296?v=4" width="100px;"/><br /><sub><b>Jonah Moses</b></sub>](https://github.com/JonahMoses)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=JonahMoses "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Code") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Tests") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Asompylasar "Bug reports") [🤔](#ideas-sompylasar "Ideas, Planning, & Feedback") | [<img src="https://avatars3.githubusercontent.com/u/4439618?v=4" width="100px;"/><br /><sub><b>Jesse Day</b></sub>](https://github.com/jday3)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=jday3 "Code") | | 
|  | 746 | +| [<img src="https://avatars1.githubusercontent.com/u/1241511?s=460&v=4" width="100px;"/><br /><sub><b>Anto Aravinth</b></sub>](https://github.com/antoaravinth)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Code") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Tests") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=antoaravinth "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3462296?v=4" width="100px;"/><br /><sub><b>Jonah Moses</b></sub>](https://github.com/JonahMoses)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=JonahMoses "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Code") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Tests") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=lgandecki "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Asompylasar "Bug reports") [🤔](#ideas-sompylasar "Ideas, Planning, & Feedback") | [<img src="https://avatars3.githubusercontent.com/u/4439618?v=4" width="100px;"/><br /><sub><b>Jesse Day</b></sub>](https://github.com/jday3)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=jday3 "Code") | [<img src="https://avatars0.githubusercontent.com/u/15199?v=4" width="100px;"/><br /><sub><b>Ernesto García</b></sub>](http://gnapse.github.io)<br />[💬](#question-gnapse "Answering Questions") [💻](https://github.com/kentcdodds/react-testing-library/commits?author=gnapse "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=gnapse "Documentation") | | 
|  | 747 | +
 | 
| 722 | 748 | <!-- ALL-CONTRIBUTORS-LIST:END --> | 
| 723 | 749 | 
 | 
| 724 | 750 | This project follows the [all-contributors][all-contributors] specification. | 
|  | 
0 commit comments