mocha-multiple-sessions-ts
v1.0.1
Published
TypeScript library for running multiple Mocha test sessions in the browser
Maintainers
Readme
Mocha Multiple Sessions - TypeScript Edition
A clean architecture TypeScript library for running multiple Mocha test sessions in the browser with full type safety and modern API design.
Features
- 🔥 Multiple Test Sessions: Run independent Mocha test sessions in a single browser window
- 🎯 TypeScript First: Full type safety with comprehensive TypeScript interfaces
- 🏗️ Clean Architecture: Dependency injection, use cases, and separation of concerns
- 🎨 Multiple APIs: Functional API, Object-Oriented API, and Legacy compatibility
- ⚡ Vite Integration: Hot module reloading during development
- 📊 Real-time Events: Listen to test execution events as they happen
- 🔧 Flexible Configuration: Customize Mocha instances, reporters, and execution options
- 📦 Multiple Build Formats: ESM, CommonJS, IIFE for different environments
Quick Start
Development Setup
# Clone and install dependencies
npm install
# Start development server with Vite
npm run dev
# Opens http://localhost:3000/basic-usage.htmlProduction Build
# Build all formats
npm run build
# Output files:
# build/esm-bundled/mocha-multiple-sessions.mjs # ES modules
# build/cjs/mocha-multiple-sessions.js # CommonJS
# build/iife/mocha-multiple-sessions.js # Browser global
# build/iife/mocha-multiple-sessions.min.js # Minified
# build/types/index.d.ts # TypeScript definitionsExamples
The examples/ directory contains comprehensive usage examples:
Built Library Examples
- ESM Example (
examples/basic-esm.html) - Modern ES module usage - IIFE Example (
examples/basic-iife.html) - Browser global usage - Advanced Features (
examples/advanced-features.html) - Full API demonstration - CDN Usage (
examples/cdn-usage.html) - Production CDN integration
Development Examples
- Basic Usage (
test/browser-samples/basic-usage.html) - TypeScript dev version - Advanced Usage (
test/browser-samples/advanced-usage.html) - Complex scenarios - Legacy Usage (
test/browser-samples/legacy-usage.html) - Backward compatibility
# Run development examples
npm run dev
# Run built examples
npm run build
npx serve . -p 3001
# Open http://localhost:3001/examples/API Reference
Functional API (Recommended)
Basic Usage
import {
testSession,
runSession,
testSessionSetup
} from './src/index.ts';
// Configure the test environment (optional)
testSessionSetup({
createMochaInstance: (sessionLabel) => {
return new Mocha({
ui: 'bdd',
reporter: Mocha.reporters.HTML
});
}
});
// Create a test session
await testSession('my-tests', () => {
describe('My Test Suite', () => {
it('should pass', () => {
chai.expect(true).to.be.true;
});
it('should handle async tests', async () => {
const result = await Promise.resolve(42);
chai.expect(result).to.equal(42);
});
});
});
// Run the session
const result = await runSession('my-tests');
console.log(`Tests: ${result.stats.tests}, Passes: ${result.stats.passes}`);API Reference
Functional API (Recommended)
Configuration
// Set up the test environment
testSessionSetup(config: Partial<ITestEnvironment>): void
// Get current environment configuration
getTestEnvironment(): ITestEnvironmentSession Management
// Create a test session
testSession(
label: string,
setupFn: () => void | Promise<void>,
options?: TestSessionOptions
): Promise<string>
// Run a specific session
runSession(label: string): Promise<ISessionExecutionResult>
// Run all sessions
runAllSessions(): Promise<SessionResult[]>
// Query sessions
getSession(label: string): ITestSession | null
getAllSessions(): ITestSession[]Event System
// Listen to specific events
onSessionEvent(eventType: SessionEventType, callback: Function): void
// Listen to all events
onAnySessionEvent(callback: (event: SessionEvent) => void): void
// Remove event listeners
offSessionEvent(eventType: SessionEventType, callback: Function): voidUtilities
// Load external scripts
loadScript(scriptPath: string, options?: ScriptLoaderOptions): Promise<string>
loadScripts(scriptPaths: string[], options?: ScriptLoaderOptions): Promise<string[]>Object-Oriented API (Advanced)
SessionManager
import { SessionManager } from './src/index.ts';
const manager = new SessionManager({
autoCleanup: true,
defaultSessionOptions: { expandFailures: true }
});
// Create multiple sessions
const sessions = await manager.createSessions([
{
label: 'unit-tests',
setupFn: () => {
describe('Unit Tests', () => {
it('should work', () => chai.expect(1).to.equal(1));
});
}
},
{
label: 'integration-tests',
setupFn: () => {
describe('Integration Tests', () => {
it('should integrate', () => chai.expect(true).to.be.true);
});
}
}
]);
// Run all sessions in parallel
const results = await manager.runAll({ parallel: true });
// Get statistics
const stats = manager.getStats();
console.log(`Total: ${stats.total}, Completed: ${stats.completed}`);ManagedSession
import { SessionManager } from './src/index.ts';
const manager = new SessionManager();
const session = manager.getSession('my-tests');
if (session) {
// Run with timeout
const result = await session.runWithTimeout(5000);
// Listen to session events
const unsubscribe = session.onAnyEvent((event) => {
console.log(`[${session.label}] ${event.type}:`, event.data);
});
// Clean up
unsubscribe();
}SessionBuilder (Fluent API)
import { SessionManager, SessionBuilder } from './src/index.ts';
const manager = new SessionManager();
const builder = new SessionBuilder(manager);
const result = await builder
.withLabel('fluent-tests')
.withTimeout(8000)
.withRetries(1)
.withMetadata('testType', 'integration')
.describe('Fluent Tests', () => {
it('should build fluently', () => {
chai.expect('fluent').to.have.length(6);
});
})
.buildAndRun();Legacy API (Deprecated but Supported)
import { legacyRunSession, legacyRunMultipleSessions } from './src/index.ts';
// Single session (legacy)
const result = await legacyRunSession(
'test-label',
'results_key',
['/path/to/test-file.js'],
'mocha-container',
{ theme: 'light' }
);
// Multiple sessions (legacy)
const results = await legacyRunMultipleSessions([
{
label: 'session1',
resultKey: 'results1',
testFiles: ['/tests1.js']
},
{
label: 'session2',
resultKey: 'results2',
testFiles: ['/tests2.js']
}
], 'mocha-container', { theme: 'light' });Configuration Options
TestSessionOptions
interface TestSessionOptions {
timeout?: number; // Default: 5000ms
retries?: number; // Default: 0
metadata?: Record<string, any>; // Custom metadata
}Example: Configuring Test Environment
import { testSessionSetup } from './src/index.ts';
testSessionSetup({
createMochaInstance: (sessionLabel) => {
return new Mocha({
ui: 'bdd',
reporter: 'html', // Choose your reporter
timeout: 5000,
slow: 2000,
// All Mocha configuration here
reporterOptions: {
// Reporter-specific options
outputToWindow: true,
windowVariableName: `results_${sessionLabel}`
}
});
},
injectGlobals: (mochaInstance) => {
// Set up globals as needed
mochaInstance.suite.emit('pre-require', window, null, mochaInstance);
if (window.chai) {
window.expect = window.chai.expect;
}
}
});Basic Usage (Updated)
// Create a session with simplified options
await testSession('my-tests', () => {
describe('My Test Suite', () => {
it('should pass', () => {
chai.expect(true).to.be.true;
});
});
}, {
timeout: 10000,
retries: 2,
metadata: { priority: 'high' }
});SessionBuilder (Updated)
const result = await builder
.withLabel('fluent-tests')
.withTimeout(8000)
.withRetries(1)
.withMetadata('testType', 'integration')
.describe('Fluent Tests', () => {
it('should build fluently', () => {
chai.expect('fluent').to.have.length(6);
});
})
.buildAndRun();Event System
Event Types
type SessionEventType =
| 'session:created'
| 'session:started'
| 'session:completed'
| 'session:failed'
| 'session:execution-started'
| 'session:execution-completed'
| 'test:pass'
| 'test:fail'
| 'script:loading'
| 'script:loaded'
| 'script:failed';Event Handling
import { onAnySessionEvent } from './src/index.ts';
onAnySessionEvent((event) => {
console.log(`[${event.type}] ${event.sessionLabel}:`, event.data);
switch (event.type) {
case 'session:completed':
console.log('Session finished:', event.data.stats);
break;
case 'test:pass':
console.log('Test passed:', event.data.testTitle);
break;
case 'test:fail':
console.log('Test failed:', event.data.error);
break;
}
});Development Samples
Available Browser Samples
Basic Usage (
/basic-usage.html)- Simple session creation and execution
- Real-time event logging
- TypeScript imports with Vite
Advanced Usage (
/advanced-usage.html)- Multiple sessions with custom configurations
- Sequential vs parallel execution
- Custom environment setup
Legacy Usage (
/legacy-usage.html)- Backward compatibility demonstrations
- Migration examples from old API
Running Samples
# Start dev server
npm run dev
# Open specific samples
# http://localhost:3000/basic-usage.html
# http://localhost:3000/advanced-usage.html
# http://localhost:3000/legacy-usage.htmlProject Structure
src/
├── index.ts # Main entry point
├── interfaces/ # TypeScript interfaces
│ ├── api/ # API interfaces
│ ├── core/ # Core domain interfaces
│ ├── events/ # Event system interfaces
│ ├── test-environment/ # Test environment interfaces
│ └── utils/ # Utility interfaces
├── impl/ # Implementation classes
│ ├── api/ # API implementations
│ ├── core/ # Core business logic
│ ├── di/ # Dependency injection
│ ├── events/ # Event system
│ ├── test-environment/ # Browser test environment
│ ├── use-cases/ # Application use cases
│ └── utils/ # Utilities
test/
├── browser-samples/ # HTML samples with Vite
├── test-files/ # Sample test files
└── ...TypeScript Types
Core Types
// Session execution result
interface ISessionExecutionResult {
sessionId: string;
sessionLabel: string;
stats: TestSessionStats;
success: boolean;
error?: Error;
duration: number;
}
// Test statistics
interface TestSessionStats {
tests: number;
passes: number;
pending: number;
failures: number;
}
// Session result for batch operations
interface SessionResult {
label: string;
result: SessionExecutionResult | null;
error?: string;
}Browser Requirements
- Modern browser with ES2020+ support
- Mocha 10.x (loaded via CDN or bundled)
- Chai 4.x (loaded via CDN or bundled)
- Optional: MochaDetailedReporter for enhanced reporting
Integration Examples
Development (Vite)
<script type="module">
import { testSession, runSession } from './src/index.ts';
// Use directly in development with TypeScript
</script>Production - ESM
<script type="module">
import { testSession, runSession } from './build/esm-bundled/mocha-multiple-sessions.mjs';
</script>Production - IIFE (Browser Global)
<script src="./build/iife/mocha-multiple-sessions.min.js"></script>
<script>
const { testSession, runSession } = MochaMultipleSessions;
</script>CDN Usage (when published)
<script src="https://unpkg.com/[email protected]/build/iife/mocha-multiple-sessions.min.js"></script>
<script>
const { testSession, runSession } = MochaMultipleSessions;
</script>With Module Bundlers
// After npm install
import { testSession, runSession } from 'mocha-multiple-sessions-ts';Migration from JavaScript Version
Old API → New API
// OLD (JavaScript)
await runSessionAPI('label', 'resultKey', ['/test.js'], 'container');
// NEW (TypeScript)
await testSession('label', async () => {
await loadScript('/test.js');
});
await runSession('label');Gradual Migration
The library provides full backward compatibility through the Legacy API, allowing gradual migration:
// Step 1: Use legacy API with TypeScript
import { legacyRunSession } from './src/index.ts';
// Step 2: Gradually migrate to modern API
import { testSession, runSession } from './src/index.ts';Contributing
# Development
npm run dev
# Type checking
npx tsc --noEmit
# Build
npm run buildLicense
MIT
