@elizaos/cli 1.3.2 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/{bun-exec-6CQHTS4F.js → bun-exec-ULMPAIQC.js} +1 -1
- package/dist/{chunk-E6XYTE3A.js → chunk-D3QSET5H.js} +69 -72
- package/dist/{chunk-FDEDLANP.js → chunk-FQYWRHLX.js} +1 -1
- package/dist/{chunk-T2QDIXGU.js → chunk-FSSUAWXQ.js} +3 -3
- package/dist/{chunk-D3Q2UZLZ.js → chunk-I4L4T7QX.js} +1 -1
- package/dist/{chunk-5GUS4CFO.js → chunk-SMZBJQJR.js} +1 -1
- package/dist/commands/agent/actions/index.js +3 -3
- package/dist/commands/agent/index.js +3 -3
- package/dist/commands/create/actions/index.js +4 -4
- package/dist/commands/create/index.js +5 -5
- package/dist/index.js +134 -109
- package/dist/{plugin-creator-H26ZLR6H.js → plugin-creator-TCUFII32.js} +2 -2
- package/dist/{registry-433S5F3Y.js → registry-RF6PW3EN.js} +3 -3
- package/dist/templates/plugin-quick-starter/README.md +52 -10
- package/dist/templates/plugin-quick-starter/package.json +2 -2
- package/dist/templates/plugin-quick-starter/src/__tests__/e2e/README.md +140 -0
- package/dist/templates/plugin-quick-starter/src/__tests__/e2e/plugin-quick-starter.e2e.ts +339 -0
- package/dist/templates/plugin-quick-starter/src/__tests__/plugin.test.ts +55 -17
- package/dist/templates/plugin-quick-starter/src/plugin.ts +14 -14
- package/dist/templates/plugin-starter/README.md +124 -49
- package/dist/templates/plugin-starter/package.json +2 -2
- package/dist/templates/plugin-starter/src/__tests__/e2e/README.md +44 -9
- package/{templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts → dist/templates/plugin-starter/src/__tests__/e2e/plugin-starter.e2e.ts} +13 -20
- package/dist/templates/plugin-starter/src/plugin.ts +5 -7
- package/dist/templates/project-starter/README.md +24 -11
- package/dist/templates/project-starter/package.json +4 -4
- package/dist/templates/project-starter/src/__tests__/actions.test.ts +2 -2
- package/dist/templates/project-starter/src/__tests__/e2e/README.md +103 -0
- package/dist/templates/project-starter/src/__tests__/e2e/project-starter.e2e.ts +575 -0
- package/dist/templates/project-starter/src/__tests__/integration.test.ts +1 -1
- package/dist/templates/project-starter/src/__tests__/models.test.ts +3 -3
- package/dist/templates/project-starter/src/__tests__/plugin.test.ts +3 -3
- package/dist/templates/project-starter/src/__tests__/provider.test.ts +2 -2
- package/dist/templates/project-starter/src/index.ts +4 -3
- package/dist/templates/project-starter/src/plugin.ts +5 -5
- package/dist/templates/project-tee-starter/README.md +44 -5
- package/dist/templates/project-tee-starter/package.json +4 -4
- package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/build-order.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/character.test.ts +1 -1
- package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/config.test.ts +1 -1
- package/dist/templates/project-tee-starter/src/__tests__/e2e/README.md +128 -0
- package/dist/templates/project-tee-starter/src/__tests__/e2e/project-tee-starter.e2e.ts +280 -0
- package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/env.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/error-handling.test.ts +2 -2
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/events.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/file-structure.test.ts +2 -2
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/integration.test.ts +2 -2
- package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/models.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/plugin.test.ts +1 -1
- package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/provider.test.ts +2 -2
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/routes.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/tee-validation.test.ts +1 -1
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/test-utils.ts +2 -2
- package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/vite-config-utils.ts +14 -2
- package/dist/templates/project-tee-starter/src/index.ts +2 -0
- package/dist/templates/project-tee-starter/src/plugin.ts +19 -7
- package/dist/{utils-DBLSDYBF.js → utils-5HPZSIF6.js} +3 -3
- package/package.json +6 -6
- package/templates/plugin-quick-starter/README.md +52 -10
- package/templates/plugin-quick-starter/package.json +2 -2
- package/templates/plugin-quick-starter/src/__tests__/e2e/README.md +140 -0
- package/templates/plugin-quick-starter/src/__tests__/e2e/plugin-quick-starter.e2e.ts +339 -0
- package/templates/plugin-quick-starter/src/__tests__/plugin.test.ts +55 -17
- package/templates/plugin-quick-starter/src/plugin.ts +14 -14
- package/templates/plugin-starter/README.md +124 -49
- package/templates/plugin-starter/package.json +2 -2
- package/templates/plugin-starter/src/__tests__/e2e/README.md +44 -9
- package/{dist/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts → templates/plugin-starter/src/__tests__/e2e/plugin-starter.e2e.ts} +13 -20
- package/templates/plugin-starter/src/plugin.ts +5 -7
- package/templates/project-starter/README.md +24 -11
- package/templates/project-starter/package.json +4 -4
- package/templates/project-starter/src/__tests__/actions.test.ts +2 -2
- package/templates/project-starter/src/__tests__/e2e/README.md +103 -0
- package/templates/project-starter/src/__tests__/e2e/project-starter.e2e.ts +575 -0
- package/templates/project-starter/src/__tests__/integration.test.ts +1 -1
- package/templates/project-starter/src/__tests__/models.test.ts +3 -3
- package/templates/project-starter/src/__tests__/plugin.test.ts +3 -3
- package/templates/project-starter/src/__tests__/provider.test.ts +2 -2
- package/templates/project-starter/src/index.ts +4 -3
- package/templates/project-starter/src/plugin.ts +5 -5
- package/templates/project-tee-starter/README.md +44 -5
- package/templates/project-tee-starter/package.json +4 -4
- package/templates/project-tee-starter/{__tests__ → src/__tests__}/build-order.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/character.test.ts +1 -1
- package/templates/project-tee-starter/{__tests__ → src/__tests__}/config.test.ts +1 -1
- package/templates/project-tee-starter/src/__tests__/e2e/README.md +128 -0
- package/templates/project-tee-starter/src/__tests__/e2e/project-tee-starter.e2e.ts +280 -0
- package/templates/project-tee-starter/{__tests__ → src/__tests__}/env.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/error-handling.test.ts +2 -2
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/events.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/file-structure.test.ts +2 -2
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/integration.test.ts +2 -2
- package/templates/project-tee-starter/{__tests__ → src/__tests__}/models.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/plugin.test.ts +1 -1
- package/templates/project-tee-starter/{__tests__ → src/__tests__}/provider.test.ts +2 -2
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/routes.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/tee-validation.test.ts +1 -1
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/test-utils.ts +2 -2
- package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/vite-config-utils.ts +14 -2
- package/templates/project-tee-starter/src/index.ts +2 -0
- package/templates/project-tee-starter/src/plugin.ts +19 -7
- package/dist/templates/plugin-starter/src/tests.ts +0 -6
- package/dist/templates/project-starter/src/__tests__/e2e/index.ts +0 -14
- package/dist/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +0 -246
- package/dist/templates/project-starter/src/__tests__/e2e/project.test.ts +0 -155
- package/dist/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +0 -421
- package/dist/templates/project-tee-starter/e2e/project.test.ts +0 -38
- package/dist/templates/project-tee-starter/e2e/starter-plugin.test.ts +0 -92
- package/templates/plugin-starter/src/tests.ts +0 -6
- package/templates/project-starter/src/__tests__/e2e/index.ts +0 -14
- package/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +0 -246
- package/templates/project-starter/src/__tests__/e2e/project.test.ts +0 -155
- package/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +0 -421
- package/templates/project-tee-starter/e2e/project.test.ts +0 -38
- package/templates/project-tee-starter/e2e/starter-plugin.test.ts +0 -92
- /package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/actions.test.ts +0 -0
- /package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/frontend.test.ts +0 -0
- /package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/utils/core-test-utils.ts +0 -0
- /package/templates/project-tee-starter/{__tests__ → src/__tests__}/actions.test.ts +0 -0
- /package/templates/project-tee-starter/{__tests__ → src/__tests__}/frontend.test.ts +0 -0
- /package/templates/project-tee-starter/{__tests__ → src/__tests__}/utils/core-test-utils.ts +0 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ModelType,
|
|
10
10
|
logger,
|
|
11
11
|
EventType,
|
|
12
|
+
Action,
|
|
12
13
|
} from '@elizaos/core';
|
|
13
14
|
import dotenv from 'dotenv';
|
|
14
15
|
import {
|
|
@@ -19,6 +20,38 @@ import {
|
|
|
19
20
|
testFixtures,
|
|
20
21
|
} from './test-utils';
|
|
21
22
|
|
|
23
|
+
// Define proper interfaces for test mocking
|
|
24
|
+
interface MockLoggerMethod {
|
|
25
|
+
calls?: any[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface MockLogger {
|
|
29
|
+
info: MockLoggerMethod;
|
|
30
|
+
error: MockLoggerMethod;
|
|
31
|
+
debug: MockLoggerMethod;
|
|
32
|
+
warn: MockLoggerMethod;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface PluginConfig {
|
|
36
|
+
EXAMPLE_PLUGIN_VARIABLE?: string | number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface TestCallbackContent {
|
|
40
|
+
text?: string;
|
|
41
|
+
actions?: string[];
|
|
42
|
+
source?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface TestActionResult {
|
|
46
|
+
text?: string;
|
|
47
|
+
success: boolean;
|
|
48
|
+
data?: {
|
|
49
|
+
actions?: string[];
|
|
50
|
+
source?: string;
|
|
51
|
+
};
|
|
52
|
+
error?: Error;
|
|
53
|
+
}
|
|
54
|
+
|
|
22
55
|
// Setup environment variables
|
|
23
56
|
dotenv.config();
|
|
24
57
|
|
|
@@ -79,7 +112,7 @@ describe('Plugin Configuration', () => {
|
|
|
79
112
|
const invalidConfig = { EXAMPLE_PLUGIN_VARIABLE: 123 }; // Should be string
|
|
80
113
|
|
|
81
114
|
if (starterPlugin.init) {
|
|
82
|
-
await expect(starterPlugin.init(invalidConfig as
|
|
115
|
+
await expect(starterPlugin.init(invalidConfig as PluginConfig, runtime)).rejects.toThrow(
|
|
83
116
|
'Invalid plugin configuration'
|
|
84
117
|
);
|
|
85
118
|
}
|
|
@@ -88,21 +121,22 @@ describe('Plugin Configuration', () => {
|
|
|
88
121
|
|
|
89
122
|
describe('Hello World Action', () => {
|
|
90
123
|
let runtime: IAgentRuntime;
|
|
91
|
-
let helloWorldAction:
|
|
124
|
+
let helloWorldAction: Action;
|
|
92
125
|
|
|
93
126
|
beforeEach(() => {
|
|
94
127
|
runtime = createMockRuntime();
|
|
95
|
-
helloWorldAction = starterPlugin
|
|
128
|
+
helloWorldAction = starterPlugin?.actions?.[0] as Action;
|
|
96
129
|
// Clear all spies before each test
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
130
|
+
const mockLogger = logger as unknown as MockLogger;
|
|
131
|
+
mockLogger.info.calls = [];
|
|
132
|
+
mockLogger.error.calls = [];
|
|
133
|
+
mockLogger.debug.calls = [];
|
|
134
|
+
mockLogger.warn.calls = [];
|
|
101
135
|
});
|
|
102
136
|
|
|
103
137
|
it('should have hello world action', () => {
|
|
104
138
|
expect(helloWorldAction).toBeDefined();
|
|
105
|
-
expect(helloWorldAction?.name).toBe('
|
|
139
|
+
expect(helloWorldAction?.name).toBe('QUICK_ACTION');
|
|
106
140
|
});
|
|
107
141
|
|
|
108
142
|
it('should always validate messages (current implementation)', async () => {
|
|
@@ -180,9 +214,9 @@ describe('Hello World Action', () => {
|
|
|
180
214
|
content: { text: 'say hello', source: 'test' },
|
|
181
215
|
});
|
|
182
216
|
|
|
183
|
-
let callbackContent:
|
|
217
|
+
let callbackContent: TestCallbackContent | null = null;
|
|
184
218
|
const callback: HandlerCallback = async (content: Content) => {
|
|
185
|
-
callbackContent = content;
|
|
219
|
+
callbackContent = content as TestCallbackContent;
|
|
186
220
|
return [];
|
|
187
221
|
};
|
|
188
222
|
|
|
@@ -191,12 +225,13 @@ describe('Hello World Action', () => {
|
|
|
191
225
|
expect(result).toHaveProperty('text', 'Hello world!');
|
|
192
226
|
expect(result).toHaveProperty('success', true);
|
|
193
227
|
expect(result).toHaveProperty('data');
|
|
194
|
-
|
|
195
|
-
expect(
|
|
228
|
+
const typedResult = result as TestActionResult;
|
|
229
|
+
expect(typedResult.data).toHaveProperty('actions', ['QUICK_ACTION']);
|
|
230
|
+
expect(typedResult.data).toHaveProperty('source', 'test');
|
|
196
231
|
|
|
197
232
|
expect(callbackContent).toEqual({
|
|
198
233
|
text: 'Hello world!',
|
|
199
|
-
actions: ['
|
|
234
|
+
actions: ['QUICK_ACTION'],
|
|
200
235
|
source: 'test',
|
|
201
236
|
});
|
|
202
237
|
});
|
|
@@ -224,7 +259,8 @@ describe('Hello World Action', () => {
|
|
|
224
259
|
|
|
225
260
|
expect(result).toHaveProperty('success', false);
|
|
226
261
|
expect(result).toHaveProperty('error');
|
|
227
|
-
|
|
262
|
+
const typedResult = result as TestActionResult;
|
|
263
|
+
expect(typedResult.error?.message).toBe('Callback error');
|
|
228
264
|
// Quick-starter plugin doesn't log errors
|
|
229
265
|
});
|
|
230
266
|
|
|
@@ -278,7 +314,7 @@ describe('Hello World Provider', () => {
|
|
|
278
314
|
|
|
279
315
|
it('should have hello world provider', () => {
|
|
280
316
|
expect(provider).toBeDefined();
|
|
281
|
-
expect(provider?.name).toBe('
|
|
317
|
+
expect(provider?.name).toBe('QUICK_PROVIDER');
|
|
282
318
|
});
|
|
283
319
|
|
|
284
320
|
it('should provide hello world data', async () => {
|
|
@@ -310,9 +346,11 @@ describe('Hello World Provider', () => {
|
|
|
310
346
|
const result2 = await provider.get(runtime, message, state);
|
|
311
347
|
|
|
312
348
|
// Text and structure should be consistent
|
|
349
|
+
expect(result1.text).toBeDefined();
|
|
350
|
+
expect(result2.text).toBeDefined();
|
|
313
351
|
expect(result1.text).toBe(result2.text);
|
|
314
|
-
expect(result1.values).toEqual(result2.values);
|
|
315
|
-
expect(result1.data).toEqual(result2.data);
|
|
352
|
+
expect(result1.values || {}).toEqual(result2.values || {});
|
|
353
|
+
expect(result1.data || {}).toEqual(result2.data || {});
|
|
316
354
|
});
|
|
317
355
|
});
|
|
318
356
|
|
|
@@ -51,9 +51,9 @@ const configSchema = z.object({
|
|
|
51
51
|
* @property {Function} handler - Asynchronous function to handle the action and generate a response.
|
|
52
52
|
* @property {Object[]} examples - An array of example inputs and expected outputs for the action.
|
|
53
53
|
*/
|
|
54
|
-
const
|
|
55
|
-
name: '
|
|
56
|
-
similes: ['GREET', 'SAY_HELLO'],
|
|
54
|
+
const quickAction: Action = {
|
|
55
|
+
name: 'QUICK_ACTION',
|
|
56
|
+
similes: ['GREET', 'SAY_HELLO', 'HELLO_WORLD'],
|
|
57
57
|
description: 'Responds with a simple hello world message',
|
|
58
58
|
|
|
59
59
|
validate: async (
|
|
@@ -79,7 +79,7 @@ const helloWorldAction: Action = {
|
|
|
79
79
|
if (callback) {
|
|
80
80
|
await callback({
|
|
81
81
|
text: response,
|
|
82
|
-
actions: ['
|
|
82
|
+
actions: ['QUICK_ACTION'],
|
|
83
83
|
source: message.content.source,
|
|
84
84
|
});
|
|
85
85
|
}
|
|
@@ -88,7 +88,7 @@ const helloWorldAction: Action = {
|
|
|
88
88
|
text: response,
|
|
89
89
|
success: true,
|
|
90
90
|
data: {
|
|
91
|
-
actions: ['
|
|
91
|
+
actions: ['QUICK_ACTION'],
|
|
92
92
|
source: message.content.source,
|
|
93
93
|
},
|
|
94
94
|
};
|
|
@@ -112,7 +112,7 @@ const helloWorldAction: Action = {
|
|
|
112
112
|
name: '{{name2}}',
|
|
113
113
|
content: {
|
|
114
114
|
text: 'hello world!',
|
|
115
|
-
actions: ['
|
|
115
|
+
actions: ['QUICK_ACTION'],
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
118
|
],
|
|
@@ -123,8 +123,8 @@ const helloWorldAction: Action = {
|
|
|
123
123
|
* Example Hello World Provider
|
|
124
124
|
* This demonstrates the simplest possible provider implementation
|
|
125
125
|
*/
|
|
126
|
-
const
|
|
127
|
-
name: '
|
|
126
|
+
const quickProvider: Provider = {
|
|
127
|
+
name: 'QUICK_PROVIDER',
|
|
128
128
|
description: 'A simple example provider',
|
|
129
129
|
|
|
130
130
|
get: async (
|
|
@@ -235,31 +235,31 @@ export const starterPlugin: Plugin = {
|
|
|
235
235
|
[EventType.MESSAGE_RECEIVED]: [
|
|
236
236
|
async (params: MessagePayload) => {
|
|
237
237
|
logger.debug('MESSAGE_RECEIVED event received');
|
|
238
|
-
logger.debug(
|
|
238
|
+
logger.debug({ message: params.message }, 'Message:');
|
|
239
239
|
},
|
|
240
240
|
],
|
|
241
241
|
[EventType.VOICE_MESSAGE_RECEIVED]: [
|
|
242
242
|
async (params: MessagePayload) => {
|
|
243
243
|
logger.debug('VOICE_MESSAGE_RECEIVED event received');
|
|
244
|
-
logger.debug(
|
|
244
|
+
logger.debug({ message: params.message }, 'Message:');
|
|
245
245
|
},
|
|
246
246
|
],
|
|
247
247
|
[EventType.WORLD_CONNECTED]: [
|
|
248
248
|
async (params: WorldPayload) => {
|
|
249
249
|
logger.debug('WORLD_CONNECTED event received');
|
|
250
|
-
logger.debug(
|
|
250
|
+
logger.debug({ world: params.world }, 'World:');
|
|
251
251
|
},
|
|
252
252
|
],
|
|
253
253
|
[EventType.WORLD_JOINED]: [
|
|
254
254
|
async (params: WorldPayload) => {
|
|
255
255
|
logger.debug('WORLD_JOINED event received');
|
|
256
|
-
logger.debug(
|
|
256
|
+
logger.debug({ world: params.world }, 'World:');
|
|
257
257
|
},
|
|
258
258
|
],
|
|
259
259
|
},
|
|
260
260
|
services: [StarterService],
|
|
261
|
-
actions: [
|
|
262
|
-
providers: [
|
|
261
|
+
actions: [quickAction],
|
|
262
|
+
providers: [quickProvider],
|
|
263
263
|
// dependencies: ['@elizaos/plugin-knowledge'], <--- plugin dependencies go here (if requires another plugin)
|
|
264
264
|
};
|
|
265
265
|
|
|
@@ -34,89 +34,164 @@ elizaos test
|
|
|
34
34
|
|
|
35
35
|
## Testing
|
|
36
36
|
|
|
37
|
-
ElizaOS
|
|
37
|
+
ElizaOS uses a dual testing approach that combines Bun's native test runner for component tests with a custom E2E test runner for integration testing within a live ElizaOS runtime.
|
|
38
38
|
|
|
39
39
|
### Test Structure
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- Test the plugin within a full ElizaOS runtime
|
|
50
|
-
- Validate complete user scenarios with a real agent
|
|
51
|
-
- Run with: `elizaos test e2e`
|
|
41
|
+
```
|
|
42
|
+
src/
|
|
43
|
+
__tests__/ # All tests live inside src
|
|
44
|
+
*.test.ts # Component tests (use Bun test runner)
|
|
45
|
+
e2e/ # E2E tests (use ElizaOS test runner)
|
|
46
|
+
*.ts # E2E test files
|
|
47
|
+
README.md # E2E testing documentation
|
|
48
|
+
```
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
- `elizaos test` runs both component and e2e tests
|
|
50
|
+
### Two Types of Tests
|
|
55
51
|
|
|
56
|
-
|
|
52
|
+
#### 1. Component Tests (Bun Test Runner)
|
|
57
53
|
|
|
58
|
-
|
|
54
|
+
- **Purpose**: Test individual functions/classes in isolation
|
|
55
|
+
- **Location**: `src/__tests__/*.test.ts`
|
|
56
|
+
- **Runner**: Bun's built-in test runner
|
|
57
|
+
- **Command**: `bun test`
|
|
58
|
+
- **Features**: Fast, isolated, uses mocks
|
|
59
59
|
|
|
60
60
|
```typescript
|
|
61
|
-
//
|
|
61
|
+
// Example: src/__tests__/plugin.test.ts
|
|
62
|
+
import { describe, it, expect } from 'bun:test';
|
|
63
|
+
import { starterPlugin } from '../plugin';
|
|
64
|
+
|
|
62
65
|
describe('Plugin Configuration', () => {
|
|
63
66
|
it('should have correct plugin metadata', () => {
|
|
64
67
|
expect(starterPlugin.name).toBe('plugin-starter');
|
|
65
68
|
});
|
|
66
69
|
});
|
|
67
|
-
|
|
68
|
-
// Integration test example (__tests__/integration.test.ts)
|
|
69
|
-
describe('Integration: HelloWorld Action with StarterService', () => {
|
|
70
|
-
it('should handle HelloWorld action with StarterService', async () => {
|
|
71
|
-
// Test interactions between components
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
70
|
```
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
#### 2. E2E Tests (ElizaOS Test Runner)
|
|
73
|
+
|
|
74
|
+
- **Purpose**: Test plugin behavior within a real ElizaOS runtime
|
|
75
|
+
- **Location**: `src/__tests__/e2e/*.ts`
|
|
76
|
+
- **Runner**: ElizaOS custom test runner
|
|
77
|
+
- **Command**: `elizaos test --type e2e`
|
|
78
|
+
- **Features**: Real runtime, real database, full integration
|
|
77
79
|
|
|
78
80
|
```typescript
|
|
79
|
-
//
|
|
81
|
+
// Example: src/__tests__/e2e/starter-plugin.ts
|
|
82
|
+
import { type TestSuite } from '@elizaos/core';
|
|
83
|
+
|
|
80
84
|
export const StarterPluginTestSuite: TestSuite = {
|
|
81
85
|
name: 'plugin_starter_test_suite',
|
|
82
|
-
description: 'E2E tests for the starter plugin',
|
|
83
86
|
tests: [
|
|
84
87
|
{
|
|
85
88
|
name: 'hello_world_action_test',
|
|
86
89
|
fn: async (runtime) => {
|
|
87
|
-
//
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// Execute action and capture response
|
|
93
|
-
const response = await helloWorldAction.handler(runtime, testMessage, ...);
|
|
94
|
-
|
|
95
|
-
// Verify agent responds with "hello world"
|
|
96
|
-
if (!response.text.includes('hello world')) {
|
|
97
|
-
throw new Error('Expected "hello world" in response');
|
|
90
|
+
// Test with real runtime - no mocks needed!
|
|
91
|
+
const action = runtime.actions.find((a) => a.name === 'HELLO_WORLD');
|
|
92
|
+
if (!action) {
|
|
93
|
+
throw new Error('Action not found');
|
|
98
94
|
}
|
|
95
|
+
// Test real behavior...
|
|
99
96
|
},
|
|
100
97
|
},
|
|
101
98
|
],
|
|
102
99
|
};
|
|
103
100
|
```
|
|
104
101
|
|
|
105
|
-
|
|
102
|
+
### Running Tests
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Run all tests (both component and E2E)
|
|
106
|
+
elizaos test
|
|
107
|
+
|
|
108
|
+
# Run only component tests (fast, for TDD)
|
|
109
|
+
bun test
|
|
110
|
+
# or
|
|
111
|
+
elizaos test --type component
|
|
112
|
+
|
|
113
|
+
# Run only E2E tests (slower, full integration)
|
|
114
|
+
elizaos test --type e2e
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Key Differences
|
|
118
|
+
|
|
119
|
+
| Aspect | Component Tests | E2E Tests |
|
|
120
|
+
| --------------- | -------------------- | ----------------------- |
|
|
121
|
+
| **Runner** | Bun test | ElizaOS TestRunner |
|
|
122
|
+
| **Environment** | Mocked | Real runtime |
|
|
123
|
+
| **Database** | Mocked | Real (PGLite) |
|
|
124
|
+
| **Speed** | Fast (ms) | Slower (seconds) |
|
|
125
|
+
| **Use Case** | TDD, component logic | Integration, user flows |
|
|
126
|
+
|
|
127
|
+
### E2E Test Integration
|
|
128
|
+
|
|
129
|
+
E2E tests are integrated into your plugin by:
|
|
130
|
+
|
|
131
|
+
1. **Creating the test suite** in `src/__tests__/e2e/`
|
|
132
|
+
2. **Importing directly** in your plugin definition:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// src/plugin.ts
|
|
136
|
+
import { StarterPluginTestSuite } from './__tests__/e2e/starter-plugin';
|
|
137
|
+
|
|
138
|
+
export const starterPlugin: Plugin = {
|
|
139
|
+
name: 'plugin-starter',
|
|
140
|
+
// ... other properties
|
|
141
|
+
tests: [StarterPluginTestSuite], // Direct import, no tests.ts needed
|
|
142
|
+
};
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Writing Effective E2E Tests
|
|
146
|
+
|
|
147
|
+
E2E tests receive a real `IAgentRuntime` instance, allowing you to:
|
|
148
|
+
|
|
149
|
+
- Access real actions, providers, and services
|
|
150
|
+
- Interact with the actual database
|
|
151
|
+
- Test complete user scenarios
|
|
152
|
+
- Validate plugin behavior in production-like conditions
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
{
|
|
156
|
+
name: 'service_lifecycle_test',
|
|
157
|
+
fn: async (runtime) => {
|
|
158
|
+
// Get the real service
|
|
159
|
+
const service = runtime.getService('starter');
|
|
160
|
+
if (!service) {
|
|
161
|
+
throw new Error('Service not initialized');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Test real behavior
|
|
165
|
+
await service.stop();
|
|
166
|
+
// Verify cleanup happened...
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Best Practices
|
|
172
|
+
|
|
173
|
+
1. **Use Component Tests for**:
|
|
174
|
+
|
|
175
|
+
- Algorithm logic
|
|
176
|
+
- Data transformations
|
|
177
|
+
- Input validation
|
|
178
|
+
- Error handling
|
|
106
179
|
|
|
107
|
-
|
|
108
|
-
- **Plugin Interaction**: Test how your plugin behaves with the actual agent
|
|
109
|
-
- **Scenario Testing**: Validate complete user interactions, not just individual functions
|
|
110
|
-
- **No Mock Required**: Access real services, actions, and providers
|
|
180
|
+
2. **Use E2E Tests for**:
|
|
111
181
|
|
|
112
|
-
|
|
182
|
+
- User scenarios
|
|
183
|
+
- Action execution flows
|
|
184
|
+
- Provider data integration
|
|
185
|
+
- Service lifecycle
|
|
186
|
+
- Plugin interactions
|
|
113
187
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
188
|
+
3. **Test Organization**:
|
|
189
|
+
- Keep related tests together
|
|
190
|
+
- Use descriptive test names
|
|
191
|
+
- Include failure scenarios
|
|
192
|
+
- Document complex test setups
|
|
118
193
|
|
|
119
|
-
The test
|
|
194
|
+
The comprehensive E2E test documentation in `src/__tests__/e2e/README.md` provides detailed examples and patterns for writing effective tests.
|
|
120
195
|
|
|
121
196
|
## Publishing & Continuous Development
|
|
122
197
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"tsup.config.ts"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@elizaos/core": "1.
|
|
44
|
+
"@elizaos/core": "1.4.2",
|
|
45
45
|
"@tanstack/react-query": "^5.80.7",
|
|
46
46
|
"clsx": "^2.1.1",
|
|
47
47
|
"tailwind-merge": "^3.3.1",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"zod": "3.24.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@elizaos/cli": "1.
|
|
53
|
+
"@elizaos/cli": "1.4.2",
|
|
54
54
|
"@tailwindcss/vite": "^4.1.10",
|
|
55
55
|
"@vitejs/plugin-react-swc": "^3.10.2",
|
|
56
56
|
"dotenv": "16.4.5",
|
|
@@ -2,9 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
This directory contains end-to-end tests for the ElizaOS plugin starter template.
|
|
4
4
|
|
|
5
|
+
## ElizaOS Testing Philosophy
|
|
6
|
+
|
|
7
|
+
ElizaOS employs a dual testing strategy:
|
|
8
|
+
|
|
9
|
+
1. **Component Tests** (`src/__tests__/*.test.ts`)
|
|
10
|
+
|
|
11
|
+
- Run with Bun's native test runner
|
|
12
|
+
- Fast, isolated tests using mocks
|
|
13
|
+
- Perfect for TDD and component logic
|
|
14
|
+
- Command: `bun test`
|
|
15
|
+
|
|
16
|
+
2. **E2E Tests** (`src/__tests__/e2e/*.ts`)
|
|
17
|
+
- Run with ElizaOS custom test runner
|
|
18
|
+
- Real runtime with actual database (PGLite)
|
|
19
|
+
- Test complete user scenarios
|
|
20
|
+
- Command: `elizaos test --type e2e`
|
|
21
|
+
|
|
5
22
|
## Overview
|
|
6
23
|
|
|
7
|
-
E2E tests run in a real ElizaOS runtime environment, allowing you to test your plugin's behavior as it would work in production.
|
|
24
|
+
E2E tests run in a real ElizaOS runtime environment, allowing you to test your plugin's behavior as it would work in production. Unlike component tests, E2E tests provide access to a fully initialized runtime with all services, actions, and providers available.
|
|
8
25
|
|
|
9
26
|
## Test Structure
|
|
10
27
|
|
|
@@ -15,24 +32,42 @@ E2E tests run in a real ElizaOS runtime environment, allowing you to test your p
|
|
|
15
32
|
- `hello_world_provider_test` - Tests provider functionality
|
|
16
33
|
- `starter_service_test` - Tests service lifecycle
|
|
17
34
|
|
|
35
|
+
## Integration with Plugin
|
|
36
|
+
|
|
37
|
+
E2E tests are integrated directly into your plugin without the need for an intermediate export file:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// src/plugin.ts
|
|
41
|
+
import { StarterPluginTestSuite } from './__tests__/e2e/plugin-starter.e2e';
|
|
42
|
+
|
|
43
|
+
export const myPlugin: Plugin = {
|
|
44
|
+
name: 'my-plugin',
|
|
45
|
+
// ... other properties
|
|
46
|
+
tests: [StarterPluginTestSuite], // Direct import!
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
18
50
|
## Running Tests
|
|
19
51
|
|
|
20
52
|
```bash
|
|
21
53
|
# Run all tests (component + e2e)
|
|
22
|
-
|
|
54
|
+
elizaos test
|
|
23
55
|
|
|
24
|
-
# Run only e2e tests
|
|
25
|
-
|
|
56
|
+
# Run only e2e tests (slower, full integration)
|
|
57
|
+
elizaos test --type e2e
|
|
26
58
|
|
|
27
|
-
# Run only component tests
|
|
28
|
-
|
|
59
|
+
# Run only component tests (fast, for TDD)
|
|
60
|
+
bun test
|
|
61
|
+
# or
|
|
62
|
+
elizaos test --type component
|
|
29
63
|
```
|
|
30
64
|
|
|
31
65
|
## Implementation Details
|
|
32
66
|
|
|
33
|
-
1. **
|
|
67
|
+
1. **Direct Import**: Tests are imported directly from the e2e test file - no intermediate export file needed
|
|
34
68
|
2. **Plugin Integration**: The test suite is added to the plugin's `tests` array
|
|
35
|
-
3. **
|
|
69
|
+
3. **Test Discovery**: The ElizaOS test runner automatically finds and executes tests from the plugin's `tests` array
|
|
70
|
+
4. **Runtime Access**: Each test receives a real runtime instance with full access to:
|
|
36
71
|
- Plugin actions, providers, and services
|
|
37
72
|
- Agent character configuration
|
|
38
73
|
- Database and model access
|
|
@@ -44,4 +79,4 @@ npm run test:component
|
|
|
44
79
|
|
|
45
80
|
## Writing New Tests
|
|
46
81
|
|
|
47
|
-
See the comprehensive documentation at the top of `starter
|
|
82
|
+
See the comprehensive documentation at the top of `plugin-starter.e2e.ts` for detailed instructions on adding new tests.
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Content,
|
|
3
|
+
type HandlerCallback,
|
|
4
|
+
type IAgentRuntime,
|
|
5
|
+
type TestSuite,
|
|
6
|
+
} from '@elizaos/core';
|
|
2
7
|
|
|
3
8
|
/**
|
|
4
9
|
* E2E (End-to-End) Test Suite for ElizaOS Plugins
|
|
@@ -31,7 +36,7 @@ import { type Content, type HandlerCallback } from '@elizaos/core';
|
|
|
31
36
|
* ```typescript
|
|
32
37
|
* {
|
|
33
38
|
* name: 'my_new_test',
|
|
34
|
-
* fn: async (runtime) => {
|
|
39
|
+
* fn: async (runtime: IAgentRuntime) => {
|
|
35
40
|
* // Your test logic here
|
|
36
41
|
* if (someCondition !== expected) {
|
|
37
42
|
* throw new Error('Test failed: reason');
|
|
@@ -60,16 +65,6 @@ import { type Content, type HandlerCallback } from '@elizaos/core';
|
|
|
60
65
|
* For more details, see the ElizaOS documentation.
|
|
61
66
|
*/
|
|
62
67
|
|
|
63
|
-
// Define a minimal TestSuite interface that matches what's needed
|
|
64
|
-
interface TestSuite {
|
|
65
|
-
name: string;
|
|
66
|
-
description?: string;
|
|
67
|
-
tests: Array<{
|
|
68
|
-
name: string;
|
|
69
|
-
fn: (runtime: any) => Promise<any>;
|
|
70
|
-
}>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
68
|
// Define minimal interfaces for the types we need
|
|
74
69
|
type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
|
75
70
|
|
|
@@ -91,8 +86,6 @@ interface State {
|
|
|
91
86
|
|
|
92
87
|
export const StarterPluginTestSuite: TestSuite = {
|
|
93
88
|
name: 'plugin_starter_test_suite',
|
|
94
|
-
description: 'E2E tests for the starter plugin',
|
|
95
|
-
|
|
96
89
|
tests: [
|
|
97
90
|
/**
|
|
98
91
|
* Basic Plugin Verification Test
|
|
@@ -102,7 +95,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
102
95
|
*/
|
|
103
96
|
{
|
|
104
97
|
name: 'example_test',
|
|
105
|
-
fn: async (runtime) => {
|
|
98
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
106
99
|
// Test the character name
|
|
107
100
|
if (runtime.character.name !== 'Eliza') {
|
|
108
101
|
throw new Error(
|
|
@@ -125,7 +118,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
125
118
|
*/
|
|
126
119
|
{
|
|
127
120
|
name: 'should_have_hello_world_action',
|
|
128
|
-
fn: async (runtime) => {
|
|
121
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
129
122
|
// Access actions through runtime.actions instead of getPlugin
|
|
130
123
|
const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');
|
|
131
124
|
if (!actionExists) {
|
|
@@ -147,7 +140,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
147
140
|
*/
|
|
148
141
|
{
|
|
149
142
|
name: 'hello_world_action_test',
|
|
150
|
-
fn: async (runtime) => {
|
|
143
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
151
144
|
// Create a test message asking the agent to say hello
|
|
152
145
|
const testMessage: Memory = {
|
|
153
146
|
entityId: '12345678-1234-1234-1234-123456789012' as UUID,
|
|
@@ -215,7 +208,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
215
208
|
*/
|
|
216
209
|
{
|
|
217
210
|
name: 'hello_world_provider_test',
|
|
218
|
-
fn: async (runtime) => {
|
|
211
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
219
212
|
// Create a test message
|
|
220
213
|
const testMessage: Memory = {
|
|
221
214
|
entityId: '12345678-1234-1234-1234-123456789012' as UUID,
|
|
@@ -258,7 +251,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
258
251
|
*/
|
|
259
252
|
{
|
|
260
253
|
name: 'starter_service_test',
|
|
261
|
-
fn: async (runtime) => {
|
|
254
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
262
255
|
// Get the service from the runtime
|
|
263
256
|
const service = runtime.getService('starter');
|
|
264
257
|
if (!service) {
|
|
@@ -287,7 +280,7 @@ export const StarterPluginTestSuite: TestSuite = {
|
|
|
287
280
|
* ```typescript
|
|
288
281
|
* {
|
|
289
282
|
* name: 'your_test_name',
|
|
290
|
-
* fn: async (runtime) => {
|
|
283
|
+
* fn: async (runtime: IAgentRuntime) => {
|
|
291
284
|
* // Setup: Create any test data needed
|
|
292
285
|
*
|
|
293
286
|
* // Action: Perform the operation you want to test
|