Files
payload-automation/dev/test-setup.ts
Bas van den Aakster 74217d532d Implement independent error storage system and comprehensive improvements
Major Features:
• Add persistent error tracking for timeout/network failures that bypasses PayloadCMS output limitations
• Implement smart error classification (timeout, DNS, connection, network) with duration-based detection
• Add comprehensive test infrastructure with MongoDB in-memory testing and enhanced mocking
• Fix HTTP request handler error preservation with detailed context storage
• Add independent execution tracking with success/failure status and duration metrics

Technical Improvements:
• Update JSONPath documentation to use correct $.trigger.doc syntax across all step types
• Fix PayloadCMS job execution to use runByID instead of run() for reliable task processing
• Add enhanced HTTP error handling that preserves outputs for 4xx/5xx status codes
• Implement proper nock configuration with undici for Node.js 22 fetch interception
• Add comprehensive unit tests for WorkflowExecutor with mocked PayloadCMS instances

Developer Experience:
• Add detailed error information in workflow context with URL, method, timeout, attempts
• Update README with HTTP error handling patterns and enhanced error tracking examples
• Add test helpers and setup infrastructure for reliable integration testing
• Fix workflow step validation and JSONPath field descriptions

Breaking Changes: None - fully backward compatible

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 18:03:30 +02:00

125 lines
2.9 KiB
TypeScript

import { MongoMemoryReplSet } from 'mongodb-memory-server'
import { getPayload } from 'payload'
import type { Payload } from 'payload'
import nock from 'nock'
import config from './payload.config.js'
// Configure nock to intercept fetch requests properly in Node.js 22
nock.disableNetConnect()
nock.enableNetConnect('127.0.0.1')
// Set global fetch to use undici for proper nock interception
import { fetch } from 'undici'
global.fetch = fetch
let mongod: MongoMemoryReplSet | null = null
let payload: Payload | null = null
// Global test setup - runs once for all tests
beforeAll(async () => {
// Start MongoDB in-memory replica set
mongod = await MongoMemoryReplSet.create({
replSet: {
count: 1,
dbName: 'payload-test',
},
})
const mongoUri = mongod.getUri()
process.env.DATABASE_URI = mongoUri
console.log('🚀 MongoDB in-memory server started:', mongoUri)
// Initialize Payload with test config
payload = await getPayload({
config: await config,
local: true
})
console.log('✅ Payload initialized for testing')
}, 60000)
// Global test teardown - runs once after all tests
afterAll(async () => {
if (payload) {
console.log('🛑 Shutting down Payload...')
// Payload doesn't have a shutdown method, but we can clear the cache
delete (global as any).payload
payload = null
}
if (mongod) {
console.log('🛑 Stopping MongoDB in-memory server...')
await mongod.stop()
mongod = null
}
}, 30000)
// Export payload instance for tests
export const getTestPayload = () => {
if (!payload) {
throw new Error('Payload not initialized. Make sure test setup has run.')
}
return payload
}
// Helper to clean all collections
export const cleanDatabase = async () => {
if (!payload) return
try {
// Clean up workflow runs first (child records)
const runs = await payload.find({
collection: 'workflow-runs',
limit: 1000
})
for (const run of runs.docs) {
await payload.delete({
collection: 'workflow-runs',
id: run.id
})
}
// Clean up workflows
const workflows = await payload.find({
collection: 'workflows',
limit: 1000
})
for (const workflow of workflows.docs) {
await payload.delete({
collection: 'workflows',
id: workflow.id
})
}
// Clean up audit logs
const auditLogs = await payload.find({
collection: 'auditLog',
limit: 1000
})
for (const log of auditLogs.docs) {
await payload.delete({
collection: 'auditLog',
id: log.id
})
}
// Clean up posts
const posts = await payload.find({
collection: 'posts',
limit: 1000
})
for (const post of posts.docs) {
await payload.delete({
collection: 'posts',
id: post.id
})
}
} catch (error) {
console.warn('Database cleanup failed:', error)
}
}