Skip to main content

Plugin Testing Framework

The Plugin Testing Framework (@ever-works/plugin/testing) provides a complete test infrastructure for plugin development. It includes a test harness for loading and exercising plugins, mock implementations of all plugin runtime services, environment simulation utilities, and contract test suites that validate plugin implementations against the platform's capability interfaces.

Package Overview​

PropertyValue
Import path@ever-works/plugin/testing
Locationplatform/packages/plugin/src/testing/
DependenciesPlugin contracts, plugin lifecycle types
Used byAll plugin test suites

Module Exports​

export { PluginTestHarness } from './plugin-test-harness.js';
export {
createMockPluginContext,
createMockLogger,
createMockCache,
createMockHttpClient,
createMockServices,
createMockFn
} from './mock-plugin-context.js';
export {
createMockPluginEnvironment,
createMockEnvVars,
createProductionEnvironment,
createDevelopmentEnvironment
} from './mock-plugin-environment.js';
export {
testBasePluginContract,
testGitProviderContract,
testDeploymentContract,
testScreenshotContract,
testSearchContract,
testAiProviderContract,
testPipelineContract,
testPipelineModifierContract,
runContractTests
} from './contract-tests.js';

PluginTestHarness​

The PluginTestHarness class provides a controlled environment for testing plugin lifecycle and behavior. It manages plugin loading, activation, deactivation, and provides built-in assertions.

Creating a Harness​

import { PluginTestHarness } from '@ever-works/plugin/testing';
import { MyPlugin } from '../src/my-plugin';

const harness = new PluginTestHarness(MyPlugin);

Lifecycle Methods​

MethodDescription
load(context?)Instantiate the plugin and call onLoad
unload()Call onDeactivate and clean up
healthCheck()Run the plugin's health check and return result
// Full lifecycle test
const harness = new PluginTestHarness(MyPlugin);

await harness.load(mockContext);
const health = await harness.healthCheck();
// health => { healthy: true }

await harness.unload();

Test Runner​

The harness includes a built-in test runner that executes named test cases and collects results.

const results = await harness.runTests([
{
name: 'should activate successfully',
fn: async (plugin) => {
await plugin.onActivate(mockContext);
harness.assert(plugin.isActive(), 'Plugin should be active');
}
},
{
name: 'should handle missing settings',
fn: async (plugin) => {
const ctx = createMockPluginContext({ settings: {} });
await harness.assertRejects(() => plugin.onActivate(ctx), 'Should throw on missing settings');
}
}
]);

// results => [
// { name: 'should activate successfully', passed: true },
// { name: 'should handle missing settings', passed: true },
// ]

Built-in Assertions​

AssertionDescription
assert(condition, message?)Assert a boolean condition is truthy
assertEqual(actual, expected, message?)Assert strict equality (===)
assertDeepEqual(actual, expected, message?)Assert structural equality (deep comparison)
assertRejects(fn, message?)Assert an async function throws an error
harness.assert(result !== null, 'Result should not be null');
harness.assertEqual(result.status, 'success', 'Status should be success');
harness.assertDeepEqual(result.data, { id: '1', name: 'test' });
await harness.assertRejects(() => plugin.doInvalidThing());

Lifecycle Tests​

The harness provides a runLifecycleTests method that automatically tests the standard plugin lifecycle sequence:

const lifecycleResults = await harness.runLifecycleTests(mockContext);
// Tests: load, activate, health check, deactivate, unload

Mock Plugin Context​

The mock-plugin-context.ts module provides factory functions for creating mock implementations of all plugin runtime services.

createMockPluginContext​

Creates a complete mock PluginContext with all services pre-configured.

import { createMockPluginContext } from '@ever-works/plugin/testing';

const context = createMockPluginContext({
settings: {
apiKey: 'test-key',
model: 'gpt-4'
},
workSettings: {
model: 'gpt-3.5-turbo'
},
envVars: {
NODE_ENV: 'test'
}
});

// context.logger => mock logger
// context.cache => mock cache (Map-based)
// context.httpClient => mock HTTP client
// context.settings => { apiKey: 'test-key', model: 'gpt-4' }

createMockLogger​

Creates a mock logger that captures all log calls for assertion.

import { createMockLogger } from '@ever-works/plugin/testing';

const logger = createMockLogger();
logger.info('Test message');
logger.error('Error occurred', { code: 500 });

// All methods available: trace, debug, info, warn, error, fatal
// Each captures calls for later inspection

createMockCache​

Creates an in-memory cache backed by a Map with TTL support.

import { createMockCache } from '@ever-works/plugin/testing';

const cache = createMockCache();

await cache.set('key', 'value', 60); // TTL: 60 seconds
const value = await cache.get('key');
// value => 'value'

