From 50243578cca1ba20806ca943296e97388fdbcc14 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Sat, 14 Jan 2023 09:19:03 +0100 Subject: [PATCH 1/8] Add docs for Web Testing Library --- docs/web-testing-library/api.mdx | 57 ++++++++++++++++++++ docs/web-testing-library/faq.mdx | 18 +++++++ docs/web-testing-library/install.mdx | 80 ++++++++++++++++++++++++++++ docs/web-testing-library/intro.mdx | 49 +++++++++++++++++ sidebars.js | 8 +++ 5 files changed, 212 insertions(+) create mode 100644 docs/web-testing-library/api.mdx create mode 100644 docs/web-testing-library/faq.mdx create mode 100644 docs/web-testing-library/install.mdx create mode 100644 docs/web-testing-library/intro.mdx diff --git a/docs/web-testing-library/api.mdx b/docs/web-testing-library/api.mdx new file mode 100644 index 000000000..ed6ec4d9a --- /dev/null +++ b/docs/web-testing-library/api.mdx @@ -0,0 +1,57 @@ +--- +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).) + +The async methods return Promises, so be sure to use `await` or `.then` when +calling them. + +## `waitFor` + +```typescript +function waitFor( + callback: () => T | Promise, + options?: { + timeout?: number + interval?: number + onTimeout?: (error: Error) => Error + }, +): Promise +``` + +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 `async` syntax), then the `waitFor` utility will 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 will run your callback immediately +before starting the intervals. + +The default `timeout` is `1000ms`. + +The default `onTimeout` takes the error and appends the `container`'s printed +state to the error message which should hopefully make it easier to track down +what caused the timeout. diff --git a/docs/web-testing-library/faq.mdx b/docs/web-testing-library/faq.mdx new file mode 100644 index 000000000..d738a21ed --- /dev/null +++ b/docs/web-testing-library/faq.mdx @@ -0,0 +1,18 @@ +--- +id: faq +title: FAQ +--- + +
+ +Why "Web" in "Web Testing Library + +This library implements testing utilities that are used on different clients +implementing the +[Minimum Common Web Platform API](https://proposal-common-min-api.deno.dev/) (or +parts of it). This includes browsers, Node.js, Deno and React Native. + +React Native is included for pragmatic reasons. In the future, we might split +the utilities up in Web and Timer testing utilities. + +
diff --git a/docs/web-testing-library/install.mdx b/docs/web-testing-library/install.mdx new file mode 100644 index 000000000..e58f09a32 --- /dev/null +++ b/docs/web-testing-library/install.mdx @@ -0,0 +1,80 @@ +--- +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. + + + +[npm]: https://www.npmjs.com/ +[node]: https://nodejs.org diff --git a/docs/web-testing-library/intro.mdx b/docs/web-testing-library/intro.mdx new file mode 100644 index 000000000..2232e2cf6 --- /dev/null +++ b/docs/web-testing-library/intro.mdx @@ -0,0 +1,49 @@ +--- +id: intro +title: Introduction +--- + +## The problem + +You want to write maintainable tests for the +[Web Platform](https://proposal-common-min-api.deno.dev/) or React Native. 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 the Web Platform (a browser, [Node.js][node], [Deno](https://deno.land/) +etc) or React Native. 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. + +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 both the Web Platform **and** React Native +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/ diff --git a/sidebars.js b/sidebars.js index 1aecc0e0d..08dd3b8fb 100755 --- a/sidebars.js +++ b/sidebars.js @@ -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', From b3f6023ddc2d1526a380eaf375c8a07fcd06fb98 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 7 Feb 2023 17:49:59 +0100 Subject: [PATCH 2/8] Update wording to use "web-interop" instead of "web platform" --- docs/web-testing-library/intro.mdx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/web-testing-library/intro.mdx b/docs/web-testing-library/intro.mdx index 2232e2cf6..3498db559 100644 --- a/docs/web-testing-library/intro.mdx +++ b/docs/web-testing-library/intro.mdx @@ -5,23 +5,20 @@ title: Introduction ## The problem -You want to write maintainable tests for the -[Web Platform](https://proposal-common-min-api.deno.dev/) or React Native. 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. +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 the Web Platform (a browser, [Node.js][node], [Deno](https://deno.land/) -etc) or React Native. 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: +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. @@ -32,7 +29,7 @@ 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 both the Web Platform **and** React Native +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 @@ -47,3 +44,6 @@ principles: [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/ From c25b253cf23ea035c197a887419584cb3585c9f0 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 7 Feb 2023 17:53:05 +0100 Subject: [PATCH 3/8] No more container in `waitFor` --- docs/web-testing-library/api.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/web-testing-library/api.mdx b/docs/web-testing-library/api.mdx index ed6ec4d9a..4e19e5863 100644 --- a/docs/web-testing-library/api.mdx +++ b/docs/web-testing-library/api.mdx @@ -52,6 +52,5 @@ before starting the intervals. The default `timeout` is `1000ms`. -The default `onTimeout` takes the error and appends the `container`'s printed -state to the error message which should hopefully make it easier to track down -what caused the timeout. +The default `onTimeout` receives the error which should hopefully make it easier +to track down what caused the timeout. From 22dd1f0b12e77bda1d8612d0fe191b40700be09f Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 9 Feb 2023 12:32:43 +0100 Subject: [PATCH 4/8] Final API --- docs/web-testing-library/api.mdx | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/web-testing-library/api.mdx b/docs/web-testing-library/api.mdx index 4e19e5863..d5bab27dd 100644 --- a/docs/web-testing-library/api.mdx +++ b/docs/web-testing-library/api.mdx @@ -17,9 +17,11 @@ calling them. function waitFor( callback: () => T | Promise, options?: { - timeout?: number interval?: number onTimeout?: (error: Error) => Error + showOriginalStackTrace?: boolean + signal?: AbortSignal + timeout?: number }, ): Promise ``` @@ -47,10 +49,26 @@ implicitly with `async` syntax), then the `waitFor` utility will 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 will run your callback immediately -before starting the intervals. +The default `interval` is `50ms`. However, it runs your callback +immediatelybefore starting the intervals. -The default `timeout` is `1000ms`. +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. -The default `onTimeout` receives the error which should hopefully make it easier -to track down what caused the timeout. +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`. From 1d56515bc91b5a79d1cbb60dbf26bedff67af5bc Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 9 Feb 2023 12:38:47 +0100 Subject: [PATCH 5/8] f wording --- docs/web-testing-library/faq.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/web-testing-library/faq.mdx b/docs/web-testing-library/faq.mdx index d738a21ed..d7704c569 100644 --- a/docs/web-testing-library/faq.mdx +++ b/docs/web-testing-library/faq.mdx @@ -7,12 +7,11 @@ title: FAQ Why "Web" in "Web Testing Library -This library implements testing utilities that are used on different clients +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 and React Native. - -React Native is included for pragmatic reasons. In the future, we might split -the utilities up in Web and Timer testing utilities. +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). From 591f9cb3c55770f2c36a3ad3f2da11022c2c2d56 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 9 Feb 2023 12:41:36 +0100 Subject: [PATCH 6/8] Apply suggestions Co-authored-by: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> --- docs/web-testing-library/api.mdx | 6 +++--- docs/web-testing-library/install.mdx | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/web-testing-library/api.mdx b/docs/web-testing-library/api.mdx index d5bab27dd..c4e0357d6 100644 --- a/docs/web-testing-library/api.mdx +++ b/docs/web-testing-library/api.mdx @@ -45,9 +45,9 @@ 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 `async` syntax), then the `waitFor` utility will not call your -callback again until that promise rejects. This allows you to `waitFor` things -that must be checked asynchronously. +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 immediatelybefore starting the intervals. diff --git a/docs/web-testing-library/install.mdx b/docs/web-testing-library/install.mdx index e58f09a32..c3743e814 100644 --- a/docs/web-testing-library/install.mdx +++ b/docs/web-testing-library/install.mdx @@ -77,4 +77,3 @@ Links --> [npm]: https://www.npmjs.com/ -[node]: https://nodejs.org From 4c384c95a79b9433cf35a3531e977fe47d87bc74 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Sat, 11 Feb 2023 14:57:14 +0100 Subject: [PATCH 7/8] Update docs/web-testing-library/api.mdx Co-authored-by: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> --- docs/web-testing-library/api.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-testing-library/api.mdx b/docs/web-testing-library/api.mdx index c4e0357d6..30dd297d3 100644 --- a/docs/web-testing-library/api.mdx +++ b/docs/web-testing-library/api.mdx @@ -50,7 +50,7 @@ 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 -immediatelybefore starting the intervals. +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 From 2c1e259a01ba4987f9e41e4a8a8d142fe1cdd3e4 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Sat, 11 Feb 2023 15:00:32 +0100 Subject: [PATCH 8/8] Add name motivation --- docs/web-testing-library/faq.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/web-testing-library/faq.mdx b/docs/web-testing-library/faq.mdx index d7704c569..f1b955e4c 100644 --- a/docs/web-testing-library/faq.mdx +++ b/docs/web-testing-library/faq.mdx @@ -12,6 +12,7 @@ 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). +contains known runtimes). The name is born out of pragmatism. A more precise +name would be "Web-interoperable runtimes Testing Library".