Hone logo
Hone
Problems

Jest Visual Regression Testing

This challenge focuses on integrating visual regression testing into a Jest test suite for a React application. Visual regression testing is crucial for ensuring that UI changes do not introduce unintended visual bugs. You will implement a system that captures screenshots of your application's components and compares them against a baseline to detect regressions.

Problem Description

Your task is to create a Jest test suite that performs visual regression testing on a given React component. This involves:

  1. Rendering a React component: You need a mechanism to render a React component within a browser-like environment for testing.
  2. Capturing a screenshot: After rendering, you must capture a screenshot of the rendered component.
  3. Comparing screenshots: The captured screenshot needs to be compared against a previously stored "baseline" screenshot.
  4. Reporting differences: If a significant difference is detected between the current screenshot and the baseline, the test should fail, and the differences should be highlighted or stored for review.

Key Requirements:

  • Use Jest as the testing framework.
  • Leverage a library capable of interacting with a headless browser (e.g., Puppeteer) to render and capture screenshots.
  • Implement a strategy for storing and managing baseline screenshots.
  • Your tests should automatically fail if a visual regression is detected.

Expected Behavior:

  • On the first run, a baseline screenshot should be generated and stored for each test.
  • On subsequent runs, the newly captured screenshot will be compared to the stored baseline.
  • If the screenshots match within a configurable tolerance, the test passes.
  • If significant differences are found, the test fails, and details of the diff (e.g., a diff image) should be made available.

Edge Cases to Consider:

  • Dynamic content or animations that might cause minor pixel variations.
  • Different screen resolutions or browser zoom levels.
  • Handling of components that might have different states.

Examples

Example 1: Basic Component Rendering and Baseline Creation

Let's assume you have a simple Button component in src/components/Button.tsx.

Input (Conceptual):

// src/components/Button.tsx
import React from 'react';

const Button = ({ label, onClick }) => <button onClick={onClick}>{label}</button>;

export default Button;

Test Setup (Conceptual):

// src/tests/Button.test.ts
import React from 'react';
import { render, screen } from '@testing-library/react';
import Button from '../components/Button';
import { setupVisualRegression } from './utils/visualRegression'; // Assume this utility exists

const { test, captureScreenshot } = setupVisualRegression();

describe('Button Component', () => {
  test('should render correctly', async () => {
    render(<Button label="Click Me" onClick={() => {}} />);
    await captureScreenshot(); // This would capture and compare/save the screenshot
  });
});

Expected Output (First Run):

  • A new file __snapshots__/Button.test.ts/Button Component should render correctly-0.png is created in a __snapshots__ directory (or a similar designated location).
  • The test passes.

Expected Output (Second Run):

  • The Button component is rendered again.
  • A new screenshot is captured.
  • This new screenshot is compared to __snapshots__/Button.test.ts/Button Component should render correctly-0.png.
  • If they match, the test passes.

Example 2: Visual Regression Failure

Suppose the Button component's styling is updated to have a red background.

Input (Conceptual):

// src/components/Button.tsx (Modified)
import React from 'react';

const Button = ({ label, onClick }) => (
  <button style={{ backgroundColor: 'red', color: 'white' }} onClick={onClick}>
    {label}
  </button>
);

export default Button;

Test Setup (Same as Example 1)

Expected Output (Second Run with Modified Component):

  • The test fails.
  • A diff image might be generated (e.g., __diffs__/Button.test.ts/Button Component should render correctly-0.png) highlighting the difference in background color.
  • A report indicating a visual regression is generated.

Constraints

  • The React application will be built using functional components and hooks.
  • Tests should be written in TypeScript.
  • The solution must integrate with Jest.
  • The chosen headless browser automation library should be performant enough for typical CI/CD pipelines.
  • Screenshots will be compared based on pixel-by-pixel differences, with a configurable tolerance for minor variations.

Notes

Consider using libraries like jest-image-snapshot or percy for handling the image comparison and diffing. You'll likely need to set up a jest-runner or a custom Jest environment to run your tests in a browser context. Think about how you will manage the baseline snapshots—should they be committed to version control? How will you update them when intentional UI changes are made?

Loading editor...
typescript