We have a simple iframe component that's wrapped by an "overlay" loading indicator component. We use the native onload function to clear the overlay's loading state.
export const Frame = ({ className, src }: FrameProps): JSX.Element => {
const [status, setStatus] = useState<OverlayStatuses>('loading')
const onLoad = useCallback(() => {
setStatus('success')
}, [])
return (
<Overlay status={status}>
<iframe className={clsx(styles.frame, className)} onLoad={onLoad} src={src.toString()} />
</Overlay>
)
}
However, in our unit test (using testing-library/react in vitest) we use abount:blank for the iframe src, which I believe triggers the onload immediately, which updates state, which triggers a warning that we need to be wrapping our test in act. Except this is the original render and I don't see a way to wrap that in act or await anything.
When we use http://example.com as the URL, the issue goes away because the onload doesn't fire immediately. But using an actual internet website isn't acceptable for our automated tests.
describe('frame', () => {
it('mounts and matches snapshot', () => {
const { container } = render(<Frame src={new URL('about:blank')} />)
expect(container).toBeInTheDocument()
expect(container).toMatchSnapshot()
})
})
stderr | app/components/frame/tests/frame.spec.tsx > frame > mounts and matches snapshot
Warning: An update to Frame inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
at Frame (C:\...\app\components\frame\frame.tsx:13:18)