Jest matcher for image comparisons used for visual regression testing.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Jest Image Snapshot provides comprehensive snapshot management including automatic cleanup of obsolete snapshots and integration with Jest's snapshot update workflow.
Jest reporter that tracks snapshot files used during test runs and removes obsolete snapshots that are no longer referenced by tests.
class OutdatedSnapshotReporter {
/**
* Mark a snapshot file as touched during test execution
* @param filePath - Absolute path to the snapshot file
*/
static markTouchedFile(filePath: string): void;
/**
* Read the list of touched files from the tracking file
* @returns Array of file paths that were touched during tests
*/
static readTouchedFileListFromDisk(): string[];
/**
* Called at the start of test run - clears tracking file
*/
onRunStart(): void;
/**
* Called at the end of test run - removes obsolete snapshots
*/
onRunComplete(): void;
}Usage Example:
{
"jest": {
"reporters": [
"default",
"jest-image-snapshot/src/outdated-snapshot-reporter.js"
]
}
}Environment Variable:
# Enable snapshot cleanup
export JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1
jestImportant Notes:
.jest-image-snapshot-touched-files is created in current working directoryJest Image Snapshot creates and manages several directory structures for organizing snapshots and related files.
interface SnapshotDirectories {
/** Default snapshot directory name */
SNAPSHOTS_DIR: '__image_snapshots__';
/** Default received images directory */
receivedDir: '__received_output__';
/** Default diff images directory */
diffDir: '__diff_output__';
}Default Directory Structure:
test-directory/
├── __image_snapshots__/ # Baseline snapshots
│ ├── test-spec-test-name-1-snap.png
│ └── test-spec-test-name-2-snap.png
├── __received_output__/ # Received images (on failure)
│ ├── test-spec-test-name-1-received.png
│ └── test-spec-test-name-2-received.png
└── __diff_output__/ # Diff images (on failure)
├── test-spec-test-name-1-diff.png
└── test-spec-test-name-2-diff.pngConfigure custom directories for different types of images and organizational needs.
interface CustomDirectoryOptions {
/** Custom absolute path for baseline snapshots */
customSnapshotsDir?: string;
/** Custom absolute path for received images */
customReceivedDir?: string;
/** Custom absolute path for diff images */
customDiffDir?: string;
/** Custom postfix for received image filenames (default: '-received') */
customReceivedPostfix?: string;
}Usage Examples:
// Custom snapshot directories
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotsDir: path.join(__dirname, 'visual-snapshots'),
customDiffDir: path.join(__dirname, 'visual-diffs'),
customReceivedDir: path.join(__dirname, 'visual-received')
});
// Environment-specific directories
const snapshotDir = process.env.NODE_ENV === 'production'
? './snapshots/prod'
: './snapshots/dev';
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotsDir: path.resolve(snapshotDir)
});
// Device-specific organization
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotsDir: `./snapshots/${deviceType}`,
customSnapshotIdentifier: `${testName}-${deviceType}`
});Control how snapshot files are named and organized within directories.
interface SnapshotNaming {
/** Default naming pattern: {testFile}-{testName}-{counter}-snap.png */
defaultPattern: string;
/** Custom identifier string or function */
customSnapshotIdentifier?: string | CustomSnapshotIdentifierFunction;
}
interface CustomSnapshotIdentifierFunction {
(params: {
testPath: string;
currentTestName: string;
counter: number;
defaultIdentifier: string;
}): string;
}Naming Examples:
// Custom string identifier
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotIdentifier: 'header-component-mobile'
});
// Function-based identifier
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotIdentifier: ({ testPath, currentTestName, counter }) => {
const testFile = path.basename(testPath, '.spec.js');
return `${testFile}__${currentTestName}__${counter}`;
}
});
// Hierarchical naming with paths
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotIdentifier: 'components/header/mobile-view'
}); // Creates: components/header/mobile-view.pngIntegration with Jest's snapshot update workflow and custom update behaviors.
interface SnapshotUpdateOptions {
/** Update snapshots even when tests pass (default: false) */
updatePassedSnapshot?: boolean;
/** Store received images on failure for CI debugging */
storeReceivedOnFailure?: boolean;
}Update Examples:
# Update all snapshots (Jest standard)
jest --updateSnapshot
# Update specific test snapshots
jest --testNamePattern="header component" --updateSnapshot// Force update even passing snapshots
expect(imageBuffer).toMatchImageSnapshot({
updatePassedSnapshot: true
});
// Store received images for CI analysis
expect(imageBuffer).toMatchImageSnapshot({
storeReceivedOnFailure: true // Helpful in CI environments
});Best practices for managing snapshot files and preventing accumulation of obsolete snapshots.
Automated Cleanup:
// package.json script for cleanup
{
"scripts": {
"test:visual": "JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest",
"test:visual:update": "JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --updateSnapshot"
}
}Manual Cleanup Patterns:
// Clean up before test runs
beforeAll(async () => {
if (process.env.CLEAN_SNAPSHOTS) {
const snapshotDir = path.join(__dirname, '__image_snapshots__');
if (fs.existsSync(snapshotDir)) {
fs.rmSync(snapshotDir, { recursive: true });
}
}
});Git Integration:
# .gitignore - typically commit snapshots but ignore temp files
__image_snapshots__/ # Commit baseline snapshots
!__received_output__/ # Ignore received images
!__diff_output__/ # Ignore diff images
.jest-image-snapshot-touched-files # Ignore tracking fileSnapshot management error scenarios and recovery strategies.
Common Issues:
// Directory creation failures
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotsDir: '/readonly/path' // Will fail with permission error
});
// Invalid custom identifiers
expect(imageBuffer).toMatchImageSnapshot({
customSnapshotIdentifier: '../../../malicious-path' // Blocked by path validation
});
// Missing snapshots in CI
expect(imageBuffer).toMatchImageSnapshot();
// Fails in CI when no baseline exists and updates are disabledRecovery Strategies:
--updateSnapshot to create baselinesallowSizeMismatch: true or regenerate snapshots for size changes