Description
@testing-library/react
version: 11.1.1- Testing Framework and version:
jest
25.1.0 - DOM Environment:
jsdom
Relevant code or config:
import * as React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
test("Is a circle", () => {
const { container } = render(
<circle cx=0 cy=0 />,
{
container:
document.body.appendChild(
document.createElementNS("http://www.w3.org/2000/svg", "svg")),
});
expect(container.firstChild.nodeName).toBe("circle");
});
What you did:
Trying to set SVG as the container element for testing SVG React components.
What happened:
Typescript threw a type error stating that render()
requires an HTMLElement.
Reproduction:
I created a repository illustrating my problem.
Problem description:
React allows components to use HTML and SVG tags. SVG tags do not work properly in an HTML context, and consequently must be rendered inside an SVG context. This can be only done by using an SVG tag as the containing element. Since the API's types disallow this, users have to wrap all their SVG based components in SVG tags manually and introducing unnecessary nesting to the render output.
Suggested solution:
Propose the following patch to @testing-library/react/types/index.d.ts
:
// TypeScript Version: 3.8
import {OptionsReceived as PrettyFormatOptions} from 'pretty-format'
import {queries, Queries, BoundFunction} from '@testing-library/dom'
import {act as reactAct} from 'react-dom/test-utils'
export * from '@testing-library/dom'
type DOMElement = HTMLElement | SVGElement;
export type RenderResult<Q extends Queries = typeof queries> = {
container: DOMElement
baseElement: DOMElement
debug: (
baseElement?:
| DOMElement
| DocumentFragment
| Array<DOMElement | DocumentFragment>,
maxLength?: number,
options?: PrettyFormatOptions,
) => void
rerender: (ui: React.ReactElement) => void
unmount: () => boolean
asFragment: () => DocumentFragment
} & {[P in keyof Q]: BoundFunction<Q[P]>}
export interface RenderOptions<Q extends Queries = typeof queries> {
container?: DOMElement
baseElement?: DOMElement
hydrate?: boolean
queries?: Q
wrapper?: React.ComponentType
}
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
/**
* Render into a container which is appended to document.body. It should be used with cleanup.
*/
export function render(
ui: React.ReactElement,
options?: Omit<RenderOptions, 'queries'>,
): RenderResult
export function render<Q extends Queries>(
ui: React.ReactElement,
options: RenderOptions<Q>,
): RenderResult<Q>
/**
* Unmounts React trees that were mounted with render.
*/
export function cleanup(): void
/**
* Simply calls ReactDOMTestUtils.act(cb)
* If that's not available (older version of react) then it
* simply calls the given callback immediately
*/
export const act: typeof reactAct extends undefined
? (callback: () => void) => void
: typeof reactAct
I've implemented this patch locally in my project where I discovered the bug and it solves the issue. However, I'm having difficulty committing my patch to react-testing-library
due to dtslint
commit hook rejecting the types in the React dependency.