如何使用 HTML5 canvas 图像快照测试 React 组件?
How do I image snapshot test a React component using HTML5 canvas?
我正在尝试使用呈现 HTML5 canvas 的 React 组件进行图像快照测试(即 而非 模拟)。我正在使用 Jest、React 测试库、Node Canvas、Puppeteer 和 Jest Image Snapshot。
给定以下 React 组件的 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>
);
}
Jest 测试可能如下所示:
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();
});
但是,此测试会生成空白的白色 800x600 PNG 图像作为基准。
但是,如果我将测试更改为:
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();
});
它根据我的 React 组件生成基线 PNG 快照就好了。
我目前正在尝试调试管道中哪里出了问题。
我用不使用puppeteer的方法做了html5 canvas图像快照,但是puppeteer的方法很有趣。这是我使用的方法
test('canvas image snapshot', async () => {
const { getByTestId } = render(
<MyComponent />,
)
const canvas = await waitForElement(() =>
getByTestId('mycanvas'),
)
const img = canvas.toDataURL()
const data = img.replace(/^data:image\/\w+;base64,/, '')
const buf = Buffer.from(data, 'base64')
// may need to do fuzzy image comparison because, at least for me, on
// travis-ci it was sometimes 2 pixel diff or more for font related stuff
expect(buf).toMatchImageSnapshot({
failureThreshold: 0.5,
failureThresholdType: 'percent',
})
})
对 toMatchImageSnapshot 使用 https://github.com/americanexpress/jest-image-snapshot
上面@Colin 的回答是需要做的。即,从 canvas URL 中剥离图像编码,因为 [显然] 它适用于浏览器。这是我们所做的:
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();
});
其中 stripEncoding
看起来像:
export function stripEncoding(canvasImageUrl: string): string {
return canvasImageUrl.replace(/^data:image\/(png|jpg);base64,/, '');
}
我正在尝试使用呈现 HTML5 canvas 的 React 组件进行图像快照测试(即 而非 模拟)。我正在使用 Jest、React 测试库、Node Canvas、Puppeteer 和 Jest Image Snapshot。
给定以下 React 组件的 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>
);
}
Jest 测试可能如下所示:
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();
});
但是,此测试会生成空白的白色 800x600 PNG 图像作为基准。
但是,如果我将测试更改为:
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();
});
它根据我的 React 组件生成基线 PNG 快照就好了。
我目前正在尝试调试管道中哪里出了问题。
我用不使用puppeteer的方法做了html5 canvas图像快照,但是puppeteer的方法很有趣。这是我使用的方法
test('canvas image snapshot', async () => {
const { getByTestId } = render(
<MyComponent />,
)
const canvas = await waitForElement(() =>
getByTestId('mycanvas'),
)
const img = canvas.toDataURL()
const data = img.replace(/^data:image\/\w+;base64,/, '')
const buf = Buffer.from(data, 'base64')
// may need to do fuzzy image comparison because, at least for me, on
// travis-ci it was sometimes 2 pixel diff or more for font related stuff
expect(buf).toMatchImageSnapshot({
failureThreshold: 0.5,
failureThresholdType: 'percent',
})
})
对 toMatchImageSnapshot 使用 https://github.com/americanexpress/jest-image-snapshot
上面@Colin 的回答是需要做的。即,从 canvas URL 中剥离图像编码,因为 [显然] 它适用于浏览器。这是我们所做的:
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();
});
其中 stripEncoding
看起来像:
export function stripEncoding(canvasImageUrl: string): string {
return canvasImageUrl.replace(/^data:image\/(png|jpg);base64,/, '');
}