CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-snapshot

Jest snapshot testing utilities that enable capturing component output, API responses, or any serializable values as snapshots for regression testing and change detection

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

path-resolution.mddocs/

Path Resolution

Snapshot file path management system that handles the relationship between test files and their corresponding snapshot files. Provides flexible path resolution with support for custom snapshot resolvers.

Capabilities

Snapshot Resolver

Interface for converting between test file paths and snapshot file paths, enabling customizable snapshot file organization.

interface SnapshotResolver {
  /**
   * Resolves from test path to snapshot path
   * @param testPath - Path to the test file
   * @param snapshotExtension - Optional snapshot file extension (defaults to 'snap')
   * @returns Path to the corresponding snapshot file
   */
  resolveSnapshotPath(testPath: string, snapshotExtension?: string): string;
  
  /**
   * Resolves from snapshot path to test path
   * @param snapshotPath - Path to the snapshot file
   * @param snapshotExtension - Optional snapshot file extension (defaults to 'snap')
   * @returns Path to the corresponding test file
   */
  resolveTestPath(snapshotPath: string, snapshotExtension?: string): string;
  
  /**
   * Example test path used for consistency checking
   * Must be a valid test path that can be resolved both ways
   */
  testPathForConsistencyCheck: string;
}

buildSnapshotResolver

Creates a snapshot resolver instance based on Jest configuration, with support for custom resolvers and caching.

/**
 * Builds a snapshot resolver for converting between test and snapshot paths
 * @param config - Jest project configuration
 * @param localRequire - Optional require function for loading custom resolvers
 * @returns Promise resolving to a SnapshotResolver instance
 */
async function buildSnapshotResolver(
  config: Config.ProjectConfig,
  localRequire?: Promise<LocalRequire> | LocalRequire
): Promise<SnapshotResolver>;

type LocalRequire = (module: string) => unknown;

Usage Examples:

import { buildSnapshotResolver } from "jest-snapshot";

// Basic resolver creation
const resolver = await buildSnapshotResolver({
  rootDir: '/project/root',
  snapshotResolver: undefined // use default resolver
});

// Custom resolver
const resolver = await buildSnapshotResolver({
  rootDir: '/project/root',
  snapshotResolver: './custom-snapshot-resolver.js'
});

// Use resolver to convert paths
const snapshotPath = resolver.resolveSnapshotPath(
  '/project/src/components/Button.test.js'
);
// Returns: '/project/src/components/__snapshots__/Button.test.js.snap'

const testPath = resolver.resolveTestPath(
  '/project/src/__snapshots__/utils.test.js.snap'
);
// Returns: '/project/src/utils.test.js'

Default Path Resolution

The default snapshot resolver follows Jest's standard conventions:

Test to Snapshot Path:

  • src/components/Button.test.jssrc/components/__snapshots__/Button.test.js.snap
  • tests/user.spec.tstests/__snapshots__/user.spec.ts.snap
  • app.test.jsx__snapshots__/app.test.jsx.snap

Snapshot to Test Path:

  • __snapshots__/Button.test.js.snapButton.test.js
  • src/__snapshots__/utils.spec.ts.snapsrc/utils.spec.ts

Custom Snapshot Resolvers

Create custom resolvers to implement different snapshot organization strategies:

// custom-snapshot-resolver.js
module.exports = {
  // Resolve from test path to snapshot path
  resolveSnapshotPath: (testPath, snapshotExtension) => {
    // Custom logic: place all snapshots in a single directory
    const testName = path.basename(testPath);
    return path.join(
      path.dirname(testPath), 
      'snapshots', 
      `${testName}.${snapshotExtension || 'snap'}`
    );
  },

  // Resolve from snapshot path to test path
  resolveTestPath: (snapshotPath, snapshotExtension) => {
    // Reverse the custom logic
    const snapshotName = path.basename(snapshotPath, `.${snapshotExtension || 'snap'}`);
    return path.join(path.dirname(path.dirname(snapshotPath)), snapshotName);
  },

  // Example test path for consistency checking
  testPathForConsistencyCheck: 'example.test.js'
};

Path Utilities

Utility functions for working with snapshot file paths.

/**
 * Checks if a given path is a snapshot file
 * @param path - File path to check
 * @returns True if the path ends with the snapshot extension
 */
function isSnapshotPath(path: string): boolean;

/**
 * Snapshot file extension constant
 */
const EXTENSION: string; // 'snap'

/**
 * Dot-prefixed snapshot extension
 */
const DOT_EXTENSION: string; // '.snap'

Usage Examples:

import { isSnapshotPath, EXTENSION, DOT_EXTENSION } from "jest-snapshot";

// Check if path is a snapshot file
console.log(isSnapshotPath('Button.test.js.snap')); // true
console.log(isSnapshotPath('Button.test.js'));      // false

// Use extension constants
const snapshotFile = `test.${EXTENSION}`;           // 'test.snap'
const pattern = `*${DOT_EXTENSION}`;                // '*.snap'

Resolver Caching

The buildSnapshotResolver function implements caching to avoid recreating resolvers:

// Cached by config.rootDir
const resolver1 = await buildSnapshotResolver(config);
const resolver2 = await buildSnapshotResolver(config);
// resolver1 === resolver2 (same instance from cache)

// Different rootDir = different cache entry
const differentConfig = { ...config, rootDir: '/different/path' };
const resolver3 = await buildSnapshotResolver(differentConfig);
// resolver3 !== resolver1 (different instance)

Resolver Validation

Custom resolvers must pass consistency checks:

// Resolver consistency check
const resolver = {
  resolveSnapshotPath: (testPath) => `/snapshots/${path.basename(testPath)}.snap`,
  resolveTestPath: (snapshotPath) => path.basename(snapshotPath, '.snap'),
  testPathForConsistencyCheck: 'example.test.js'
};

// Jest validates:
// 1. testPath -> snapshotPath -> testPath should return original
// 2. Both functions should be consistent

Integration with FileSystem

Resolvers work with Jest's file system abstraction:

import { cleanup } from "jest-snapshot";

// Use resolver in cleanup operations
const result = cleanup(
  fileSystem,
  updateMode,
  resolver,
  testPathIgnorePatterns
);

// Resolver is used to:
// 1. Find all snapshot files matching the pattern
// 2. Convert snapshot paths back to test paths
// 3. Check if corresponding test files exist

Error Handling

// Invalid custom resolver
await buildSnapshotResolver({
  rootDir: '/project',
  snapshotResolver: './missing-resolver.js'
});
// Error: Cannot resolve module './missing-resolver.js'

// Inconsistent resolver functions
const badResolver = {
  resolveSnapshotPath: (testPath) => 'snapshot.snap',
  resolveTestPath: (snapshotPath) => 'different.test.js',
  testPathForConsistencyCheck: 'test.js'
};
// Error: Inconsistent snapshot resolver implementation

// Missing required methods
const incompleteResolver = {
  resolveSnapshotPath: (testPath) => `${testPath}.snap`
  // Missing resolveTestPath and testPathForConsistencyCheck
};
// Error: Invalid snapshot resolver

Types

interface Config {
  rootDir: string;
  snapshotResolver?: string;  // Path to custom resolver module
}

type LocalRequire = (module: string) => unknown;

interface ResolverCache extends Map<string, SnapshotResolver> {}

docs

cleanup.md

error-snapshots.md

index.md

path-resolution.md

serialization.md

snapshot-matchers.md

state-management.md

tile.json