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

Add docs for Web Testing Library #1204

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
74 changes: 74 additions & 0 deletions docs/web-testing-library/api.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
id: api
title: API
---

Several utilities are provided for dealing with asynchronous code. These can be
useful to wait for an element to appear or disappear in response to an event,
user action, timeout, or Promise. (See the
[guide to testing disappearance](guide-disappearance.mdx).)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this link work?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


The async methods return Promises, so be sure to use `await` or `.then` when
calling them.

## `waitFor`

```typescript
function waitFor<T>(
callback: () => T | Promise<T>,
options?: {
interval?: number
onTimeout?: (error: Error) => Error
showOriginalStackTrace?: boolean
signal?: AbortSignal
timeout?: number
},
): Promise<T>
```

When in need to wait for any period of time you can use `waitFor`, to wait for
your expectations to pass. Here's a simple example:

```javascript
// ...
// Wait until the callback does not throw an error. In this case, that means
// it'll wait until the mock function has been called once.
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
// ...
```

`waitFor` may run the callback a number of times until the timeout is reached.
Note that the number of calls is constrained by the `timeout` and `interval`
options.

This can be useful if you have a unit test that mocks API calls and you need to
wait for your mock promises to all resolve.

If you return a promise in the `waitFor` callback (either explicitly or
implicitly with the `async` syntax), then the `waitFor` utility does not call
your callback again until that promise rejects. This allows you to `waitFor`
things that must be checked asynchronously.

The default `interval` is `50ms`. However, it runs your callback
immediately before starting the intervals.

The `onTimeout` callback receives the error with which `waitFor` should reject.
You can return a more detailed error with which `waitFor` should reject. For
example, in a DOM you can return a snapshot of the DOM at the time `waitFor`
timed out.

You can pass an
[`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) if
you want `waitFor` to stop checking the callback (e.g. if you want it to race
against other observers like
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver)).
`waitFor` will then reject with the
[`reason` of the given `AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/reason).

By default, `waitFor` will reject with the stack trace of the `waitFor` call.
This is usually the more relevant stack trace for developers. However, you might
want to trace the last call to the given `callback` that caused `waitFor` to
reject. Then you can pass `showOriginalStackTrace: true`. We don't recommend
using it unless you know what you're doing.

The default `timeout` is `1000ms`.
18 changes: 18 additions & 0 deletions docs/web-testing-library/faq.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
id: faq
title: FAQ
---

<details>

<summary>Why "Web" in "Web Testing Library</summary>

