New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@go-corp/test-framework

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@go-corp/test-framework

Test framework utilities for Cloudflare Workers and Hono applications

latest
Source
npmnpm
Version
1.0.5
Version published
Maintainers
1
Created
Source

@go-corp/test-framework

🧪 The Ultimate Hybrid Test Framework for Modern Web Applications

A comprehensive, multi-runtime test framework designed for Cloudflare Workers, Node.js, and Bun applications with Hono, featuring smart data factories, automatic database management, and interactive test running.

🎯 What We've Built

🏗️ Hybrid Test Framework (@go-corp/test-framework)

Multi-Runtime Support: Works seamlessly with Cloudflare Workers, Node.js, and Bun
Environment-Agnostic: Adapters for D1, SQLite, in-memory, and Drizzle databases
NPM Ready: Complete package structure for publishing and reuse across projects

✨ Key Features

  • Interactive Test Runner 🎮 - CLI with selectable test categories and runtime detection
  • Smart Data Factory 🏭 - Seeded random generation for consistent, realistic test data
  • Test Store Management 🗄️ - Automatic cleanup and state isolation
  • HTTP Test Client 🌐 - Full-featured API testing with session management
  • Vitest Integration ⚡ - Built-in helpers for automatic test isolation
  • Database Adapters 💾 - Support for multiple database providers with automatic detection
  • Environment Detection 🔍 - Automatic runtime and capability detection

💡 Hybrid Approach Benefits

Fast Unit Tests: Memory database for rapid development
Integration Tests: SQLite for realistic database interactions
E2E Tests: Full Cloudflare Workers environment for production-like testing
Flexible Runtime Detection: Automatically adapts to your environment

Installation

bun add --dev @go-corp/test-framework

Quick Start

Basic Setup

// test/setup.ts
import { setupCloudflareWorkerTests } from '@go-corp/test-framework'

// Sets up console mocking and required environment variables
setupCloudflareWorkerTests()

Simple Request Testing

import { requestWithCookies, postJSON } from '@go-corp/test-framework'
import app from '../src/app'

test('user authentication flow', async () => {
  // All requests automatically persist cookies
  const { json: user } = await postJSON(app, '/api/auth/sign-in', {
    body: { email: 'test@example.com', password: 'password' }
  })
  
  // Session cookie is automatically included in subsequent requests
  const { json: profile } = await requestJSON(app, '/api/profile', {
    method: 'GET'
  }, { expected: 200 })
  
  expect(profile.email).toBe('test@example.com')
})

Modern API Usage

// Modern setup with enhanced features
import { 
  setupTestFramework, 
  TestDataFactory,
  createHttpTestClient,
  dbTest,
  factoryTest 
} from '@go-corp/test-framework'
import app from '../src/app'

// Configure test framework
setupTestFramework({
  app,
  database: 'sqlite',
  isolation: 'test',
  autoCleanup: true
})

// Database test with automatic cleanup
dbTest('user creation with database', async (db) => {
  const factory = new TestDataFactory()
  const userData = factory.user()
  
  // Insert user into database
  await db.insert(users).values(userData)
  
  // Test API endpoint
  const client = createHttpTestClient(app)
  const { response, json } = await client.getJSON(`/api/users/${userData.id}`)
  
  expect(response.status).toBe(200)
  expect(json.email).toBe(userData.email)
})

// Factory test with seeded data
factoryTest('consistent test data', async (factory) => {
  const user1 = factory.user()
  const user2 = factory.user()
  
  // Same seed produces consistent data across test runs
  expect(user1.id).toBeDefined()
  expect(user2.id).toBeDefined()
  expect(user1.id).not.toBe(user2.id)
}, 12345) // Custom seed

Core Testing Utilities

Request Helpers

requestWithCookies(app, path, init?, jarKey?)

Makes a request with automatic cookie persistence across test requests.

import { requestWithCookies, resetCookies } from '@go-corp/test-framework'

// Start with clean session
resetCookies()

// Login request sets session cookie
const loginRes = await requestWithCookies(app, '/api/auth/login', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ username: 'test', password: 'pass' })
})

// Subsequent requests automatically include session cookie
const profileRes = await requestWithCookies(app, '/api/profile')

requestJSON(app, path, init, options?)

Request helper that automatically parses JSON and validates status codes.

// Expect 200 status (default)
const { res, json } = await requestJSON(app, '/api/users', {
  method: 'GET'
})

// Expect specific status
const { json: error } = await requestJSON(app, '/api/invalid', {
  method: 'GET'
}, { expected: 404 })

// Accept multiple status codes
const { json } = await requestJSON(app, '/api/endpoint', {
  method: 'POST',
  body: JSON.stringify(data)
}, { expected: [200, 201] })

postJSON(app, path, options?)

Convenience wrapper for POST requests with JSON body.

// Simple POST
const { json } = await postJSON(app, '/api/users', {
  body: { name: 'John', email: 'john@example.com' }
})

