@elizaos/cli 1.0.9 → 1.0.10

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.
Files changed (240) hide show
  1. package/README.md +9 -16
  2. package/dist/assets/{index-CCyz05Yl.js → index-CmuPnu0u.js} +72 -89
  3. package/dist/assets/index-CmuPnu0u.js.br +0 -0
  4. package/dist/assets/index-CmuPnu0u.js.map +1 -0
  5. package/dist/assets/{index-Cxd2b7is.js → index-DDQnwxzL.js} +1318 -13721
  6. package/dist/assets/{index-Cxd2b7is.js.map → index-DDQnwxzL.js.map} +1 -1
  7. package/dist/assets/index-Df1AFSuJ.css +1 -0
  8. package/dist/assets/index-Df1AFSuJ.css.br +0 -0
  9. package/dist/assets/vendor-DSdxb8P-.js.map +1 -1
  10. package/dist/{chunk-Y755OOSP.js → chunk-7HYEGM5V.js} +877 -1550
  11. package/dist/{chunk-HZQCHL3J.js → chunk-B4KJXECB.js} +13 -18
  12. package/dist/{chunk-Z6GVELRX.js → chunk-GWQB7PBK.js} +58 -29
  13. package/dist/{chunk-CVADLFW6.js → chunk-LQ6XHF53.js} +4543 -3043
  14. package/dist/{chunk-JWONHNLD.js → chunk-RIAWNDYI.js} +2 -9
  15. package/dist/{chunk-IEKLJDUU.js → chunk-WS4DWCDZ.js} +54 -32
  16. package/dist/commands/agent/actions/index.d.ts +5 -1
  17. package/dist/commands/agent/actions/index.js +5 -3
  18. package/dist/commands/agent/index.js +3 -3
  19. package/dist/commands/create/actions/index.js +4 -4
  20. package/dist/commands/create/index.js +5 -5
  21. package/dist/{fileFromPath-DCRQMDLJ.js → fileFromPath-KB6XMTJ4.js} +1 -0
  22. package/dist/index.html +2 -2
  23. package/dist/index.js +9351 -102236
  24. package/dist/{migrator-KZLCVEIH.js → migrator-JREQPDN3.js} +42 -220
  25. package/dist/pglite.data +0 -0
  26. package/dist/pglite.wasm +0 -0
  27. package/dist/plugin-creator-T4K2673C.js +910 -0
  28. package/dist/{registry-W7CIK4O2.js → registry-CBMRMYCG.js} +3 -3
  29. package/dist/templates/plugin-starter/README.md +255 -0
  30. package/dist/templates/plugin-starter/bunfig.toml +6 -0
  31. package/dist/templates/plugin-starter/cypress.config.ts +18 -0
  32. package/dist/templates/plugin-starter/index.html +13 -0
  33. package/dist/templates/plugin-starter/package.json +95 -0
  34. package/dist/templates/plugin-starter/postcss.config.js +3 -0
  35. package/dist/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
  36. package/dist/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
  37. package/dist/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
  38. package/dist/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
  39. package/dist/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
  40. package/dist/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
  41. package/dist/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
  42. package/dist/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
  43. package/dist/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
  44. package/dist/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
  45. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/integration.test.ts +22 -17
  46. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/plugin.test.ts +8 -8
  47. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/test-utils.ts +17 -17
  48. package/dist/templates/plugin-starter/src/frontend/index.css +77 -0
  49. package/dist/templates/plugin-starter/src/frontend/index.tsx +164 -0
  50. package/dist/templates/plugin-starter/src/frontend/utils.ts +6 -0
  51. package/dist/templates/plugin-starter/src/index.ts +274 -0
  52. package/dist/templates/plugin-starter/src/tests.ts +6 -0
  53. package/dist/templates/plugin-starter/tailwind.config.js +62 -0
  54. package/dist/templates/plugin-starter/tsconfig.build.json +11 -0
  55. package/dist/templates/plugin-starter/tsconfig.json +28 -0
  56. package/dist/templates/plugin-starter/tsup.config.ts +20 -0
  57. package/dist/templates/plugin-starter/vite.config.ts +20 -0
  58. package/dist/templates/project-starter/.env.example +153 -0
  59. package/dist/templates/project-starter/README.md +109 -0
  60. package/dist/templates/project-starter/bunfig.toml +6 -0
  61. package/dist/templates/project-starter/cypress.config.ts +31 -0
  62. package/dist/templates/project-starter/index.html +13 -0
  63. package/dist/templates/project-starter/package.json +83 -0
  64. package/dist/templates/project-starter/postcss.config.js +3 -0
  65. package/dist/templates/project-starter/scripts/test-all.sh +101 -0
  66. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/actions.test.ts +6 -6
  67. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/character.test.ts +3 -3
  68. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/config.test.ts +18 -18
  69. package/dist/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
  70. package/dist/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
  71. package/dist/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
  72. package/dist/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
  73. package/dist/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
  74. package/dist/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
  75. package/dist/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
  76. package/dist/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
  77. package/dist/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
  78. package/dist/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
  79. package/dist/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
  80. package/dist/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
  81. package/dist/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
  82. package/dist/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
  83. package/dist/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
  84. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/env.test.ts +2 -2
  85. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/error-handling.test.ts +17 -17
  86. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/events.test.ts +7 -7
  87. package/dist/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
  88. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/integration.test.ts +25 -25
  89. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/models.test.ts +6 -6
  90. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/plugin.test.ts +9 -9
  91. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/provider.test.ts +7 -7
  92. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/routes.test.ts +3 -3
  93. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/test-utils.ts +17 -17
  94. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/utils/core-test-utils.ts +3 -3
  95. package/dist/templates/project-starter/src/frontend/index.css +77 -0
  96. package/dist/templates/project-starter/src/frontend/index.html +19 -0
  97. package/dist/templates/project-starter/src/frontend/index.tsx +98 -0
  98. package/dist/templates/project-starter/src/frontend/utils.ts +6 -0
  99. package/dist/templates/project-starter/src/index.ts +153 -0
  100. package/dist/templates/project-starter/src/plugin.ts +255 -0
  101. package/dist/templates/project-starter/tailwind.config.js +62 -0
  102. package/dist/templates/project-starter/tsconfig.build.json +20 -0
  103. package/dist/templates/project-starter/tsconfig.json +39 -0
  104. package/dist/templates/project-starter/tsup.config.ts +19 -0
  105. package/dist/templates/project-starter/vite.config.ts +39 -0
  106. package/dist/templates/project-tee-starter/.dockerignore +20 -0
  107. package/dist/templates/project-tee-starter/.env.example +55 -0
  108. package/dist/templates/project-tee-starter/Dockerfile +66 -0
  109. package/dist/templates/project-tee-starter/GUIDE.md +235 -0
  110. package/dist/templates/project-tee-starter/README.md +173 -0
  111. package/dist/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
  112. package/dist/templates/project-tee-starter/__tests__/character.test.ts +86 -0
  113. package/dist/templates/project-tee-starter/__tests__/config.test.ts +31 -0
  114. package/dist/templates/project-tee-starter/__tests__/env.test.ts +87 -0
  115. package/dist/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
  116. package/dist/templates/project-tee-starter/__tests__/events.test.ts +21 -0
  117. package/{templates/project-starter → dist/templates/project-tee-starter}/__tests__/file-structure.test.ts +6 -6
  118. package/dist/templates/project-tee-starter/__tests__/integration.test.ts +205 -0
  119. package/dist/templates/project-tee-starter/__tests__/models.test.ts +22 -0
  120. package/dist/templates/project-tee-starter/__tests__/plugin.test.ts +38 -0
  121. package/dist/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
  122. package/dist/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
  123. package/dist/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
  124. package/dist/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
  125. package/dist/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
  126. package/dist/templates/project-tee-starter/bunfig.toml +6 -0
  127. package/dist/templates/project-tee-starter/docker-compose.yaml +57 -0
  128. package/dist/templates/project-tee-starter/e2e/project.test.ts +38 -0
  129. package/dist/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
  130. package/dist/templates/project-tee-starter/package.json +74 -0
  131. package/dist/templates/project-tee-starter/src/character.ts +257 -0
  132. package/dist/templates/project-tee-starter/src/index.ts +33 -0
  133. package/dist/templates/project-tee-starter/src/plugin.ts +169 -0
  134. package/dist/templates/project-tee-starter/tsconfig.build.json +13 -0
  135. package/dist/templates/project-tee-starter/tsconfig.json +30 -0
  136. package/dist/templates/project-tee-starter/tsup.config.ts +19 -0
  137. package/dist/{utils-2G2QVMW3.js → utils-TIALZU53.js} +9 -7
  138. package/package.json +28 -9
  139. package/templates/plugin-starter/README.md +38 -13
  140. package/templates/plugin-starter/bunfig.toml +6 -0
  141. package/templates/plugin-starter/cypress.config.ts +18 -0
  142. package/templates/plugin-starter/index.html +13 -0
  143. package/templates/plugin-starter/package.json +19 -7
  144. package/templates/plugin-starter/postcss.config.js +3 -0
  145. package/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
  146. package/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
  147. package/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
  148. package/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
  149. package/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
  150. package/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
  151. package/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
  152. package/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
  153. package/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
  154. package/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
  155. package/templates/plugin-starter/src/__tests__/integration.test.ts +138 -0
  156. package/templates/plugin-starter/src/__tests__/plugin.test.ts +182 -0
  157. package/templates/plugin-starter/src/__tests__/test-utils.ts +162 -0
  158. package/templates/plugin-starter/src/frontend/index.css +77 -0
  159. package/templates/plugin-starter/src/frontend/index.tsx +164 -0
  160. package/templates/plugin-starter/src/frontend/utils.ts +6 -0
  161. package/templates/plugin-starter/src/index.ts +30 -7
  162. package/templates/plugin-starter/src/tests.ts +6 -0
  163. package/templates/plugin-starter/tailwind.config.js +62 -0
  164. package/templates/plugin-starter/tsconfig.json +8 -8
  165. package/templates/plugin-starter/vite.config.ts +20 -0
  166. package/templates/project-starter/bunfig.toml +6 -0
  167. package/templates/project-starter/cypress.config.ts +31 -0
  168. package/templates/project-starter/index.html +13 -0
  169. package/templates/project-starter/package.json +37 -14
  170. package/templates/project-starter/postcss.config.js +3 -0
  171. package/templates/project-starter/scripts/test-all.sh +101 -0
  172. package/templates/project-starter/src/__tests__/actions.test.ts +155 -0
  173. package/templates/project-starter/src/__tests__/character.test.ts +86 -0
  174. package/templates/project-starter/src/__tests__/config.test.ts +193 -0
  175. package/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
  176. package/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
  177. package/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
  178. package/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
  179. package/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
  180. package/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
  181. package/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
  182. package/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
  183. package/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
  184. package/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
  185. package/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
  186. package/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
  187. package/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
  188. package/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
  189. package/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
  190. package/templates/project-starter/src/__tests__/env.test.ts +87 -0
  191. package/templates/project-starter/src/__tests__/error-handling.test.ts +177 -0
  192. package/templates/project-starter/src/__tests__/events.test.ts +144 -0
  193. package/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
  194. package/templates/project-starter/src/__tests__/integration.test.ts +209 -0
  195. package/templates/project-starter/src/__tests__/models.test.ts +152 -0
  196. package/templates/project-starter/src/__tests__/plugin.test.ts +393 -0
  197. package/templates/project-starter/src/__tests__/provider.test.ts +325 -0
  198. package/templates/project-starter/src/__tests__/routes.test.ts +79 -0
  199. package/templates/project-starter/src/__tests__/test-utils.ts +121 -0
  200. package/templates/project-starter/src/__tests__/utils/core-test-utils.ts +180 -0
  201. package/templates/project-starter/src/frontend/index.css +77 -0
  202. package/templates/project-starter/src/frontend/index.html +19 -0
  203. package/templates/project-starter/src/frontend/index.tsx +98 -0
  204. package/templates/project-starter/src/frontend/utils.ts +6 -0
  205. package/templates/project-starter/src/index.ts +3 -0
  206. package/templates/project-starter/tailwind.config.js +62 -0
  207. package/templates/project-starter/tsconfig.build.json +9 -2
  208. package/templates/project-starter/tsconfig.json +15 -6
  209. package/templates/project-starter/tsup.config.ts +1 -1
  210. package/templates/project-starter/vite.config.ts +39 -0
  211. package/templates/project-tee-starter/__tests__/actions.test.ts +1 -1
  212. package/templates/project-tee-starter/__tests__/character.test.ts +1 -1
  213. package/templates/project-tee-starter/__tests__/config.test.ts +1 -1
  214. package/templates/project-tee-starter/__tests__/env.test.ts +2 -2
  215. package/templates/project-tee-starter/__tests__/error-handling.test.ts +1 -1
  216. package/templates/project-tee-starter/__tests__/events.test.ts +1 -1
  217. package/templates/project-tee-starter/__tests__/file-structure.test.ts +5 -5
  218. package/templates/project-tee-starter/__tests__/integration.test.ts +22 -26
  219. package/templates/project-tee-starter/__tests__/models.test.ts +1 -1
  220. package/templates/project-tee-starter/__tests__/plugin.test.ts +6 -12
  221. package/templates/project-tee-starter/__tests__/provider.test.ts +6 -6
  222. package/templates/project-tee-starter/__tests__/routes.test.ts +1 -1
  223. package/templates/project-tee-starter/__tests__/test-utils.ts +15 -15
  224. package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +3 -3
  225. package/templates/project-tee-starter/bunfig.toml +6 -0
  226. package/templates/project-tee-starter/package.json +10 -12
  227. package/dist/assets/index-CCyz05Yl.js.br +0 -0
  228. package/dist/assets/index-CCyz05Yl.js.map +0 -1
  229. package/dist/assets/index-DeXwJbtm.css +0 -1
  230. package/dist/assets/index-DeXwJbtm.css.br +0 -0
  231. package/dist/chunk-CEE6RKN5.js +0 -2746
  232. package/dist/chunk-TUAYJIF2.js +0 -3649
  233. package/dist/plugin-creator-IK6H4LVZ.js +0 -29165
  234. package/templates/plugin-starter/e2e/starter-plugin.test.ts +0 -171
  235. package/templates/plugin-starter/images/README.md +0 -24
  236. package/templates/plugin-starter/vitest.config.ts +0 -16
  237. package/templates/project-starter/e2e/project.test.ts +0 -34
  238. package/templates/project-starter/e2e/starter-plugin.test.ts +0 -217
  239. package/templates/project-starter/vitest.config.ts +0 -16
  240. package/templates/project-tee-starter/vitest.config.ts +0 -19
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Manual E2E Test Runner
5
+ *
6
+ * This script manually runs the E2E tests without using the broken ElizaOS test runner.
7
+ * It simulates a runtime environment and executes the tests.
8
+ */
9
+
10
+ // First, let's build and run a simple test of the plugin functionality
11
+ console.log('🧪 Running E2E Tests Manually\n');
12
+
13
+ // Import the built plugin
14
+ import starterPlugin from '../dist/index.js';
15
+
16
+ // Create a mock runtime
17
+ const mockRuntime = {
18
+ character: {
19
+ name: 'Eliza',
20
+ },
21
+ actions: starterPlugin.actions || [],
22
+ providers: starterPlugin.providers || [],
23
+ services: new Map(),
24
+ getService: function (name) {
25
+ if (name === 'starter' && starterPlugin.services) {
26
+ // Create a mock service instance
27
+ return {
28
+ capabilityDescription:
29
+ 'This is a starter service which is attached to the agent through the starter plugin.',
30
+ stop: async () => {
31
+ console.log('Service stopped');
32
+ },
33
+ };
34
+ }
35
+ return null;
36
+ },
37
+ };
38
+
39
+ // Manually define the tests since we can't import TypeScript files directly
40
+ const tests = [
41
+ {
42
+ name: 'example_test',
43
+ fn: async (runtime) => {
44
+ // Test the character name
45
+ if (runtime.character.name !== 'Eliza') {
46
+ throw new Error(
47
+ `Expected character name to be "Eliza" but got "${runtime.character.name}"`
48
+ );
49
+ }
50
+ // Verify the plugin is loaded properly
51
+ const service = runtime.getService('starter');
52
+ if (!service) {
53
+ throw new Error('Starter service not found');
54
+ }
55
+ },
56
+ },
57
+ {
58
+ name: 'should_have_hello_world_action',
59
+ fn: async (runtime) => {
60
+ // Check if the hello world action is registered
61
+ const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');
62
+ if (!actionExists) {
63
+ throw new Error('Hello world action not found in runtime actions');
64
+ }
65
+ },
66
+ },
67
+ {
68
+ name: 'hello_world_action_test',
69
+ fn: async (runtime) => {
70
+ // Find the hello world action
71
+ const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');
72
+ if (!helloWorldAction) {
73
+ throw new Error('Hello world action not found in runtime actions');
74
+ }
75
+
76
+ // Create test data
77
+ const testMessage = {
78
+ entityId: '12345678-1234-1234-1234-123456789012',
79
+ roomId: '12345678-1234-1234-1234-123456789012',
80
+ content: {
81
+ text: 'Can you say hello?',
82
+ source: 'test',
83
+ actions: ['HELLO_WORLD'],
84
+ },
85
+ };
86
+
87
+ const testState = {
88
+ values: {},
89
+ data: {},
90
+ text: '',
91
+ };
92
+
93
+ let responseText = '';
94
+ let responseReceived = false;
95
+
96
+ // Create a callback
97
+ const callback = async (response) => {
98
+ responseReceived = true;
99
+ responseText = response.text || '';
100
+
101
+ if (!response.actions?.includes('HELLO_WORLD')) {
102
+ throw new Error('Response did not include HELLO_WORLD action');
103
+ }
104
+
105
+ return Promise.resolve([]);
106
+ };
107
+
108
+ // Execute the action
109
+ await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);
110
+
111
+ // Verify response
112
+ if (!responseReceived) {
113
+ throw new Error('Hello world action did not produce a response');
114
+ }
115
+
116
+ if (!responseText.toLowerCase().includes('hello world')) {
117
+ throw new Error(`Expected response to contain "hello world" but got: "${responseText}"`);
118
+ }
119
+ },
120
+ },
121
+ {
122
+ name: 'hello_world_provider_test',
123
+ fn: async (runtime) => {
124
+ // Find the hello world provider
125
+ const helloWorldProvider = runtime.providers?.find((p) => p.name === 'HELLO_WORLD_PROVIDER');
126
+ if (!helloWorldProvider) {
127
+ throw new Error('Hello world provider not found in runtime providers');
128
+ }
129
+
130
+ // Test data
131
+ const testMessage = {
132
+ entityId: '12345678-1234-1234-1234-123456789012',
133
+ roomId: '12345678-1234-1234-1234-123456789012',
134
+ content: {
135
+ text: 'What can you provide?',
136
+ source: 'test',
137
+ },
138
+ };
139
+
140
+ const testState = {
141
+ values: {},
142
+ data: {},
143
+ text: '',
144
+ };
145
+
146
+ // Test the provider
147
+ const result = await helloWorldProvider.get(runtime, testMessage, testState);
148
+
149
+ if (result.text !== 'I am a provider') {
150
+ throw new Error(`Expected provider to return "I am a provider", got "${result.text}"`);
151
+ }
152
+ },
153
+ },
154
+ {
155
+ name: 'starter_service_test',
156
+ fn: async (runtime) => {
157
+ // Get the service from the runtime
158
+ const service = runtime.getService('starter');
159
+ if (!service) {
160
+ throw new Error('Starter service not found');
161
+ }
162
+
163
+ // Check service capability description
164
+ if (
165
+ service.capabilityDescription !==
166
+ 'This is a starter service which is attached to the agent through the starter plugin.'
167
+ ) {
168
+ throw new Error('Incorrect service capability description');
169
+ }
170
+
171
+ // Test service stop method
172
+ await service.stop();
173
+ },
174
+ },
175
+ ];
176
+
177
+ console.log(`Test Suite: plugin_starter_test_suite`);
178
+ console.log(`Description: E2E tests for the starter plugin`);
179
+ console.log('─'.repeat(50));
180
+
181
+ let passed = 0;
182
+ let failed = 0;
183
+
184
+ // Run each test
185
+ for (const test of tests) {
186
+ try {
187
+ console.log(`\n▶️ Running test: ${test.name}`);
188
+ await test.fn(mockRuntime);
189
+ console.log(`✅ ${test.name} - PASSED`);
190
+ passed++;
191
+ } catch (error) {
192
+ console.log(`❌ ${test.name} - FAILED`);
193
+ console.log(` Error: ${error.message}`);
194
+ failed++;
195
+ }
196
+ }
197
+
198
+ console.log('\n' + '─'.repeat(50));
199
+ console.log(`\n📊 Test Summary: ${passed} passed, ${failed} failed\n`);
200
+
201
+ process.exit(failed > 0 ? 1 : 0);
@@ -0,0 +1,404 @@
1
+ /// <reference types="cypress" />
2
+ /// <reference types="@cypress/react" />
3
+ /// <reference types="@testing-library/cypress" />
4
+
5
+ import React from 'react';
6
+ import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
7
+ import '../../../frontend/index.css';
8
+
9
+ // Define the interface for time response
10
+ interface TimeResponse {
11
+ timestamp: string;
12
+ unix: number;
13
+ formatted: string;
14
+ timezone: string;
15
+ }
16
+
17
+ // Define ELIZA config interface
18
+ interface ElizaConfig {
19
+ agentId: string;
20
+ apiBase?: string; // Make optional to fix type error
21
+ }
22
+
23
+ declare global {
24
+ interface Window {
25
+ ELIZA_CONFIG: ElizaConfig | undefined;
26
+ }
27
+ }
28
+
29
+ describe('ExampleRoute Component Tests', () => {
30
+ // Component definitions inside describe block to have access to cy
31
+ const TimeDisplay = ({ apiBase }: { apiBase: string }) => {
32
+ const { data, isLoading, error, refetch } = useQuery<TimeResponse>({
33
+ queryKey: ['currentTime'],
34
+ queryFn: async () => {
35
+ const response = await fetch(`${apiBase}/api/time`);
36
+ if (!response.ok) {
37
+ throw new Error('Failed to fetch time');
38
+ }
39
+ return response.json();
40
+ },
41
+ refetchInterval: 1000, // Refresh every second
42
+ });
43
+
44
+ if (isLoading) {
45
+ return <div className="text-gray-600">Loading time...</div>;
46
+ }
47
+
48
+ if (error) {
49
+ return (
50
+ <div className="text-red-600">
51
+ Error fetching time: {error instanceof Error ? error.message : 'Unknown error'}
52
+ </div>
53
+ );
54
+ }
55
+
56
+ return (
57
+ <div className="space-y-2" data-testid="time-display">
58
+ <h2 className="text-lg font-semibold">Current Time</h2>
59
+ <div className="space-y-1 text-sm">
60
+ <div>
61
+ <span className="font-medium">Formatted:</span> {data?.formatted}
62
+ </div>
63
+ <div>
64
+ <span className="font-medium">Timezone:</span> {data?.timezone}
65
+ </div>
66
+ <div>
67
+ <span className="font-medium">Unix:</span> {data?.unix}
68
+ </div>
69
+ </div>
70
+ <button
71
+ onClick={() => refetch()}
72
+ className="px-3 py-1 text-sm bg-primary text-primary-foreground rounded hover:opacity-90"
73
+ data-testid="refresh-button"
74
+ >
75
+ Refresh
76
+ </button>
77
+ </div>
78
+ );
79
+ };
80
+
81
+ const ExampleRoute = () => {
82
+ const [config] = React.useState(window.ELIZA_CONFIG);
83
+ const apiBase = config?.apiBase || 'http://localhost:3000';
84
+
85
+ React.useEffect(() => {
86
+ document.documentElement.classList.add('dark');
87
+ }, []);
88
+
89
+ if (!config?.agentId) {
90
+ return (
91
+ <div className="p-4 text-center">
92
+ <div className="text-red-600 font-medium">Error: Agent ID not found</div>
93
+ <div className="text-sm text-gray-600 mt-2">
94
+ The server should inject the agent ID configuration.
95
+ </div>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ return (
101
+ <QueryClientProvider client={new QueryClient()}>
102
+ <div className="p-6 space-y-6">
103
+ <div>
104
+ <h1 className="text-2xl font-bold mb-2">Plugin Starter Example</h1>
105
+ <div className="text-sm text-muted-foreground">Agent ID: {config.agentId}</div>
106
+ </div>
107
+ <TimeDisplay apiBase={apiBase} />
108
+ </div>
109
+ </QueryClientProvider>
110
+ );
111
+ };
112
+
113
+ describe('Component Rendering', () => {
114
+ it('should apply dark mode on mount', () => {
115
+ cy.mount(<ExampleRoute />);
116
+ cy.shouldBeDarkMode();
117
+ });
118
+
119
+ it('should show error when agent ID is missing', () => {
120
+ // Clear the config before mounting
121
+ cy.window().then((win) => {
122
+ win.ELIZA_CONFIG = undefined;
123
+ });
124
+
125
+ cy.mount(<ExampleRoute />);
126
+
127
+ // Check error message is displayed
128
+ cy.contains('Error: Agent ID not found').should('be.visible');
129
+ cy.contains('The server should inject the agent ID configuration.').should('be.visible');
130
+ });
131
+
132
+ it('should render correctly with agent ID', () => {
133
+ const testAgentId = '12345678-1234-1234-1234-123456789abc';
134
+
135
+ // Set config before mounting
136
+ cy.window().then((win) => {
137
+ win.ELIZA_CONFIG = {
138
+ agentId: testAgentId,
139
+ apiBase: 'http://localhost:3000',
140
+ };
141
+ });
142
+
143
+ cy.mount(<ExampleRoute />);
144
+
145
+ // Check that the agent ID is displayed
146
+ cy.contains('Plugin Starter Example').should('be.visible');
147
+ cy.contains(`Agent ID: ${testAgentId}`).should('be.visible');
148
+ });
149
+ });
150
+
151
+ describe('API Communication', () => {
152
+ beforeEach(() => {
153
+ // Set up ELIZA_CONFIG
154
+ cy.window().then((win) => {
155
+ win.ELIZA_CONFIG = {
156
+ agentId: 'test-agent-123',
157
+ apiBase: 'http://localhost:3000',
158
+ };
159
+ });
160
+ });
161
+
162
+ it('should fetch and display time from backend', () => {
163
+ // Mock the API response
164
+ cy.intercept('GET', '**/api/time', {
165
+ statusCode: 200,
166
+ body: {
167
+ timestamp: '2024-01-01T12:00:00.000Z',
168
+ unix: 1704110400,
169
+ formatted: '1/1/2024, 12:00:00 PM',
170
+ timezone: 'UTC',
171
+ },
172
+ }).as('getTime');
173
+
174
+ cy.mount(<ExampleRoute />);
175
+
176
+ // Wait for the API call
177
+ cy.wait('@getTime');
178
+
179
+ // Check that time data is displayed
180
+ cy.get('[data-testid="time-display"]').should('be.visible');
181
+ cy.contains('Current Time').should('be.visible');
182
+ cy.contains('Formatted: 1/1/2024, 12:00:00 PM').should('be.visible');
183
+ cy.contains('Timezone: UTC').should('be.visible');
184
+ cy.contains('Unix: 1704110400').should('be.visible');
185
+ });
186
+
187
+ it('should refresh time when refresh button is clicked', () => {
188
+ let callCount = 0;
189
+
190
+ // Mock multiple API responses
191
+ cy.intercept('GET', '**/api/time', (req) => {
192
+ callCount++;
193
+ req.reply({
194
+ statusCode: 200,
195
+ body: {
196
+ timestamp: new Date().toISOString(),
197
+ unix: Math.floor(Date.now() / 1000) + callCount,
198
+ formatted: `Call ${callCount}: ${new Date().toLocaleString()}`,
199
+ timezone: 'UTC',
200
+ },
201
+ });
202
+ }).as('getTime');
203
+
204
+ cy.mount(<ExampleRoute />);
205
+
206
+ // Wait for initial load
207
+ cy.wait('@getTime');
208
+ cy.contains('Call 1:').should('be.visible');
209
+
210
+ // Click refresh button
211
+ cy.get('[data-testid="refresh-button"]').click();
212
+
213
+ // Wait for refresh
214
+ cy.wait('@getTime');
215
+ cy.contains('Call 2:').should('be.visible');
216
+ });
217
+
218
+ it('should verify auto-refresh behavior', () => {
219
+ let callCount = 0;
220
+
221
+ cy.intercept('GET', '**/api/time', (req) => {
222
+ callCount++;
223
+ req.reply({
224
+ statusCode: 200,
225
+ body: {
226
+ timestamp: new Date().toISOString(),
227
+ unix: Math.floor(Date.now() / 1000),
228
+ formatted: `Update ${callCount}`,
229
+ timezone: 'UTC',
230
+ },
231
+ });
232
+ }).as('getTime');
233
+
234
+ cy.mount(<ExampleRoute />);
235
+
236
+ // Wait for initial load
237
+ cy.wait('@getTime');
238
+ cy.contains('Update 1').should('be.visible');
239
+
240
+ // Verify multiple API calls happen due to auto-refresh
241
+ cy.wait('@getTime', { timeout: 2000 });
242
+ cy.get('@getTime.all').should('have.length.greaterThan', 1);
243
+ });
244
+
245
+ it('should show loading state', () => {
246
+ // Add delay to see loading state
247
+ cy.intercept('GET', '**/api/time', (req) => {
248
+ // Instead of req.reply with a callback, use a simpler approach
249
+ req.reply({
250
+ statusCode: 200,
251
+ body: {
252
+ timestamp: new Date().toISOString(),
253
+ unix: Math.floor(Date.now() / 1000),
254
+ formatted: new Date().toLocaleString(),
255
+ timezone: 'UTC',
256
+ },
257
+ delay: 1000, // Add delay directly
258
+ });
259
+ }).as('getTimeDelayed');
260
+
261
+ cy.mount(<ExampleRoute />);
262
+
263
+ // Check loading state
264
+ cy.contains('Loading time...').should('be.visible');
265
+
266
+ // Wait for data to load
267
+ cy.wait('@getTimeDelayed');
268
+ cy.contains('Loading time...').should('not.exist');
269
+ cy.get('[data-testid="time-display"]').should('be.visible');
270
+ });
271
+ });
272
+
273
+ describe('Configuration Handling', () => {
274
+ it('should handle different API base URLs', () => {
275
+ const customApiBase = 'https://api.example.com';
276
+
277
+ cy.window().then((win) => {
278
+ win.ELIZA_CONFIG = {
279
+ agentId: 'test-agent',
280
+ apiBase: customApiBase,
281
+ };
282
+ });
283
+
284
+ // Intercept with custom base URL
285
+ cy.intercept('GET', `${customApiBase}/api/time`, {
286
+ statusCode: 200,
287
+ body: {
288
+ timestamp: new Date().toISOString(),
289
+ unix: Math.floor(Date.now() / 1000),
290
+ formatted: 'Custom API Response',
291
+ timezone: 'UTC',
292
+ },
293
+ }).as('getTimeCustom');
294
+
295
+ cy.mount(<ExampleRoute />);
296
+
297
+ cy.wait('@getTimeCustom');
298
+ cy.contains('Custom API Response').should('be.visible');
299
+ });
300
+
301
+ it('should use default API base when not provided', () => {
302
+ cy.window().then((win) => {
303
+ win.ELIZA_CONFIG = {
304
+ agentId: 'test-agent',
305
+ // No apiBase provided - this is now valid with optional apiBase
306
+ };
307
+ });
308
+
309
+ // Intercept with default base URL
310
+ cy.intercept('GET', 'http://localhost:3000/api/time', {
311
+ statusCode: 200,
312
+ body: {
313
+ timestamp: new Date().toISOString(),
314
+ unix: Math.floor(Date.now() / 1000),
315
+ formatted: 'Default API Response',
316
+ timezone: 'UTC',
317
+ },
318
+ }).as('getTimeDefault');
319
+
320
+ cy.mount(<ExampleRoute />);
321
+
322
+ cy.wait('@getTimeDefault');
323
+ cy.contains('Default API Response').should('be.visible');
324
+ });
325
+ });
326
+
327
+ describe('Accessibility', () => {
328
+ beforeEach(() => {
329
+ cy.window().then((win) => {
330
+ win.ELIZA_CONFIG = {
331
+ agentId: 'test-agent',
332
+ apiBase: 'http://localhost:3000',
333
+ };
334
+ });
335
+
336
+ cy.intercept('GET', '**/api/time', {
337
+ statusCode: 200,
338
+ body: {
339
+ timestamp: new Date().toISOString(),
340
+ unix: Math.floor(Date.now() / 1000),
341
+ formatted: new Date().toLocaleString(),
342
+ timezone: 'UTC',
343
+ },
344
+ }).as('getTime');
345
+ });
346
+
347
+ it('should have proper heading hierarchy', () => {
348
+ cy.mount(<ExampleRoute />);
349
+ cy.wait('@getTime');
350
+
351
+ // Check h1 exists
352
+ cy.get('h1').contains('Plugin Starter Example').should('be.visible');
353
+
354
+ // Check h2 exists
355
+ cy.get('h2').contains('Current Time').should('be.visible');
356
+ });
357
+
358
+ it('should have accessible button', () => {
359
+ cy.mount(<ExampleRoute />);
360
+ cy.wait('@getTime');
361
+
362
+ // Button should be focusable and clickable
363
+ cy.get('[data-testid="refresh-button"]')
364
+ .should('be.visible')
365
+ .should('not.be.disabled')
366
+ .focus()
367
+ .should('have.focus');
368
+ });
369
+ });
370
+ });
371
+
372
+ /**
373
+ * TESTING PATTERNS FOR FRONTEND COMPONENTS IN ELIZAOS
374
+ *
375
+ * 1. COMPONENT ISOLATION
376
+ * - Test components in isolation using cy.mount()
377
+ * - Mock external dependencies (like API calls)
378
+ * - Use data-testid attributes for reliable element selection
379
+ *
380
+ * 2. CONFIGURATION TESTING
381
+ * - Always test with and without ELIZA_CONFIG
382
+ * - Test with invalid/malformed configurations
383
+ * - Verify error states and fallbacks
384
+ *
385
+ * 3. DARK MODE SUPPORT
386
+ * - Ensure components work in both light and dark modes
387
+ * - Use the custom shouldBeDarkMode() command
388
+ *
389
+ * 4. QUERY CLIENT TESTING
390
+ * - Mock API responses for react-query
391
+ * - Test loading, error, and success states
392
+ * - Verify cache behavior
393
+ *
394
+ * 5. ACCESSIBILITY
395
+ * - Use Testing Library queries (findByRole, findByText)
396
+ * - Test keyboard navigation
397
+ * - Verify ARIA attributes
398
+ *
399
+ * 6. API INTEGRATION TESTING
400
+ * - Mock all external API calls
401
+ * - Test error handling
402
+ * - Verify retry logic
403
+ * - Test different response scenarios
404
+ */