Hone logo
Hone
Problems

Implementing Visual Regression Testing with Jest and Chromatic

Visual regression testing is crucial for maintaining the consistency of your UI across different environments, code changes, and browser versions. This challenge asks you to implement a basic visual regression testing setup using Jest, a screenshot comparison library (like jest-image-snapshot), and a service like Chromatic (though Chromatic integration is optional for the core challenge). The goal is to automatically detect unintended visual changes in your components.

Problem Description

You need to create a Jest test suite that captures screenshots of a React component and compares them against baseline images. The test suite should:

  1. Render a React component: The component to be tested is src/components/Button.tsx. This component is a simple button with configurable text and styling.
  2. Capture a screenshot: Use jest-image-snapshot to capture a screenshot of the rendered component.
  3. Compare against a baseline: Compare the captured screenshot with a baseline image stored in the __snapshots__ directory.
  4. Update baseline on failure (optional): If the screenshots differ, the test should fail and provide an option to update the baseline image.
  5. Handle different component states: The test should cover at least two different states of the button: a default state and a "hovered" state. Simulate the hovered state by adding a class to the component during rendering.
  6. Chromatic Integration (Optional): While not required for the core functionality, consider how your tests could be integrated with Chromatic for easier visual diff review and baseline management.

Key Requirements:

  • Use Jest as the test runner.
  • Use jest-image-snapshot for screenshot capture and comparison.
  • The test suite should be robust and handle different component states.
  • The test suite should clearly indicate when a baseline image needs to be updated.
  • The code should be well-structured and easy to understand.

Expected Behavior:

  • The test suite should pass if the rendered component matches the baseline images.
  • The test suite should fail if the rendered component differs from the baseline images.
  • When a test fails, the user should be able to easily compare the current screenshot with the baseline image.
  • The user should be able to update the baseline image if the changes are intentional.

Edge Cases to Consider:

  • Different screen sizes/resolutions: While not explicitly required, consider how your tests might behave on different screen sizes. jest-image-snapshot has options for handling this.
  • Font rendering differences: Font rendering can vary across operating systems and browsers. Consider using a consistent font stack or mocking font rendering if necessary.
  • Anti-aliasing: Differences in anti-aliasing can cause false positives. jest-image-snapshot has options to control anti-aliasing.

Examples

Example 1:

Input: Button component rendered in default state. Baseline image exists.
Output: Test passes.
Explanation: The rendered component matches the existing baseline image.

Example 2:

Input: Button component rendered in hovered state. Baseline image exists.
Output: Test passes.
Explanation: The rendered component matches the existing baseline image for the hovered state.

Example 3:

Input: Button component rendered in default state. Baseline image does not exist.
Output: Test fails.  A message is displayed indicating that a baseline image needs to be created.
Explanation:  Since no baseline exists, the test fails, prompting the user to create one.

Constraints

  • Dependencies: You are allowed to use jest, jest-image-snapshot, @types/jest, and React. No other external libraries are permitted for the core screenshot comparison functionality.
  • Component: You must test the src/components/Button.tsx component.
  • Baseline Directory: Baseline images must be stored in the __snapshots__ directory.
  • Test File: Create a test file named src/components/Button.test.tsx.
  • Performance: The tests should execute within a reasonable timeframe (e.g., under 5 seconds per test).

Notes

  • Start by setting up your Jest environment and installing the necessary dependencies.
  • Familiarize yourself with the jest-image-snapshot API.
  • Consider using a mocking library (like jest.mock) to isolate your component from external dependencies.
  • Think about how to handle different component states and ensure that your tests cover all relevant scenarios.
  • Chromatic integration is optional but highly recommended for a production-ready visual regression testing setup. Research Chromatic's Jest integration for more details.
  • The src/components/Button.tsx file is provided below for your convenience.
// src/components/Button.tsx
import React from 'react';

interface ButtonProps {
  text: string;
  onClick?: () => void;
  className?: string;
}

const Button: React.FC<ButtonProps> = ({ text, onClick, className }) => {
  return (
    <button onClick={onClick} className={`button ${className || ''}`}>
      {text}
    </button>
  );
};

export default Button;
Loading editor...
typescript