'How do I image snapshot test a React component using HTML5 canvas?
I'm attempting to get image snapshot testing working (i.e., not mocked) with a React component that renders an HTML5 canvas. I'm using Jest, React Testing Library, Node Canvas, Puppeteer, and Jest Image Snapshot.
Given the following React component's render():
public render(): React.ReactElement<TestCanvas> {
const { innerWidth, innerHeight } = window;
return (
<div id="canvas" style={{ height: `${innerHeight}px`, width: `${innerWidth}px` }}>
<canvas ref={this.canvasRef} />
</div>
);
}
Here's what a Jest test might look like:
it('should render a <TestCanvas/> component', async () => {
const { container } = render(<TestCanvas />);
const page: puppeteer.Page = await browser.newPage();
await page.setContent(container.outerHTML);
const image: string = await page.screenshot();
expect(image).toMatchImageSnapshot();
});
However, this test generates an empty, white, 800x600 PNG image as the baseline.
If, however, I change the test to this:
it('should render a <TestCanvas/> component', async () => {
const { container } = render(<TestCanvas />);
const canvas: HTMLCanvasElement = container.querySelector('canvas') as HTMLCanvasElement;
const img = document.createElement('img');
img.src = canvas.toDataURL();
const page: puppeteer.Page = await browser.newPage();
await page.setContent(img.outerHTML);
const image: string = await page.screenshot();
expect(image).toMatchImageSnapshot();
});
It generates the baseline PNG snapshot based on my React component just fine.
I'm currently trying to debug where in the pipeline things are going screwy.
Solution 1:[1]
The answer from @Colin above is what one needs to do. Namely, strip off the image encoding from the canvas URL because [apparently] it's meant for a browser. Here's what we did:
it('should scroll down', () => {
const { getByTestId } = render(<PaneDrawerTestWrapper />);
const mouseHandler = getByTestId(mouseHandlerId);
act(() => {
fireEvent.wheel(mouseHandler, { deltaY: 100 });
});
const canvas = getByTestId(canvasId) as HTMLCanvasElement;
const image = stripEncoding(canvas.toDataURL());
expect(image).toMatchImageSnapshot();
});
Where stripEncoding looks like:
export function stripEncoding(canvasImageUrl: string): string {
return canvasImageUrl.replace(/^data:image\/(png|jpg);base64,/, '');
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | icfantv |
