diff --git a/.all-contributorsrc b/.all-contributorsrc index 89091cb7..df9690ed 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1261,6 +1261,52 @@ "contributions": [ "code" ] + }, + { + "login": "anpaopao", + "name": "Angus J. Pope", + "avatar_url": "https://avatars.githubusercontent.com/u/44686792?v=4", + "profile": "https://github.com/anpaopao", + "contributions": [ + "doc" + ] + }, + { + "login": "leschdom", + "name": "Dominik Lesch", + "avatar_url": "https://avatars.githubusercontent.com/u/62334278?v=4", + "profile": "https://github.com/leschdom", + "contributions": [ + "doc" + ] + }, + { + "login": "ImADrafter", + "name": "Marcos Gรณmez", + "avatar_url": "https://avatars.githubusercontent.com/u/44379989?v=4", + "profile": "https://github.com/ImADrafter", + "contributions": [ + "doc" + ] + }, + { + "login": "akashshyamdev", + "name": "Akash Shyam", + "avatar_url": "https://avatars.githubusercontent.com/u/56759828?v=4", + "profile": "https://www.akashshyam.online/", + "contributions": [ + "bug" + ] + }, + { + "login": "fmeum", + "name": "Fabian Meumertzheim", + "avatar_url": "https://avatars.githubusercontent.com/u/4312191?v=4", + "profile": "https://hen.ne.ke", + "contributions": [ + "code", + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index f9286936..bf3237bb 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -1,3 +1,5 @@ { - "sandboxes": ["new", "github/kentcdodds/react-testing-library-examples"] + "installCommand": "install:csb", + "sandboxes": ["new", "github/kentcdodds/react-testing-library-examples"], + "node": "12" } diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 371a86f6..f5000e21 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -37,7 +37,7 @@ merge of your pull request! - [ ] Documentation added to the [docs site](https://github.com/testing-library/testing-library-docs) - [ ] Tests -- [ ] Typescript definitions updated +- [ ] TypeScript definitions updated - [ ] Ready to be merged diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index dc793472..b2e7dc4c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -2,7 +2,9 @@ name: validate on: push: branches: - - '+([0-9])?(.{+([0-9]),x}).x' + # Match SemVer major release branches + # e.g. "12.x" or "8.x" + - '[0-9]+.x' - 'main' - 'next' - 'next-major' @@ -17,7 +19,8 @@ jobs: if: ${{ !contains(github.head_ref, 'all-contributors') }} strategy: matrix: - node: [10.13, 12, 14, 15, 16] + # TODO: relax `'16.9.1'` to `16` once GitHub has 16.9.1 cached. 16.9.0 is broken due to https://github.com/nodejs/node/issues/40030 + node: [12, 14, '16.9.1'] react: [latest, next, experimental] runs-on: ubuntu-latest steps: @@ -37,6 +40,10 @@ jobs: with: useLockFile: false + # TODO: Can be removed if https://github.com/kentcdodds/kcd-scripts/pull/146 is released + - name: Verify format (`npm run format` committed?) + run: npm run format -- --check --no-write + # as requested by the React team :) # https://reactjs.org/blog/2019/10/22/react-release-channels.html#using-the-next-channel-for-integration-testing - name: โš›๏ธ Setup react @@ -53,8 +60,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository == 'testing-library/react-testing-library' && - contains('refs/heads/main,refs/heads/beta,refs/heads/next,refs/heads/alpha', - github.ref) && github.event_name == 'push' }} + github.event_name == 'push' }} steps: - name: ๐Ÿ›‘ Cancel Previous Runs uses: styfle/cancel-workflow-action@0.9.0 diff --git a/.npmrc b/.npmrc index d2722898..1df2a6d8 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ -registry=http://registry.npmjs.org/ +registry=https://registry.npmjs.org/ package-lock=false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5876fb3..e16e9d61 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,11 +35,11 @@ sure to include those changes (if they exist) in your commit. ### Update Typings If your PR introduced some changes in the API, you are more than welcome to -modify the Typescript type definition to reflect those changes. Just modify the -`/types/index.d.ts` file accordingly. If you have never seen Typescript +modify the TypeScript type definition to reflect those changes. Just modify the +`/types/index.d.ts` file accordingly. If you have never seen TypeScript definitions before, you can read more about it in its [documentation pages](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html). -Though this library itself is not written in Typescript we use +Though this library itself is not written in TypeScript we use [dtslint](https://github.com/microsoft/dtslint) to lint our typings. ## Help needed @@ -50,6 +50,5 @@ Also, please watch the repo and respond to questions/bug reports/feature requests! Thanks! [egghead]: - https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github -[all-contributors]: https://github.com/all-contributors/all-contributors + https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github [issues]: https://github.com/testing-library/react-testing-library/issues diff --git a/README.md b/README.md index 80d7ad9e..0bc06ceb 100644 --- a/README.md +++ b/README.md @@ -608,6 +608,13 @@ Thanks goes to these people ([emoji key][emojis]):
Solufa

๐Ÿ› ๐Ÿ’ป
Ari Perkkiรถ

โš ๏ธ
Johannes Ewald

๐Ÿ’ป +
Angus J. Pope

๐Ÿ“– +
Dominik Lesch

๐Ÿ“– + + +
Marcos Gรณmez

๐Ÿ“– +
Akash Shyam

๐Ÿ› +
Fabian Meumertzheim

๐Ÿ’ป ๐Ÿ› diff --git a/package.json b/package.json index fde78a35..47b5ad06 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "types": "types/index.d.ts", "module": "dist/@testing-library/react.esm.js", "engines": { - "node": ">=10" + "node": ">=12" }, "scripts": { "prebuild": "rimraf dist", @@ -14,6 +14,8 @@ "build:bundle:main": "dotenv -e .bundle.main.env kcd-scripts build -- --bundle --no-clean", "build:bundle:pure": "dotenv -e .bundle.main.env -e .bundle.pure.env kcd-scripts build -- --bundle --no-clean", "build:main": "kcd-scripts build --no-clean", + "format": "kcd-scripts format", + "install:csb": "npm install", "lint": "kcd-scripts lint", "setup": "npm install && npm run validate -s", "test": "kcd-scripts test", @@ -44,13 +46,13 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^7.28.1" + "@testing-library/dom": "^8.0.0", + "@types/react-dom": "<18.0.0" }, "devDependencies": { "@testing-library/jest-dom": "^5.11.6", - "@types/react-dom": "^17.0.0", "dotenv-cli": "^4.0.0", - "kcd-scripts": "^7.5.1", + "kcd-scripts": "^11.1.0", "npm-run-all": "^4.1.5", "react": "^17.0.1", "react-dom": "^17.0.1", @@ -58,8 +60,8 @@ "typescript": "^4.1.2" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "react": "<18.0.0", + "react-dom": "<18.0.0" }, "eslintConfig": { "extends": "./node_modules/kcd-scripts/eslint.js", @@ -68,7 +70,10 @@ "react/no-adjacent-inline-elements": "off", "import/no-unassigned-import": "off", "import/named": "off", - "testing-library/no-dom-import": "off" + "testing-library/no-container": "off", + "testing-library/no-dom-import": "off", + "testing-library/no-unnecessary-act": "off", + "testing-library/prefer-user-event": "off" } }, "eslintIgnore": [ diff --git a/src/__tests__/cleanup.js b/src/__tests__/cleanup.js index 6043ae06..9d3f52d4 100644 --- a/src/__tests__/cleanup.js +++ b/src/__tests__/cleanup.js @@ -54,15 +54,16 @@ describe('fake timers and missing act warnings', () => { jest.useRealTimers() }) - test('cleanup does not flush immediates', () => { + test('cleanup does not flush microtasks', () => { const microTaskSpy = jest.fn() function Test() { const counter = 1 const [, setDeferredCounter] = React.useState(null) React.useEffect(() => { let cancelled = false - setImmediate(() => { + Promise.resolve().then(() => { microTaskSpy() + // eslint-disable-next-line jest/no-if -- false positive if (!cancelled) { setDeferredCounter(counter) } @@ -82,7 +83,10 @@ describe('fake timers and missing act warnings', () => { expect(microTaskSpy).toHaveBeenCalledTimes(0) // console.error is mocked // eslint-disable-next-line no-console - expect(console.error).toHaveBeenCalledTimes(0) + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 1 : 0, + ) }) test('cleanup does not swallow missing act warnings', () => { @@ -92,12 +96,12 @@ describe('fake timers and missing act warnings', () => { const [, setDeferredCounter] = React.useState(null) React.useEffect(() => { let cancelled = false - setImmediate(() => { + setTimeout(() => { deferredStateUpdateSpy() if (!cancelled) { setDeferredCounter(counter) } - }) + }, 0) return () => { cancelled = true @@ -108,16 +112,22 @@ describe('fake timers and missing act warnings', () => { } render() - jest.runAllImmediates() + jest.runAllTimers() cleanup() expect(deferredStateUpdateSpy).toHaveBeenCalledTimes(1) // console.error is mocked // eslint-disable-next-line no-console - expect(console.error).toHaveBeenCalledTimes(1) - // eslint-disable-next-line no-console - expect(console.error.mock.calls[0][0]).toMatch( - 'a test was not wrapped in act(...)', + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 2 : 1, ) + // eslint-disable-next-line no-console + expect( + console.error.mock.calls[ + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 1 : 0 + ][0], + ).toMatch('a test was not wrapped in act(...)') }) }) diff --git a/src/__tests__/debug.js b/src/__tests__/debug.js index e4e9faa0..f3aad595 100644 --- a/src/__tests__/debug.js +++ b/src/__tests__/debug.js @@ -43,8 +43,8 @@ test('allows same arguments as prettyDOM', () => { expect(console.log).toHaveBeenCalledTimes(1) expect(console.log.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "
- ...", +
+ ..., ] `) }) diff --git a/src/__tests__/end-to-end.js b/src/__tests__/end-to-end.js index 87c70f1b..cf222aec 100644 --- a/src/__tests__/end-to-end.js +++ b/src/__tests__/end-to-end.js @@ -1,5 +1,5 @@ import * as React from 'react' -import {render, waitForElementToBeRemoved, screen} from '../' +import {render, waitForElementToBeRemoved, screen, waitFor} from '../' const fetchAMessage = () => new Promise(resolve => { @@ -11,27 +11,63 @@ const fetchAMessage = () => }, randomTimeout) }) -class ComponentWithLoader extends React.Component { - state = {loading: true} - async componentDidMount() { - const data = await fetchAMessage() - this.setState({data, loading: false}) // eslint-disable-line - } - render() { - if (this.state.loading) { - return
Loading...
+function ComponentWithLoader() { + const [state, setState] = React.useState({data: undefined, loading: true}) + React.useEffect(() => { + let cancelled = false + fetchAMessage().then(data => { + if (!cancelled) { + setState({data, loading: false}) + } + }) + + return () => { + cancelled = true } - return ( -
- Loaded this message: {this.state.data.returnedMessage}! -
- ) + }, []) + + if (state.loading) { + return
Loading...
} + + return ( +
+ Loaded this message: {state.data.returnedMessage}! +
+ ) } -test('it waits for the data to be loaded', async () => { - render() - const loading = () => screen.getByText('Loading...') - await waitForElementToBeRemoved(loading) - expect(screen.getByTestId('message')).toHaveTextContent(/Hello World/) +describe.each([ + ['real timers', () => jest.useRealTimers()], + ['fake legacy timers', () => jest.useFakeTimers('legacy')], + ['fake modern timers', () => jest.useFakeTimers('modern')], +])('it waits for the data to be loaded using %s', (label, useTimers) => { + beforeEach(() => { + useTimers() + }) + + afterEach(() => { + jest.useRealTimers() + }) + + test('waitForElementToBeRemoved', async () => { + render() + const loading = () => screen.getByText('Loading...') + await waitForElementToBeRemoved(loading) + expect(screen.getByTestId('message')).toHaveTextContent(/Hello World/) + }) + + test('waitFor', async () => { + render() + const message = () => screen.getByText(/Loaded this message:/) + await waitFor(message) + expect(screen.getByTestId('message')).toHaveTextContent(/Hello World/) + }) + + test('findBy', async () => { + render() + await expect(screen.findByTestId('message')).resolves.toHaveTextContent( + /Hello World/, + ) + }) }) diff --git a/src/__tests__/new-act.js b/src/__tests__/new-act.js index 56ce4970..af81e29c 100644 --- a/src/__tests__/new-act.js +++ b/src/__tests__/new-act.js @@ -1,4 +1,4 @@ -let asyncAct +let asyncAct, consoleErrorMock jest.mock('react-dom/test-utils', () => ({ act: cb => { @@ -9,11 +9,11 @@ jest.mock('react-dom/test-utils', () => ({ beforeEach(() => { jest.resetModules() asyncAct = require('../act-compat').asyncAct - jest.spyOn(console, 'error').mockImplementation(() => {}) + consoleErrorMock = jest.spyOn(console, 'error').mockImplementation(() => {}) }) afterEach(() => { - console.error.mockRestore() + consoleErrorMock.mockRestore() }) test('async act works when it does not exist (older versions of react)', async () => { @@ -49,7 +49,7 @@ test('async act recovers from errors', async () => { expect(console.error.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "call console.error", + call console.error, ], ] `) @@ -67,7 +67,7 @@ test('async act recovers from sync errors', async () => { expect(console.error.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "call console.error", + call console.error, ], ] `) diff --git a/src/__tests__/no-act.js b/src/__tests__/no-act.js index 039a79ae..d739e763 100644 --- a/src/__tests__/no-act.js +++ b/src/__tests__/no-act.js @@ -1,14 +1,15 @@ -let act, asyncAct +let act, asyncAct, React, consoleErrorMock beforeEach(() => { jest.resetModules() - act = require('..').act + act = require('../pure').act asyncAct = require('../act-compat').asyncAct - jest.spyOn(console, 'error').mockImplementation(() => {}) + React = require('react') + consoleErrorMock = jest.spyOn(console, 'error').mockImplementation(() => {}) }) afterEach(() => { - console.error.mockRestore() + consoleErrorMock.mockRestore() }) jest.mock('react-dom/test-utils', () => ({})) @@ -17,7 +18,10 @@ test('act works even when there is no act from test utils', () => { const callback = jest.fn() act(callback) expect(callback).toHaveBeenCalledTimes(1) - expect(console.error).toHaveBeenCalledTimes(0) + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 1 : 0, + ) }) test('async act works when it does not exist (older versions of react)', async () => { @@ -26,7 +30,10 @@ test('async act works when it does not exist (older versions of react)', async ( await Promise.resolve() await callback() }) - expect(console.error).toHaveBeenCalledTimes(0) + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 2 : 0, + ) expect(callback).toHaveBeenCalledTimes(1) callback.mockClear() @@ -36,7 +43,10 @@ test('async act works when it does not exist (older versions of react)', async ( await Promise.resolve() await callback() }) - expect(console.error).toHaveBeenCalledTimes(0) + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 2 : 0, + ) expect(callback).toHaveBeenCalledTimes(1) }) @@ -49,14 +59,16 @@ test('async act recovers from errors', async () => { } catch (err) { console.error('call console.error') } - expect(console.error).toHaveBeenCalledTimes(1) - expect(console.error.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ - "call console.error", - ], - ] - `) + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 2 : 1, + ) + expect( + console.error.mock.calls[ + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 1 : 0 + ][0], + ).toMatch('call console.error') }) test('async act recovers from sync errors', async () => { @@ -71,7 +83,7 @@ test('async act recovers from sync errors', async () => { expect(console.error.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "call console.error", + call console.error, ], ] `) diff --git a/src/__tests__/old-act.js b/src/__tests__/old-act.js index b3de9377..6081fef8 100644 --- a/src/__tests__/old-act.js +++ b/src/__tests__/old-act.js @@ -1,13 +1,13 @@ -let asyncAct +let asyncAct, consoleErrorMock beforeEach(() => { jest.resetModules() asyncAct = require('../act-compat').asyncAct - jest.spyOn(console, 'error').mockImplementation(() => {}) + consoleErrorMock = jest.spyOn(console, 'error').mockImplementation(() => {}) }) afterEach(() => { - console.error.mockRestore() + consoleErrorMock.mockRestore() }) jest.mock('react-dom/test-utils', () => ({ @@ -32,18 +32,18 @@ test('async act works even when the act is an old one', async () => { console.error('sigil') }) expect(console.error.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ - "sigil", - ], - Array [ - "It looks like you're using a version of react-dom that supports the \\"act\\" function, but not an awaitable version of \\"act\\" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning.", - ], - Array [ - "sigil", - ], - ] - `) + Array [ + Array [ + sigil, + ], + Array [ + It looks like you're using a version of react-dom that supports the "act" function, but not an awaitable version of "act" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning., + ], + Array [ + sigil, + ], + ] + `) expect(callback).toHaveBeenCalledTimes(1) // and it doesn't warn you twice @@ -71,10 +71,10 @@ test('async act recovers from async errors', async () => { expect(console.error.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "It looks like you're using a version of react-dom that supports the \\"act\\" function, but not an awaitable version of \\"act\\" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning.", + It looks like you're using a version of react-dom that supports the "act" function, but not an awaitable version of "act" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning., ], Array [ - "call console.error", + call console.error, ], ] `) @@ -92,7 +92,7 @@ test('async act recovers from sync errors', async () => { expect(console.error.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "call console.error", + call console.error, ], ] `) @@ -109,11 +109,11 @@ test('async act can handle any sort of console.error', async () => { Array [ Array [ Object { - "error": "some error", + error: some error, }, ], Array [ - "It looks like you're using a version of react-dom that supports the \\"act\\" function, but not an awaitable version of \\"act\\" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning.", + It looks like you're using a version of react-dom that supports the "act" function, but not an awaitable version of "act" which you will need. Please upgrade to at least react-dom@16.9.0 to remove this warning., ], ] `) diff --git a/src/__tests__/render.js b/src/__tests__/render.js index fdc1ff4c..fea1a649 100644 --- a/src/__tests__/render.js +++ b/src/__tests__/render.js @@ -78,14 +78,14 @@ test('renders options.wrapper around node', () => { expect(screen.getByTestId('wrapper')).toBeInTheDocument() expect(container.firstChild).toMatchInlineSnapshot(` -
-
-
-`) +
+
+
+ `) }) test('flushes useEffect cleanup functions sync on unmount()', () => { diff --git a/src/__tests__/stopwatch.js b/src/__tests__/stopwatch.js index eeaf395c..400fce10 100644 --- a/src/__tests__/stopwatch.js +++ b/src/__tests__/stopwatch.js @@ -53,5 +53,8 @@ test('unmounts a component', async () => { // and get an error. await sleep(5) // eslint-disable-next-line no-console - expect(console.error).not.toHaveBeenCalled() + expect(console.error).toHaveBeenCalledTimes( + // ReactDOM.render is deprecated in React 18 + React.version.startsWith('18') ? 1 : 0, + ) }) diff --git a/src/index.js b/src/index.js index c89dc1a2..96fbe155 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ import {cleanup} from './pure' // this ensures that tests run in isolation from each other // if you don't like this then either import the `pure` module // or set the RTL_SKIP_AUTO_CLEANUP env variable to 'true'. -if (typeof process === "undefined" || !process.env?.RTL_SKIP_AUTO_CLEANUP) { +if (typeof process === 'undefined' || !process.env?.RTL_SKIP_AUTO_CLEANUP) { // ignore teardown() in code coverage because Jest does not support it /* istanbul ignore else */ if (typeof afterEach === 'function') { diff --git a/tests/setup-env.js b/tests/setup-env.js index 264828a9..6c0b953b 100644 --- a/tests/setup-env.js +++ b/tests/setup-env.js @@ -1 +1,20 @@ import '@testing-library/jest-dom/extend-expect' + +let consoleErrorMock + +beforeEach(() => { + const originalConsoleError = console.error + consoleErrorMock = jest + .spyOn(console, 'error') + .mockImplementation((message, ...optionalParams) => { + // Ignore ReactDOM.render/ReactDOM.hydrate deprecation warning + if (message.indexOf('Use createRoot instead.') !== -1) { + return + } + originalConsoleError(message, ...optionalParams) + }) +}) + +afterEach(() => { + consoleErrorMock.mockRestore() +}) diff --git a/types/index.d.ts b/types/index.d.ts index 6d0c67ee..604b3966 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -13,10 +13,11 @@ export * from '@testing-library/dom' export type RenderResult< Q extends Queries = typeof queries, - Container extends Element | DocumentFragment = HTMLElement + Container extends Element | DocumentFragment = HTMLElement, + BaseElement extends Element | DocumentFragment = Container, > = { container: Container - baseElement: Element + baseElement: BaseElement debug: ( baseElement?: | Element @@ -32,13 +33,46 @@ export type RenderResult< export interface RenderOptions< Q extends Queries = typeof queries, - Container extends Element | DocumentFragment = HTMLElement + Container extends Element | DocumentFragment = HTMLElement, + BaseElement extends Element | DocumentFragment = Container, > { + /** + * By default, React Testing Library will create a div and append that div to the document.body. Your React component will be rendered in the created div. If you provide your own HTMLElement container via this option, + * it will not be appended to the document.body automatically. + * + * For example: If you are unit testing a `` element, it cannot be a child of a div. In this case, you can + * specify a table as the render container. + * + * @see https://testing-library.com/docs/react-testing-library/api/#container + */ container?: Container - baseElement?: Element + /** + * Defaults to the container if the container is specified. Otherwise `document.body` is used for the default. This is used as + * the base element for the queries as well as what is printed when you use `debug()`. + * + * @see https://testing-library.com/docs/react-testing-library/api/#baseelement + */ + baseElement?: BaseElement + /** + * If `hydrate` is set to `true`, then it will render with `ReactDOM.hydrate`. This may be useful if you are using server-side + * rendering and use ReactDOM.hydrate to mount your components. + * + * @see https://testing-library.com/docs/react-testing-library/api/#hydrate) + */ hydrate?: boolean + /** + * Queries to bind. Overrides the default set from DOM Testing Library unless merged. + * + * @see https://testing-library.com/docs/react-testing-library/api/#queries + */ queries?: Q - wrapper?: React.ComponentType + /** + * Pass a React Component as the wrapper option to have it rendered around the inner element. This is most useful for creating + * reusable custom render functions for common data providers. See setup for examples. + * + * @see https://testing-library.com/docs/react-testing-library/api/#wrapper + */ + wrapper?: React.JSXElementConstructor<{children: React.ReactElement}> } type Omit = Pick> @@ -48,11 +82,12 @@ type Omit = Pick> */ export function render< Q extends Queries = typeof queries, - Container extends Element | DocumentFragment = HTMLElement + Container extends Element | DocumentFragment = HTMLElement, + BaseElement extends Element | DocumentFragment = Container, >( ui: React.ReactElement, - options: RenderOptions, -): RenderResult + options: RenderOptions, +): RenderResult export function render( ui: React.ReactElement, options?: Omit, diff --git a/types/test.tsx b/types/test.tsx index 5f9575ac..eae6e81f 100644 --- a/types/test.tsx +++ b/types/test.tsx @@ -3,39 +3,39 @@ import {render, fireEvent, screen, waitFor} from '.' import * as pure from './pure' export async function testRender() { - const page = render(