This library implements testing utilities that are used on different runtimes
implementing the
[Minimum Common Web Platform API](https://proposal-common-min-api.deno.dev/) (or
parts of it). This includes browsers, Node.js, Deno, React Native and others
(the [runtime keys](https://runtime-keys.proposal.wintercg.org/#react-native)
contains known runtimes). The name is born out of pragmatism. A more precise
name would be "Web-interoperable runtimes Testing Library".

</details>
79 changes: 79 additions & 0 deletions docs/web-testing-library/install.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
id: install
title: Install
sidebar_label: Install
---

This module is distributed via [npm][npm] and should be installed as one of your
project's `devDependencies`:

```
npm install --save-dev @testing-library/web
```

## Wrappers

If you are using a framework or library such as React, you will likely want to
install the wrapper:

- [React Testing Library](react-testing-library/intro.mdx)
- [Reason Testing Library](bs-react-testing-library/intro.mdx)
- [React Native Testing Library](react-native-testing-library/intro.mdx)
- [Vue Testing Library](vue-testing-library/intro.mdx)
- [Marko Testing Library](marko-testing-library/intro.mdx)
- [Angular Testing Library](angular-testing-library/intro.mdx)
- [Preact Testing Library](preact-testing-library/intro.mdx)
- [Svelte Testing Library](svelte-testing-library/intro.mdx)
- [Cypress Testing Library](cypress-testing-library/intro.mdx)
- [Puppeteer Testing Library](pptr-testing-library/intro.mdx)
- [Testcafe Testing Library](testcafe-testing-library/intro.mdx)
- [Nightwatch Testing Library](nightwatch-testing-library/intro.mdx)

## Ecosystem

`Web Testing Library` works well with these companion libraries:

- [user-event](user-event/intro.mdx) browser event simulation
- [jest-dom](ecosystem-jest-dom.mdx) custom Jest matchers
- [bs-jest-dom](ecosystem-bs-jest-dom.mdx) companion library for
`bs-react-testing-library`
- [jest-native](ecosystem-jest-native.mdx) companion library for
`React Native Testing Library`
- [react-select-event](ecosystem-react-select-event.mdx) companion library for
`React Testing Library`
- [eslint-plugin-testing-library](ecosystem-eslint-plugin-testing-library.mdx)
ESLint plugin for Testing Library
- [eslint-plugin-jest-dom](ecosystem-eslint-plugin-jest-dom.mdx) ESLint plugin
for Jest DOM
- [riot-testing-library](ecosystem-riot-testing-library.mdx) adds APIs for
working with Riot.js components

## Main Exports

You can
[review the `Web Testing Library` package.json here](https://unpkg.com/@testing-library/web/package.json).

In particular, the `main`, `module`, and `umd:main` fields are useful. Each of
these points to a file that's useful in certain situations. Typically, your
testing framework will resolve to the correct one for your situation, but if it
does not, then you can either configure your testing framework to resolve to the
right file when you require/import `@testing-library/dom` or you can import the
file you need more explicitly. For example:

```js
import {waitFor} from '@testing-library/web/dist/@testing-library/web.umd.js'
```

You can
[review the published `dist` files here](https://unpkg.com/@testing-library/web/dist/).

The `main` file is configured to compile down to support the version of node
that is referenced in the `package.json` `engines.node` field. But the `module`
and `umd:main` files are configured to compile down to support browsers as old
as IE 10.

<!--
Links
-->

[npm]: https://www.npmjs.com/
49 changes: 49 additions & 0 deletions docs/web-testing-library/intro.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
id: intro
title: Introduction
---

## The problem

You want to write maintainable tests for [Web-interoperable
runtimes][min-web-api]. As a part of this goal, you want your tests to avoid
including implementation details of your components and rather focus on making
your tests give you the confidence for which they are intended. As part of this,
you want your testbase to be maintainable in the long run so refactors of your
components (changes to implementation but not functionality) don't break your
tests and slow you and your team down.

## This solution

The `Web Testing Library` is a very light-weight solution for testing code that
runs on Web-interoperable runtimes (a browser, [Node.js][node], [Deno][deno]
etc.) or [React Native][react-native]. The `Web 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.

We try to only expose methods and utilities that encourage you to write tests
that closely resemble how your code is used on the Web Platform or React Native.

Utilities are included in this project based on the following guiding
principles:

1. They should be usable on the [minimum common web platform API][min-web-api]
2. It should be generally useful for testing the application in the way the user
would use it. We _are_ making some trade-offs here because we're using a
computer and often a simulated environment, but in general, utilities should
encourage tests that use the application the way they're intended to be used.
3. Utility implementations and APIs should be simple and flexible.

**What this library is not**:

1. A test runner or framework
2. Specific to a testing framework (though we do have better defaults for Jest
like support for fake timers).

[jest]: https://jestjs.io
[node]: https://nodejs.org/en/
[deno]: https://deno.land/
[react-native]: https://reactnative.dev/
[min-web-api]: https://proposal-common-min-api.deno.dev/
8 changes: 8 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ module.exports = {
'svelte-testing-library/api',
],
},
{
'Web Testing Library': [
'web-testing-library/intro',
'web-testing-library/install',
'web-testing-library/api',
'web-testing-library/faq',
],
},
'cypress-testing-library/intro',
'pptr-testing-library/intro',
'testcafe-testing-library/intro',
Expand Down