#react-testing-library #node-canvas #jest-image-snapshot
#react-testing-library #узел-холст #jest-image-snapshot
Вопрос:
Я пытаюсь заставить тестирование моментального снимка изображения работать (т. Е. не издеваться) с компонентом React, который отображает холст HTML5. Я использую 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();
});
Однако этот тест генерирует пустое белое изображение в формате PNG размером 800×600 в качестве базовой линии.
Однако, если я изменю тест на этот:
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();
});
Он отлично генерирует базовый снимок PNG на основе моего компонента React.
В настоящее время я пытаюсь отладить, где в конвейере что-то идет не так.
Ответ №1:
Я сделал снимок изображения html5 canvas с помощью метода, который не использует puppeteer, но метод 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',
})
})
Использует https://github.com/americanexpress/jest-image-snapshot для toMatchImageSnapshot
Комментарии:
1. Да, это в основном то, что мы сделали. Потребовалось некоторое время, чтобы понять, что нам нужно удалить этот мусор кодирования.
Ответ №2:
Ответ от @ Colin выше — это то, что нужно сделать. А именно, удалите кодировку изображения из URL-адреса canvas, потому что [по-видимому] он предназначен для браузера. Вот что мы сделали:
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,/, '');
}