// With status validation
const { json } = await postJSON(app, '/api/users', {
  body: { name: 'John' },
  expected: 201
})

Session Management

Multiple Test Sessions

Use different jarKey values to isolate test sessions:

import { requestWithCookies, resetCookies } from '@go-corp/test-framework'

test('concurrent user sessions', async () => {
  // User A login
  await postJSON(app, '/api/auth/login', {
    body: { username: 'userA' },
    jarKey: 'sessionA'
  })
  
  // User B login  
  await postJSON(app, '/api/auth/login', {
    body: { username: 'userB' },
    jarKey: 'sessionB'
  })
  
  // Each user sees their own profile
  const { json: profileA } = await requestJSON(app, '/api/profile', {}, {
    jarKey: 'sessionA'
  })
  const { json: profileB } = await requestJSON(app, '/api/profile', {}, {
    jarKey: 'sessionB'
  })
  
  expect(profileA.username).toBe('userA')
  expect(profileB.username).toBe('userB')
})

Test Context

Create isolated test contexts with automatic cleanup:

import { createTestContext } from '@go-corp/test-framework'

test('isolated test context', async () => {
  const ctx = createTestContext()
  
  // All requests use isolated cookie jar
  await ctx.postJSON(app, '/api/auth/login', {
    body: { username: 'test' }
  })
  
  const { json } = await ctx.requestJSON(app, '/api/profile', {})
  expect(json.username).toBe('test')
  
  // Clean up (optional, happens automatically)
  ctx.reset()
})

Email Testing

Test email functionality with built-in assertion helpers.

Basic Email Testing

import { 
  clearOutbox, 
  assertEmailSent, 
  extractVerificationLink 
} from '@go-corp/test-framework'

test('password reset flow', async () => {
  await clearOutbox(app)
  
  // Trigger password reset
  await postJSON(app, '/api/auth/reset-password', {
    body: { email: 'user@example.com' }
  })
  
  // Assert email was sent
  const email = await assertEmailSent(app, 'user@example.com')
  expect(email.subject).toContain('Password Reset')
  
  // Extract and use verification link
  const resetLink = extractVerificationLink(email)
  expect(resetLink).toBeTruthy()
  
  // Test the verification link
  const { json } = await requestJSON(app, resetLink!)
  expect(json.message).toBe('Reset link verified')
})

Advanced Email Testing

import { 
  getOutbox,
  getLastEmail,
  waitForEmail,
  extractOTPCode
} from '@go-corp/test-framework'

test('email verification with OTP', async () => {
  await clearOutbox(app)
  
  // Trigger account creation
  await postJSON(app, '/api/auth/register', {
    body: { email: 'new@example.com' }
  })
  
  // Wait for email (useful for async operations)
  const email = await waitForEmail(app, 'new@example.com', 3000)
  
  // Extract OTP code
  const otpCode = extractOTPCode(email)
  expect(otpCode).toBeTruthy()
  
  // Verify with OTP
  const { json } = await postJSON(app, '/api/auth/verify-otp', {
    body: { email: 'new@example.com', code: otpCode }
  })
  
  expect(json.verified).toBe(true)
})

Test Environment Setup

Basic Setup

import { setupCloudflareWorkerTests } from '@go-corp/test-framework'

// Automatic setup with sensible defaults
setupCloudflareWorkerTests()

Custom Setup

import { setupTestEnvironment } from '@go-corp/test-framework'

setupTestEnvironment({
  mockConsole: true,
  consoleMethods: ['log', 'info', 'debug'],
  env: {
    API_KEY: 'test-key',
    DATABASE_URL: 'test-db'
  },
  cleanup: [
    () => {
      // Custom cleanup logic
    }
  ]
})

Environment Variables

import { ensureTestEnv, withTestEnv } from '@go-corp/test-framework'

// Ensure variables exist with defaults
ensureTestEnv({
  RESEND_API_KEY: 'test-key',
  NODE_ENV: 'test'
})

// Run test with specific environment
const testWithEnv = withTestEnv({
  FEATURE_FLAG: 'enabled'
}, async () => {
  // Test logic here
  const { json } = await requestJSON(app, '/api/feature')
  expect(json.enabled).toBe(true)
})

await testWithEnv()

Time Mocking

import { createTimeMock } from '@go-corp/test-framework'