await cache.delete('key');
const deleted = await cache.get('key');
// deleted => undefined

Cache Features:

FeatureBehavior
StorageIn-memory Map<string, { value, expiry }>
TTLStored as Date.now() + ttlSeconds * 1000
Expiry checkget() returns undefined for expired entries
has()Checks existence and expiry
delete()Removes entry from map
clear()Clears entire map

createMockHttpClient​

Creates a mock HTTP client that returns configurable responses.

import { createMockHttpClient } from '@ever-works/plugin/testing';

const httpClient = createMockHttpClient();

// Default: returns { status: 200, data: {} }
const response = await httpClient.get('https://api.example.com/data');

createMockServices​

Creates a complete set of mock platform services.

import { createMockServices } from '@ever-works/plugin/testing';

const services = createMockServices();
// services.logger, services.cache, services.httpClient, etc.

createMockFn​

Creates a mock function compatible with both Jest and Vitest patterns.

import { createMockFn } from '@ever-works/plugin/testing';

const fn = createMockFn();
fn('arg1', 'arg2');

// fn.calls => [['arg1', 'arg2']]
// fn.callCount => 1

Mock Plugin Environment​

The mock-plugin-environment.ts module provides utilities for simulating different runtime environments.

createMockPluginEnvironment​

Creates a complete mock environment with configurable properties.

import { createMockPluginEnvironment } from '@ever-works/plugin/testing';

const env = createMockPluginEnvironment({
nodeEnv: 'production',
platform: 'linux',
version: '1.5.0'
});

createMockEnvVars​

Creates a mock environment variables object with common defaults.

import { createMockEnvVars } from '@ever-works/plugin/testing';

const envVars = createMockEnvVars({
OPENAI_API_KEY: 'sk-test-key',
DATABASE_URL: 'postgres://localhost/test'
});
// Also includes NODE_ENV: 'test' by default

Preset Environments​

FunctionNODE_ENVDebugDescription
createProductionEnvironment()productionfalseSimulates production deployment
createDevelopmentEnvironment()developmenttrueSimulates local development

Contract Tests​

The contract-tests.ts module provides reusable test suites that validate plugin implementations against the platform's capability interfaces. Each contract test suite ensures that a plugin correctly implements the methods, return types, and error handling required by its declared capabilities.

Available Contract Test Suites​

FunctionTestsDescription
testBasePluginContract(plugin)onLoad, onActivate, onDeactivate, manifestCore plugin lifecycle
testGitProviderContract(plugin)clone, push, pull, branch, PR operationsGit provider capability
testDeploymentContract(plugin)deploy, status, rollbackDeployment capability
testScreenshotContract(plugin)capture, format optionsScreenshot capability
testSearchContract(plugin)search, results format, paginationSearch capability
testAiProviderContract(plugin)chat, streaming, embeddings, modelsAI provider capability
testPipelineContract(plugin)execute, step handling, status reportingPipeline capability
testPipelineModifierContract(plugin)modify, transform, validatePipeline modifier capability

Running Contract Tests​

import { testBasePluginContract, testAiProviderContract } from '@ever-works/plugin/testing';

describe('MyAiPlugin', () => {
const plugin = new MyAiPlugin();
const context = createMockPluginContext({ settings: testSettings });

testBasePluginContract(plugin);
testAiProviderContract(plugin);
});

runContractTests​

A convenience function that automatically detects a plugin's declared capabilities and runs all applicable contract test suites.

import { runContractTests } from '@ever-works/plugin/testing';

const results = await runContractTests(plugin, mockContext);
// Automatically runs base + capability-specific contract tests
// results => { passed: 15, failed: 0, skipped: 2, details: [...] }

Testing Patterns​

Full Plugin Integration Test​

import { PluginTestHarness, createMockPluginContext, testBasePluginContract } from '@ever-works/plugin/testing';

describe('GitHubPlugin', () => {
let harness: PluginTestHarness;
let context: PluginContext;

beforeEach(() => {
harness = new PluginTestHarness(GitHubPlugin);
context = createMockPluginContext({
settings: { token: 'ghp_test', defaultOrg: 'test-org' }
});
});

afterEach(async () => {
await harness.unload();
});

testBasePluginContract(new GitHubPlugin());

it('should clone a repository', async () => {
await harness.load(context);
const plugin = harness.getPlugin();
const dir = await plugin.cloneRepository('owner', 'repo');
harness.assert(dir !== null, 'Should return work path');
});
});

File Structure​

plugin/src/testing/
index.ts # Public exports
plugin-test-harness.ts # PluginTestHarness class
mock-plugin-context.ts # Mock context, logger, cache, HTTP, services
mock-plugin-environment.ts # Mock environments and env vars
contract-tests.ts # Capability contract test suites