Scenarios & Recordings
A scenario is a named collection of recorded API interactions. A recording captures a single HTTP request and its corresponding response.
What is a Scenario?
A scenario represents a complete test case or user flow. It contains:
- A unique name identifying the scenario
- A description explaining what it tests
- An array of recordings (request/response pairs)
- Timestamps for creation and last update
import { createScenario } from '@mockmaster/msw-adapter'
const scenario = createScenario('user-login', 'Successful user login flow')
console.log(scenario)
// {
// name: 'user-login',
// description: 'Successful user login flow',
// recordings: [],
// createdAt: 1234567890,
// updatedAt: 1234567890
// }Creating Scenarios
Empty Scenario
Start with an empty scenario and add recordings:
import { createScenario, addRecordingToScenario, createRecording } from '@mockmaster/msw-adapter'
let scenario = createScenario('checkout-flow', 'Complete checkout process')
// Add recordings one by one
const cartRecording = createRecording(
{ method: 'GET', url: 'https://api.example.com/cart', path: '/cart', timestamp: Date.now() },
{ status: 200, body: { items: [], total: 0 }, timestamp: Date.now() }
)
scenario = addRecordingToScenario(scenario, cartRecording)From OpenAPI Spec
Generate scenarios automatically from OpenAPI specs:
import { generateScenariosFromSpec } from '@mockmaster/cli'
import { parseYaml } from '@mockmaster/openapi'
const spec = parseYaml(`
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
responses:
'200':
content:
application/json:
schema:
type: array
`)
const scenarios = generateScenariosFromSpec(spec, 'user-api')
// Returns array of scenarios with realistic dataManaging Recordings
Adding Recordings
Use addRecordingToScenario to add recordings:
import { createScenario, addRecordingToScenario, createRecording } from '@mockmaster/msw-adapter'
let scenario = createScenario('user-api', 'User CRUD operations')
// Add GET /users
const listRecording = createRecording(
{ method: 'GET', url: 'https://api.example.com/users', path: '/users', timestamp: Date.now() },
{ status: 200, body: [{ id: 1, name: 'Alice' }], timestamp: Date.now() }
)
scenario = addRecordingToScenario(scenario, listRecording)
// Add GET /users/:id
const getRecording = createRecording(
{ method: 'GET', url: 'https://api.example.com/users/1', path: '/users/:id', timestamp: Date.now() },
{ status: 200, body: { id: 1, name: 'Alice' }, timestamp: Date.now() }
)
scenario = addRecordingToScenario(scenario, getRecording)
console.log(scenario.recordings.length) // 2Accessing Recordings
Recordings are stored in the recordings array:
scenario.recordings.forEach((recording, index) => {
console.log(`Recording ${index + 1}:`)
console.log(' Method:', recording.request.method)
console.log(' Path:', recording.request.path)
console.log(' Status:', recording.response.status)
})Storing Scenarios
Save to Disk
Write scenarios to JSON files:
import { writeScenario } from '@mockmaster/cli'
await writeScenario('./scenarios', scenario)
// Saves to: ./scenarios/user-api.jsonLoad from Disk
Read scenarios from JSON files:
import { readScenario } from '@mockmaster/cli'
const scenario = await readScenario('./scenarios', 'user-api')
// Loads from: ./scenarios/user-api.jsonJSON Format
Scenarios are stored as JSON files:
{
"name": "checkout-flow",
"description": "Complete checkout process",
"recordings": [
{
"request": {
"method": "GET",
"url": "https://api.example.com/cart",
"path": "/cart",
"timestamp": 1234567890
},
"response": {
"status": 200,
"body": {
"items": [
{ "id": 1, "name": "Product", "price": 29.99 }
]
},
"headers": {
"content-type": "application/json"
},
"timestamp": 1234567890
}
}
],
"createdAt": 1234567890,
"updatedAt": 1234567891
}Organizing Scenarios
By Feature
Organize scenarios by feature or module:
scenarios/
├── auth/
│ ├── login-success.json
│ ├── login-failure.json
│ ├── logout.json
│ └── refresh-token.json
├── users/
│ ├── list-users.json
│ ├── get-user.json
│ ├── create-user.json
│ └── update-user.json
└── products/
├── list-products.json
└── get-product.jsonBy User Flow
Organize by user flows or test cases:
scenarios/
├── new-user-signup.json
├── existing-user-login.json
├── checkout-with-coupon.json
└── profile-update.jsonBy Environment
Create environment-specific scenarios:
scenarios/
├── development/
│ └── user-api.json
├── staging/
│ └── user-api.json
└── production/
└── user-api.jsonScenario Naming Conventions
Use clear, descriptive names:
Good Names
user-registration-successlogin-with-invalid-credentialscheckout-flow-with-discountapi-user-crud-operations
Avoid
test1scenariotempx
Version Control
Commit Scenarios
Always commit scenario JSON files to version control:
git add scenarios/
git commit -m "Add user authentication scenarios"Update When APIs Change
When APIs change, update scenarios:
# Re-generate from updated OpenAPI spec
node scripts/generate-scenarios.ts
# Review changes
git diff scenarios/
# Commit updates
git add scenarios/
git commit -m "Update scenarios for API v2"Code Review
Include scenario files in code reviews:
- Verify recordings match expected API behavior
- Check for realistic test data
- Ensure error cases are covered
Best Practices
1. Descriptive Names
Use names that clearly describe what the scenario tests:
// Good
createScenario('user-login-success', 'User logs in with valid credentials')
createScenario('user-login-invalid-password', 'Login fails with wrong password')
// Bad
createScenario('test1', 'test')
createScenario('user', 'user stuff')2. Detailed Descriptions
Write descriptions that explain the scenario’s purpose:
createScenario(
'checkout-flow',
'Complete checkout process: add items to cart, apply discount code, and complete payment'
)3. One Scenario Per Flow
Keep scenarios focused on a single user flow or test case:
// Good - focused scenarios
createScenario('user-registration', 'New user signs up')
createScenario('user-login', 'Existing user logs in')
// Bad - too broad
createScenario('user-auth', 'All auth stuff')4. Include Error Cases
Create scenarios for both success and error cases:
createScenario('create-user-success', '201 Created')
createScenario('create-user-validation-error', '400 Bad Request')
createScenario('create-user-duplicate-email', '409 Conflict')5. Keep Scenarios Updated
Update scenarios when:
- API endpoints change
- Response formats change
- New fields are added
- Error messages change
Complete Example
import {
createScenario,
addRecordingToScenario,
createRecording
} from '@mockmaster/msw-adapter'
import { writeScenario } from '@mockmaster/cli'
async function createAuthScenarios() {
// Login success scenario
let loginSuccess = createScenario(
'login-success',
'User logs in with valid credentials'
)
const loginRecording = createRecording(
{
method: 'POST',
url: 'https://api.example.com/auth/login',
path: '/auth/login',
body: { email: 'user@example.com', password: 'password123' },
timestamp: Date.now()
},
{
status: 200,
body: {
accessToken: 'eyJhbGc...',
user: { id: 1, email: 'user@example.com', name: 'Test User' }
},
timestamp: Date.now()
}
)
loginSuccess = addRecordingToScenario(loginSuccess, loginRecording)
await writeScenario('./scenarios/auth', loginSuccess)
// Login failure scenario
let loginFailure = createScenario(
'login-failure',
'Login fails with invalid credentials'
)
const loginFailureRecording = createRecording(
{
method: 'POST',
url: 'https://api.example.com/auth/login',
path: '/auth/login',
body: { email: 'user@example.com', password: 'wrong' },
timestamp: Date.now()
},
{
status: 401,
body: { error: 'Invalid credentials' },
timestamp: Date.now()
}
)
loginFailure = addRecordingToScenario(loginFailure, loginFailureRecording)
await writeScenario('./scenarios/auth', loginFailure)
console.log('✓ Auth scenarios created successfully!')
}
createAuthScenarios().catch(console.error)Next Steps
- Learn about Record & Replay to use scenarios in tests
- Explore OpenAPI Integration to generate scenarios automatically
- Check out Examples for complete scenario use cases