CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-image-snapshot

Jest matcher for image comparisons used for visual regression testing.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

snapshot-management.mddocs/

Snapshot Management

Jest Image Snapshot provides comprehensive snapshot management including automatic cleanup of obsolete snapshots and integration with Jest's snapshot update workflow.

Capabilities

Outdated Snapshot Reporter

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
jest

Important Notes:

  • Only run with full test suite - partial runs may mark active snapshots as obsolete
  • The reporter deletes files permanently - ensure you have version control backups
  • Tracking file .jest-image-snapshot-touched-files is created in current working directory

Snapshot Directory Structure

Jest 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.png

Custom Directory Configuration

Configure 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}`
});

Snapshot Naming

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.png

Snapshot Updates

Integration 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
});

Cleanup and Maintenance

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 file

Error Handling

Snapshot 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 disabled

Recovery Strategies:

  • Missing Snapshots: Run tests locally with --updateSnapshot to create baselines
  • Permission Errors: Ensure test directories have write permissions
  • Corrupted Snapshots: Delete and regenerate affected snapshot files
  • Size Conflicts: Use allowSizeMismatch: true or regenerate snapshots for size changes

docs

configuration.md

core-matcher.md

index.md

snapshot-management.md

tile.json