Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
VCR
✓ import { VCR } from 'socket-vcr-test';
✗ const { VCR } = require('socket-vcr-test');
The library is primarily designed for ESM usage in TypeScript or modern JavaScript environments. For CommonJS, named imports are still possible but less idiomatic for newer projects.
FileStorage
✓ import { FileStorage } from 'socket-vcr-test';
✗ import FileStorage from 'socket-vcr-test/FileStorage';
FileStorage is a named export, not a default export or submodule. Ensure correct named import syntax.
RecordMode
✓ import { RecordMode } from 'socket-vcr-test';
✗ import { RecordingMode } from 'socket-vcr-test';
The enum for recording behavior is named `RecordMode`, not `RecordingMode`.
DefaultRequestMatcher
✓ import { DefaultRequestMatcher } from 'socket-vcr-test';
Used for customizing how VCR matches incoming requests against recorded interactions.
This quickstart demonstrates how to initialize `socket-vcr-test` with `FileStorage`, use `useCassette` to wrap an asynchronous API call, and verifies that the HTTP interactions are recorded and then replayed. It shows both recording (first run) and replaying (subsequent runs) behavior, as well as an example of `RecordMode.update`.
import { join } from 'node:path';
import { VCR, FileStorage, RecordMode } from 'socket-vcr-test';
import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync } from 'node:fs';
// Mock an external API call for demonstration purposes
const mockApi = {
myAwesomeApiCall: async () => {
console.log(' Making a simulated API call...');
return new Promise(resolve => setTimeout(() => resolve({ data: 'hello from real API', timestamp: Date.now() }), 50));
}
};
// Basic mocks for a runnable 'test' context
const expect = (value: any) => ({
toBeDefined: () => {
if (value === undefined || value === null) throw new Error('Expected value to be defined');
},
toEqual: (expected: any) => {
if (JSON.stringify(value) !== JSON.stringify(expected)) throw new Error(`Expected ${JSON.stringify(value)} to equal ${JSON.stringify(expected)}`);
}
});
const describe = (name: string, fn: () => void) => { console.log(`\n-- Running Suite: ${name} --`); fn(); };
const it = (name: string, fn: () => Promise<void>) => {
console.log(` Test: ${name}`);
fn().then(() => console.log(` ✓ Passed: ${name}`)).catch(e => console.error(` ✗ Failed: ${name}\n`, e));
};
// Setup a dummy directory for cassettes
const CASSETTES_DIR = join(process.cwd(), '__quickstart_cassettes__');
if (!existsSync(CASSETTES_DIR)) {
mkdirSync(CASSETTES_DIR, { recursive: true });
} else {
// Clean up previous run's cassettes for a fresh start
rmSync(CASSETTES_DIR, { recursive: true, force: true });
mkdirSync(CASSETTES_DIR, { recursive: true });
}
describe('socket-vcr-test quickstart', () => {
it('should record and replay an API call using VCR', async () => {
const cassetteName = 'quickstart_api_call';
const cassettePath = join(CASSETTES_DIR, cassetteName + '.yml');
// 1. Initial run: Configure VCR to record (default mode is 'once')
let vcr = new VCR(new FileStorage(CASSETTES_DIR));
vcr.mode = RecordMode.once; // Explicitly set, though it's the default
console.log(` First run (Recording mode: ${vcr.mode}): Cassette ${cassetteName}.yml should be created.`);
await vcr.useCassette(cassetteName, async () => {
const result = await mockApi.myAwesomeApiCall();
expect(result).toBeDefined();
expect((result as any).data).toEqual('hello from real API');
});
expect(existsSync(cassettePath)).toEqual(true);
console.log(` Cassette '${cassetteName}.yml' now exists.`);
// 2. Second run: VCR should replay from the cassette
// Re-initialize VCR to clear any internal state from the previous run
vcr = new VCR(new FileStorage(CASSETTES_DIR));
vcr.mode = RecordMode.once; // Still 'once', but cassette exists
console.log(`\n Second run (Replay mode: ${vcr.mode}): Cassette ${cassetteName}.yml should be replayed.`);
const startTime = Date.now();
await vcr.useCassette(cassetteName, async () => {
const result = await mockApi.myAwesomeApiCall();
expect(result).toBeDefined();
expect((result as any).data).toEqual('hello from real API');
});
const endTime = Date.now();
console.log(` API call completed in ${endTime - startTime}ms (expected very fast replay).`);
// Demonstrating `update` mode
vcr = new VCR(new FileStorage(CASSETTES_DIR));
vcr.mode = RecordMode.update;
console.log(`\n Third run (Update mode: ${vcr.mode}): Simulating change to trigger re-recording if needed.`);
await vcr.useCassette(cassetteName, async () => {
// Even if mockApi changes, 'update' would re-record or update existing entries
const result = await mockApi.myAwesomeApiCall();
expect(result).toBeDefined();
});
});
});
// To run this example: save as `quickstart.ts`, compile with `tsc quickstart.ts`, then `node quickstart.js`
Errors
Common errors & fixes
Error: No matching HTTP interaction found in cassette 'cassette_name'
An HTTP request made during the test run did not exactly match any recorded interactions in the specified cassette. This can happen if the request URL, method, headers, or body changed.
fixIf the request has genuinely changed, update the cassette by running the test with `vcr.mode = RecordMode.update` or by deleting the cassette file and letting `RecordMode.once` re-record it. If the difference is in dynamic headers (e.g., `Date`, `Authorization`), use `vcr.matcher.ignoreHeaders.add('header-name')` or implement a custom request masker. TypeError: Cannot read properties of undefined (reading 'headers')
This usually indicates that HTTP interception is not active or correctly configured, or that a request was made outside of the `vcr.useCassette` block.
fixVerify that `vcr.useCassette()` properly wraps all code that makes HTTP requests. Ensure the `VCR` instance is correctly initialized with a `FileStorage` or custom storage. If using a custom HTTP client, ensure it's compatible with `socket-vcr-test`'s interception mechanism.
SyntaxError: Named export 'VCR' not found. The requested module 'socket-vcr-test' does not provide an export named 'VCR'
Attempting to use `require()` syntax (`const { VCR } = require('socket-vcr-test');`) in a pure ESM project, or an incorrect import statement in TypeScript/ESM.
fixEnsure you are using correct ESM import syntax: `import { VCR } from 'socket-vcr-test';`. For CommonJS environments that require this package, this specific error usually means the CJS compatibility isn't set up, or the project is trying to import an ESM-only package incorrectly. Audit
Dependencies
No dependency data recorded yet.