test('time-sensitive operations', async () => {
  const mockTime = createTimeMock(new Date('2024-01-01'))
  mockTime.start()
  
  // Create token that expires in 1 hour
  const { json: token } = await postJSON(app, '/api/auth/token')
  
  // Advance time by 2 hours
  mockTime.advance(2 * 60 * 60 * 1000)
  
  // Token should now be expired
  const { json } = await requestJSON(app, '/api/auth/verify', {
    headers: { authorization: \`Bearer \${token.access_token}\` }
  }, { expected: 401 })
  
  expect(json.error).toBe('Token expired')
  
  mockTime.restore()
})

Utility Functions

Unique Data Generation

import { uniqueEmail, uniqueUsername } from '@go-corp/test-framework'

test('user creation', async () => {
  const email = uniqueEmail() // test+1@example.com
  const username = uniqueUsername() // user1
  
  await postJSON(app, '/api/users', {
    body: { email, username }
  })
})

Wait Utility

import { wait } from '@go-corp/test-framework'

test('async operations', async () => {
  // Trigger async operation
  await postJSON(app, '/api/process')
  
  // Wait for processing
  await wait(1000)
  
  // Check result
  const { json } = await requestJSON(app, '/api/status')
  expect(json.status).toBe('completed')
})

API Reference

Database Adapters

  • createDatabaseAdapter(type, config?) - Create database adapter for tests
  • MemoryDatabaseAdapter, SqliteDatabaseAdapter, D1DatabaseAdapter - Database implementations
  • DrizzleSqliteAdapter, DrizzleD1Adapter - Drizzle ORM integrations

Test Data Factory

  • TestDataFactory - Seeded data generation for consistent tests
  • factory.user(), factory.organization(), factory.post() - Built-in generators
  • createSeededFactory(seed) - Factory with custom seed

Enhanced HTTP Client

  • HttpTestClient - Full-featured test client with retries and cookies
  • createHttpTestClient(app, options) - Create HTTP client instance

Vitest Integration

  • setupTestFramework(config) - Configure test environment
  • testSuite(name, fn, config) - Enhanced test suite with setup
  • testWithContext(name, fn) - Test with isolated context
  • dbTest(name, fn) - Database test with cleanup
  • httpTest(name, fn) - HTTP test with session isolation
  • factoryTest(name, fn, seed?) - Test with seeded data factory

Legacy API (Compatibility)

Core Functions

  • requestWithCookies(app, path, init?, jarKey?) - Make request with cookie persistence
  • requestJSON(app, path, init, options?) - Request with JSON parsing and status validation
  • postJSON(app, path, options?) - POST request convenience wrapper
  • resetCookies(jarKey?) - Clear cookies for jar key or all jars
  • createTestContext(jarKey?) - Create isolated test context

Email Functions

  • getOutbox(app, jarKey?) - Get all emails from test outbox
  • clearOutbox(app, jarKey?) - Clear test email outbox
  • getLastEmail(app, recipient, jarKey?) - Get most recent email to recipient
  • waitForEmail(app, recipient, timeout?, jarKey?) - Wait for email to be sent
  • assertEmailSent(app, recipient, jarKey?) - Assert email was sent
  • extractVerificationLink(email) - Extract verification URL from email
  • extractOTPCode(email) - Extract OTP code from email

Setup Functions

  • setupCloudflareWorkerTests() - Default setup for Cloudflare Workers
  • setupTestEnvironment(options?) - Custom test environment setup
  • ensureTestEnv(vars) - Ensure environment variables exist
  • withTestEnv(env, fn) - Run function with specific environment

Utility Functions

  • uniqueEmail(prefix?) - Generate unique email address
  • uniqueUsername(prefix?) - Generate unique username
  • wait(ms) - Wait for specified milliseconds
  • createTimeMock(date?) - Create time mock for testing

TypeScript Support

The package includes comprehensive TypeScript definitions for all APIs:

// Core types
import type { 
  Runtime,
  DatabaseProvider,
  TestEnvironmentConfig,
  HonoApp
} from '@go-corp/test-framework'

// HTTP testing types
import type {
  TestRequestOptions,
  TestResponse,
  HttpClientOptions
} from '@go-corp/test-framework'

// Email testing types
import type {
  TestEmail,
  TestSetupOptions
} from '@go-corp/test-framework'

// Factory types
import type {
  FactoryConfig,
  FactoryFunction,
  TestDataGenerators
} from '@go-corp/test-framework'

// Store and lifecycle types
import type {
  TestStore,
  IsolationLevel,
  VitestConfig,
  TestSuiteConfig,
  TestRunnerConfig
} from '@go-corp/test-framework'

// Database adapter type
import type {
  DatabaseAdapter
} from '@go-corp/test-framework'

🛠️ Development

# Install dependencies
bun install

# Build for development
bun run dev

# Type check
bun run typecheck

# Lint code
bun run lint
bun run lint:fix

# Test the CLI
bun run test-runner --help

🚀 Release Management

This project uses @go-corp/workflow for automated release management:

# Interactive release (quality gates, git, npm)
bun run release

# Dry run (show what would happen)
bun run release --dry-run

# Skip specific deployments
bun run release --skip-npm --skip-cloudflare

# Force specific version bump
bun run release --type minor

# Check workflow status
bun run workflow:status

Release Pipeline:

  • Quality Gates: Auto-fix linting, type checking, tests
  • 🏷️ Version Management: Smart semantic versioning with changelog
  • 📦 Build & Publish: Automated npm publishing with confirmation
  • 🔗 GitHub Integration: Automated releases and tagging

License

MIT

Keywords

testing

FAQs

Package last updated on 18 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts