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

Use custom jest matchers from jest-dom #15

Merged
merged 2 commits into from
Apr 10, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 23 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ your team down.

The `dom-testing-library` is a very light-weight solution for testing DOM nodes
(whether simulated with [`JSDOM`](https://github.com/jsdom/jsdom) as provided by
default with [jest](https://facebook.github.io/jest) or in the browser). The
main utilities it provides involve querying the DOM for nodes in a way that's
similar to how the user finds elements on the page. In this way, the library
helps ensure your tests give you confidence in your UI code. The
`dom-testing-library`'s primary guiding principle is:
default with [jest][] or in the browser). The main utilities it provides involve
querying the DOM for nodes in a way that's similar to how the user finds
elements on the page. In this way, the library helps ensure your tests give you
confidence in your UI code. The `dom-testing-library`'s primary guiding
principle is:

> [The more your tests resemble the way your software is used, the more confidence they can give you.][guiding-principle]

Expand Down Expand Up @@ -80,11 +80,7 @@ when a real user uses it.
* [`waitForElement`](#waitforelement)
* [`fireEvent(node: HTMLElement, event: Event)`](#fireeventnode-htmlelement-event-event)
* [Custom Jest Matchers](#custom-jest-matchers)
* [`toBeInTheDOM`](#tobeinthedom)
* [`toHaveTextContent`](#tohavetextcontent)
* [`toHaveAttribute`](#tohaveattribute)
* [`toHaveClass`](#tohaveclass)
* [Custom Jest Matchers - Typescript](#custom-jest-matchers---typescript)
* [Using other assertion libraries](#using-other-assertion-libraries)
* [`TextMatch`](#textmatch)
* [`query` APIs](#query-apis)
* [Debugging](#debugging)
Expand Down Expand Up @@ -400,106 +396,37 @@ fireEvent.click(getElementByText('Submit'), rightClick)

## Custom Jest Matchers

There are two simple API which extend the `expect` API of jest for making assertions easier.

### `toBeInTheDOM`

This allows you to assert whether an element present in the DOM or not.
When using [jest][], we recommend that you import a set of custom matchers that
make it easier to check several aspects of the state of a DOM element. These are
provided by [jest-dom](https://github.com/gnapse/jest-dom), but are also
included for convenience to be imported from this library directly:

```javascript
// add the custom expect matchers
import 'dom-testing-library/extend-expect'

// <span data-testid="greetings">Hello World</span>
expect(queryByText(container, 'greetings')).toBeInTheDOM()
expect(queryByText(container, 'greetings')).not.toHaveTextContent('Bye bye')
// ...
// <span data-testid="count-value">2</span>
expect(queryByTestId(container, 'count-value')).toBeInTheDOM()
expect(queryByTestId(container, 'count-value1')).not.toBeInTheDOM()
// ...
```

> Note: when using `toBeInTheDOM`, make sure you use a query function
> (like `queryByTestId`) rather than a get function (like `getByTestId`).
> Otherwise the `get*` function could throw an error before your assertion.

### `toHaveTextContent`

This API allows you to check whether the given element has a text content or not.

```javascript
// add the custom expect matchers
import 'dom-testing-library/extend-expect'

// ...
// <span data-testid="count-value">2</span>
expect(getByTestId(container, 'count-value')).toHaveTextContent('2')
expect(getByTestId(container, 'count-value')).not.toHaveTextContent('21')
// ...
```

### `toHaveAttribute`

This allows you to check wether the given element has an attribute or not. You
can also optionally check that the attribute has a specific expected value.

```javascript
// add the custom expect matchers
import 'dom-testing-library/extend-expect'

// ...
// <button data-testid="ok-button" type="submit" disabled>
// OK
// </button>
expect(getByTestId(container, 'ok-button')).toHaveAttribute('disabled')
expect(getByTestId(container, 'ok-button')).toHaveAttribute('type', 'submit')
expect(getByTestId(container, 'ok-button')).not.toHaveAttribute(
'type',
'button',
)
// ...
```

### `toHaveClass`
Check out [jest-dom's documentation](https://github.com/gnapse/jest-dom#readme)
for a full list of available matchers.

This allows you to check wether the given element has certain classes within its
`class` attribute.
### Using other assertion libraries

```javascript
// add the custom expect matchers
import 'dom-testing-library/extend-expect'
If you're not using jest, you may be able to find a similar set of custom
assertions for your library of choice. Here's a list of alternatives to jest-dom
for other popular assertion libraries:

// ...
// <button data-testid="delete-button" class="btn extra btn-danger">
// Delete item
// </button>
expect(getByTestId(container, 'delete-button')).toHaveClass('extra')
expect(getByTestId(container, 'delete-button')).toHaveClass('btn-danger btn')
expect(getByTestId(container, 'delete-button')).not.toHaveClass('btn-link')
// ...
```

### Custom Jest Matchers - Typescript
* [chai-dom](https://github.com/nathanboktae/chai-dom)

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:

```typescript
import {getByTestId} from 'dom-testing-library'
// this adds custom expect matchers
import 'dom-testing-library/extend-expect'
interface ExtendedMatchers extends jest.Matchers<void> {
toHaveTextContent: (htmlElement: string) => object
toBeInTheDOM: () => void
}
test('renders the tooltip as expected', async () => {
// however you render it:
// render(`<div><span data-testid="greeting">hello world</span></div>`)
;(expect(
container,
getByTestId('greeting'),
) as ExtendedMatchers).toHaveTextContent('hello world')
})
```
If you're aware of some other alternatives, please [make a pull request][prs]
and add it here!

## `TextMatch`

Expand Down Expand Up @@ -768,3 +695,4 @@ MIT
[set-immediate]: https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
[guiding-principle]: https://twitter.com/kentcdodds/status/977018512689455106
[data-testid-blog-post]: https://blog.kentcdodds.com/making-your-ui-tests-resilient-to-change-d37a6ee37269
[jest]: https://facebook.github.io/jest
2 changes: 1 addition & 1 deletion extend-expect.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// eslint-disable-next-line
require('./dist/extend-expect')
require('jest-dom/extend-expect')
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"extend-expect.js"
],
"dependencies": {
"jest-matcher-utils": "^22.4.3",
"jest-dom": "^1.0.0",
"pretty-format": "^22.4.3",
"mutationobserver-shim": "^0.3.2",
"wait-for-expect": "^0.4.0"
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/element-queries.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import '../extend-expect'
import 'jest-dom/extend-expect'
import {render} from './helpers/test-utils'

test('query can return null', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/example.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// query utilities:
import {getByLabelText, getByText, getByTestId, queryByTestId, wait} from '../'
// adds special assertions like toHaveTextContent
import '../extend-expect'
import 'jest-dom/extend-expect'

function getExampleDOM() {
// This is just a raw example of setting up some DOM
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/wait-for-element.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {waitForElement, wait} from '../'
// adds special assertions like toBeInTheDOM
import '../extend-expect'
import 'jest-dom/extend-expect'
import {render} from './helpers/test-utils'

async function skipSomeTime(delayMs) {
Expand Down
9 changes: 0 additions & 9 deletions src/extend-expect.js

This file was deleted.

169 changes: 0 additions & 169 deletions src/jest-extensions.js

This file was deleted.