From dcf41dbd4cd6f0b181125d6b33f331c01ab50700 Mon Sep 17 00:00:00 2001 From: Alex Krolick Date: Tue, 12 Jan 2021 18:46:27 -0800 Subject: [PATCH] docs: reorganize query docs - give queries a top-level nav entry instead of nesting under DOM Testing Library - give each query its own page - reorganize pages like "Which Query" under the new heading - update internal links and redirects --- docs/contributing.mdx | 29 - docs/dom-testing-library/api-async.mdx | 53 +- .../dom-testing-library/api-configuration.mdx | 55 +- docs/dom-testing-library/api-helpers.mdx | 10 +- docs/dom-testing-library/api-queries.mdx | 1112 +-- docs/dom-testing-library/cheatsheet.mdx | 2 +- docs/dom-testing-library/faq.mdx | 2 +- docs/example-findByText.md | 7 +- docs/guide-disappearance.mdx | 19 +- docs/guide-which-query.mdx | 76 - ...imers.mdx => guides-using-fake-timers.mdx} | 0 docs/queries/about.mdx | 418 ++ docs/queries/byalttext.mdx | 70 + docs/queries/bydisplayvalue.mdx | 154 + docs/queries/bylabeltext.mdx | 132 + docs/queries/byplaceholdertext.mdx | 69 + docs/queries/byrole.mdx | 293 + docs/queries/bytestid.mdx | 83 + docs/queries/bytext.mdx | 90 + docs/queries/bytitle.mdx | 72 + docs/react-testing-library/api.mdx | 5 +- docs/react-testing-library/cheatsheet.mdx | 2 +- docs/react-testing-library/faq.mdx | 2 - .../migrate-from-enzyme.mdx | 3 +- docs/recipes.mdx | 5 +- docs/testcafe-testing-library/intro.mdx | 2 +- docs/vue-testing-library/cheatsheet.mdx | 3 +- docusaurus.config.js | 12 +- netlify.toml | 8 +- sidebars.js | 80 +- src/pages/help.js | 19 +- src/pages/index.js | 22 +- website/i18n/en.json | 157 + website/yarn.lock | 6545 +++++++++++++++++ 34 files changed, 8286 insertions(+), 1325 deletions(-) delete mode 100644 docs/guide-which-query.mdx rename docs/{using-fake-timers.mdx => guides-using-fake-timers.mdx} (100%) create mode 100644 docs/queries/about.mdx create mode 100644 docs/queries/byalttext.mdx create mode 100644 docs/queries/bydisplayvalue.mdx create mode 100644 docs/queries/bylabeltext.mdx create mode 100644 docs/queries/byplaceholdertext.mdx create mode 100644 docs/queries/byrole.mdx create mode 100644 docs/queries/bytestid.mdx create mode 100644 docs/queries/bytext.mdx create mode 100644 docs/queries/bytitle.mdx create mode 100644 website/i18n/en.json create mode 100644 website/yarn.lock diff --git a/docs/contributing.mdx b/docs/contributing.mdx index 65791f758..619c6149c 100644 --- a/docs/contributing.mdx +++ b/docs/contributing.mdx @@ -40,35 +40,6 @@ Links: -[npm]: https://www.npmjs.com/ -[node]: https://nodejs.org -[build-badge]: https://img.shields.io/travis/kentcdodds/react-testing-library.svg?style=flat-square -[build]: https://travis-ci.org/kentcdodds/react-testing-library -[coverage-badge]: https://img.shields.io/codecov/c/github/kentcdodds/react-testing-library.svg?style=flat-square -[coverage]: https://codecov.io/github/kentcdodds/react-testing-library -[version-badge]: https://img.shields.io/npm/v/react-testing-library.svg?style=flat-square -[package]: https://www.npmjs.com/package/react-testing-library -[downloads-badge]: https://img.shields.io/npm/dm/react-testing-library.svg?style=flat-square -[npmtrends]: http://www.npmtrends.com/react-testing-library -[license-badge]: https://img.shields.io/npm/l/react-testing-library.svg?style=flat-square -[license]: https://github.com/testing-library/react-testing-library/blob/master/LICENSE -[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square -[prs]: http://makeapullrequest.com -[donate-badge]: https://img.shields.io/badge/$-support-green.svg?style=flat-square -[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square -[coc]: https://github.com/testing-library/react-testing-library/blob/master/CODE_OF_CONDUCT.md -[github-watch-badge]: https://img.shields.io/github/watchers/kentcdodds/react-testing-library.svg?style=social -[github-watch]: https://github.com/testing-library/react-testing-library/watchers -[github-star-badge]: https://img.shields.io/github/stars/kentcdodds/react-testing-library.svg?style=social -[github-star]: https://github.com/testing-library/react-testing-library/stargazers -[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20react-testing-library%20by%20%40kentcdodds%20https%3A%2F%2Fgithub.com%2Fkentcdodds%2Freact-testing-library%20%F0%9F%91%8D -[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/testing-library/react-testing-library.svg?style=social -[emojis]: https://github.com/kentcdodds/all-contributors#emoji-key -[all-contributors]: https://github.com/kentcdodds/all-contributors -[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 -[dom-testing-lib-textmatch]: https://github.com/testing-library/dom-testing-library#textmatch [bugs]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Acreated-desc [requests]: https://github.com/testing-library/react-testing-library/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3Aenhancement+is%3Aopen [good-first-issue]: https://github.com/testing-library/react-testing-library/issues?utf8=✓&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3A"good+first+issue"+ diff --git a/docs/dom-testing-library/api-async.mdx b/docs/dom-testing-library/api-async.mdx index 71be357a1..a1ff88831 100644 --- a/docs/dom-testing-library/api-async.mdx +++ b/docs/dom-testing-library/api-async.mdx @@ -1,13 +1,33 @@ --- id: api-async -title: Async Utilities +title: Async Methods --- 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 action. -(See the [guide to testing disappearance](guide-disappearance.mdx).) +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).) -All the async utils are built on top of `waitFor`. +The async methods return Promises, so be sure to use `await` or `.then` when +calling them. + +## `findBy` Queries + +`findBy` methods are a combination of `getBy` +[queries](queries/about.mdx#types-of-queries) and [`waitFor`](#waitfor). They +accept the waitFor options as the last argument (i.e. +`await screen.findByText('text', queryOptions, waitForOptions)`). + +`findBy` queries work when you expect an element to appear but the change to the +DOM might not happen immediately. + +```js +const button = screen.getByRole('button', { name: 'Click Me' }) +fireEvent.click(button) +await screen.findByText('Clicked once') +fireEvent.click(button) +await screen.findByText('Clicked twice') +``` ## `waitFor` @@ -122,7 +142,20 @@ waitForElementToBeRemoved(() => getByText(/not here/i)).catch((err) => The options object is forwarded to `waitFor`. -## `wait` (DEPRECATED, use waitFor instead) +## Deprecated Methods + +`wait`, `waitForDomChange`, and `waitForElement` have been combined into the +`waitFor` method + +
+ +
+ +Deprecated Methods + +### `wait` + +> (DEPRECATED, use waitFor instead) ```typescript function wait( @@ -144,7 +177,9 @@ Unlike wait, the callback parameter is mandatory in waitFor. Although you can migrate an existing `wait()` call to `waitFor( () => {} )`, it is considered bad practice to use an empty callback because it will make the tests more fragile. -## `waitForDomChange` (DEPRECATED, use waitFor instead) +### `waitForDomChange` + +> (DEPRECATED, use waitFor instead) ```typescript function waitForDomChange(options?: { @@ -205,7 +240,9 @@ will detect additions and removals of child elements (including text nodes) in the `container` and any of its descendants. It will also detect attribute changes. -## `waitForElement` (DEPRECATED, use `find*` queries or `waitFor`) +### `waitForElement` + +> (DEPRECATED, use `find*` queries or `waitFor`) ```typescript function waitForElement( @@ -263,3 +300,5 @@ The default `mutationObserverOptions` is will detect additions and removals of child elements (including text nodes) in the `container` and any of its descendants. It will also detect attribute changes. + +
diff --git a/docs/dom-testing-library/api-configuration.mdx b/docs/dom-testing-library/api-configuration.mdx index 57d02abb4..0e1a561c7 100644 --- a/docs/dom-testing-library/api-configuration.mdx +++ b/docs/dom-testing-library/api-configuration.mdx @@ -61,31 +61,35 @@ configure({ testIdAttribute: 'data-my-test-id' }) ## Configuration options: ### `computedStyleSupportsPseudoElements` -Set to `true` if `window.getComputedStyle` supports pseudo-elements i.e. a second argument. If -you're using testing-library in a browser you almost always want to set this to -`true`. Only very old browser don't support this property (such as IE 8 and -earlier). However, `jsdom` does not support the second argument currently. This -includes versions of `jsdom` prior to `16.4.0` and any version that logs a -`not implemented` warning when calling `getComputedStyle` with a second argument -e.g. `window.getComputedStyle(document.createElement('div'), '::after')`. -Defaults to `false` + +Set to `true` if `window.getComputedStyle` supports pseudo-elements i.e. a +second argument. If you're using testing-library in a browser you almost always +want to set this to `true`. Only very old browser don't support this property +(such as IE 8 and earlier). However, `jsdom` does not support the second +argument currently. This includes versions of `jsdom` prior to `16.4.0` and any +version that logs a `not implemented` warning when calling `getComputedStyle` +with a second argument e.g. +`window.getComputedStyle(document.createElement('div'), '::after')`. Defaults to +`false` ### `defaultHidden` + The default value for the `hidden` option used by [`getByRole`](api-queries.mdx#byrole). Defaults to `false`. ### `showOriginalStackTrace` -By default, `waitFor` will ensure that the stack trace -for errors thrown by Testing Library is cleaned up and shortened so it's easier -for you to identify the part of your code that resulted in the error (async -stack traces are hard to debug). If you want to disable this, then -set`showOriginalStackTrace` to `false`. You can also disable this for a specific -call in the options you pass to `waitFor`. + +By default, `waitFor` will ensure that the stack trace for errors thrown by +Testing Library is cleaned up and shortened so it's easier for you to identify +the part of your code that resulted in the error (async stack traces are hard to +debug). If you want to disable this, then set`showOriginalStackTrace` to +`false`. You can also disable this for a specific call in the options you pass +to `waitFor`. ### `throwSuggestions` (experimental) -When enabled, if [better queries](https://testing-library.com/docs/guide-which-query) are -available the test will fail and provide a suggested query to use instead. -Default to `false`. + +When enabled, if [better queries](queries/about.mdx#priority) are available the +test will fail and provide a suggested query to use instead. Default to `false`. To disable a suggestion for a single query just add `{suggest:false}` as an option. @@ -95,14 +99,17 @@ screen.getByTestId('foo', { suggest: false }) // will not throw a suggestion ``` ### `testIdAttribute` -The attribute used by [`getByTestId`](api-queries.mdx#bytestid) and related queries. Defaults to -`data-testid`. + +The attribute used by [`getByTestId`](api-queries.mdx#bytestid) and related +queries. Defaults to `data-testid`. ### `getElementError` -A function that returns the error used when -[`getBy*`](api-queries.mdx#getby) or [`getAllBy*`](api-queries.mdx#getallby) -fail. Takes the error message and container object as arguments. + +A function that returns the error used when [`getBy*`](api-queries.mdx#getby) or +[`getAllBy*`](api-queries.mdx#getallby) fail. Takes the error message and +container object as arguments. ### `asyncUtilTimeout` -The global timeout value in milliseconds used by `waitFor` -utilities. Defaults to 1000ms. + +The global timeout value in milliseconds used by `waitFor` utilities. Defaults +to 1000ms. diff --git a/docs/dom-testing-library/api-helpers.mdx b/docs/dom-testing-library/api-helpers.mdx index c749d1c3e..c6e7a7e17 100644 --- a/docs/dom-testing-library/api-helpers.mdx +++ b/docs/dom-testing-library/api-helpers.mdx @@ -140,8 +140,8 @@ could do: ```js import { within } from '@testing-library/dom' -const { getByText } = within(document.getElementById('messages')) -const helloMessage = getByText('hello') +const messages = document.getElementById('messages') +const helloMessage = within(messages).getByText('hello') ``` @@ -167,7 +167,9 @@ cy.get('form').within(() => { -## `getRoles` +## Accessibility + +### `getRoles` This function allows iteration over the implicit ARIA roles represented in a given tree of DOM nodes. @@ -197,7 +199,7 @@ console.log(getRoles(nav)) // } ``` -## `isInaccessible` +### `isInaccessible` This function will compute if the given element should be excluded from the accessibility API by the browser. It implements every **MUST** criteria from the diff --git a/docs/dom-testing-library/api-queries.mdx b/docs/dom-testing-library/api-queries.mdx index f718ccdd3..76b3b6973 100644 --- a/docs/dom-testing-library/api-queries.mdx +++ b/docs/dom-testing-library/api-queries.mdx @@ -3,1114 +3,4 @@ id: api-queries title: Queries --- -import Tabs from '@theme/Tabs' -import TabItem from '@theme/TabItem' - -## Variants - -> `getBy` queries are shown by default in the [query documentation](#queries) -> below. - -### getBy - -`getBy*` queries return the matching node for a query, and throw an error if no -elements match or if more than one match is found (use `getAllBy` instead). - -### getAllBy - -`getAllBy*` queries return an array of all matching nodes for a query, and throw -an error if no elements match. - -### queryBy - -`queryBy*` queries return the first matching node for a query, and return `null` -if no elements match. This is useful for asserting an element that is not -present. This throws an error if more than one match is found (use `queryAllBy` -instead). - -### queryAllBy - -`queryAllBy*` queries return an array of all matching nodes for a query, and -return an empty array (`[]`) if no elements match. - -### findBy - -`findBy*` queries return a promise which resolves when an element is found which -matches the given query. The promise is rejected if no element is found or if -more than one element is found after a default timeout of `1000`ms. If you need -to find more than one element, then use `findAllBy`. - -> **Note** -> -> this is a simple combination of `getBy*` queries and -> [`waitFor`](api-async.mdx#waitfor). The `findBy*` queries accept the `waitFor` -> options as the last argument. (i.e. -> `screen.findByText('text', queryOptions, waitForOptions)`) - -### findAllBy - -`findAllBy*` queries return a promise which resolves to an array of elements -when any elements are found which match the given query. The promise is rejected -if no elements are found after a default timeout of `1000`ms. - -## Options - -The argument to a query can be a _string_, _regular expression_, or _function_. -There are also options to adjust how node text is parsed. - -See [TextMatch](#textmatch) for documentation on what can be passed to a query. - -## `screen` - -All of the queries exported by DOM Testing Library accept a `container` as the -first argument. Because querying the entire `document.body` is very common, DOM -Testing Library also exports a `screen` object which has every query that is -pre-bound to `document.body` (using the -[`within`](/docs/dom-testing-library/api-helpers#within-and-getqueriesforelement-apis) -functionality). - -Here's how you use it: - -```javascript -import { screen } from '@testing-library/dom' -// NOTE: many framework-implementations of Testing Library -// re-export everything from `@testing-library/dom` so you -// may be able to import screen from your framework-implementation: -// import {render, screen} from '@testing-library/react' - -const exampleHTML = ` - - -` -document.body.innerHTML = exampleHTML -const exampleInput = screen.getByLabelText(/example/i) -``` - -> **Note** -> -> You need a global DOM environment to use `screen`. If you're using jest, with -> the -> [testEnvironment](https://jestjs.io/docs/en/configuration#testenvironment-string) -> set to `jsdom`, a global DOM environment will be available for you. -> -> If you're loading your test with a `script` tag, make sure it comes after the -> `body`. An example can be seen -> [here](https://github.com/testing-library/dom-testing-library/issues/700#issuecomment-692218886). - -### `screen.debug` - -For convenience screen also exposes a `debug` method in addition to the queries. -This method is essentially a shortcut for `console.log(prettyDOM())`. It -supports debugging the document, a single element, or an array of elements. - -```javascript -import { screen } from '@testing-library/dom' - -document.body.innerHTML = ` - - multi-test -
multi-test
-` - -// debug document -screen.debug() -// debug single element -screen.debug(screen.getByText('test')) -// debug multiple elements -screen.debug(screen.getAllByText('multi-test')) -``` - -### `screen.logTestingPlaygroundURL` - -For debugging using [testing-playground](https://testing-playground.com), screen -exposes this convenient method which logs a URL that can be opened in a browser. - -```javascript -import { screen } from '@testing-library/dom' - -document.body.innerHTML = ` - - multi-test -
multi-test
-` - -// log entire document to testing-playground -screen.logTestingPlaygroundURL() -// log a single element -screen.logTestingPlaygroundURL(screen.getByText('test')) -``` - -## Queries - -> **Note** -> -> These queries are the base queries and require you to pass a `container` as -> the first argument. Most framework-implementations of Testing Library provide -> a pre-bound version of these queries when you render your components with them -> which means you do not have to provide a container. In addition, if you just -> want to query `document.body` then you can use the [`screen`](#screen) export -> as demonstrated above (using `screen` is recommended). - -### `ByLabelText` - -> getByLabelText, queryByLabelText, getAllByLabelText, queryAllByLabelText, -> findByLabelText, findAllByLabelText - -```typescript -getByLabelText( - container: HTMLElement, // if you're using `screen`, then skip this argument - text: TextMatch, - options?: { - selector?: string = '*', - exact?: boolean = true, - normalizer?: NormalizerFn, - }): HTMLElement -``` - -This will search for the label that matches the given [`TextMatch`](#textmatch), -then find the element associated with that label. - -The example below will find the input node for the following DOM structures: - -```js -// for/htmlFor relationship between label and form element id - - - -// The aria-labelledby attribute with form elements - - - -// Wrapper labels - - -// Wrapper labels where the label text is in another child element - - -// aria-label attributes -// Take care because this is not a label that users can see on the page, -// so the purpose of your input must be obvious to visual users. - -``` - - - - -```js -import { screen } from '@testing-library/dom' - -const inputNode = screen.getByLabelText('Username') -``` - - - - -```jsx -import { render, screen } from '@testing-library/react' - -render() - -const inputNode = screen.getByLabelText('username') -``` - - - - -```js -cy.findByLabelText('username').should('exist') -``` - - - - -It will NOT find the input node for label text broken up by elements. You can -use `getByRole('textbox', { name: 'Username' })` instead which is robust against -switching to `aria-label` or `aria-labelledby`. - -If it is important that you query an actual `