snow-flow 1.1.76 → 1.1.78

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 (234) hide show
  1. package/.claude-flow/queen/queen-memory.db +0 -0
  2. package/CLAUDE.md +34 -5
  3. package/README.md +256 -384
  4. package/dist/agents/base-agent.d.ts +92 -0
  5. package/dist/agents/base-agent.d.ts.map +1 -0
  6. package/dist/agents/base-agent.js +228 -0
  7. package/dist/agents/base-agent.js.map +1 -0
  8. package/dist/agents/coordinator.d.ts +200 -0
  9. package/dist/agents/coordinator.d.ts.map +1 -0
  10. package/dist/agents/coordinator.js +775 -0
  11. package/dist/agents/coordinator.js.map +1 -0
  12. package/dist/agents/flow-builder-agent.d.ts +18 -0
  13. package/dist/agents/flow-builder-agent.d.ts.map +1 -0
  14. package/dist/agents/flow-builder-agent.js +536 -0
  15. package/dist/agents/flow-builder-agent.js.map +1 -0
  16. package/dist/agents/index.d.ts +18 -0
  17. package/dist/agents/index.d.ts.map +1 -0
  18. package/dist/agents/index.js +61 -0
  19. package/dist/agents/index.js.map +1 -0
  20. package/dist/agents/queen-agent-example.d.ts +23 -0
  21. package/dist/agents/queen-agent-example.d.ts.map +1 -0
  22. package/dist/agents/queen-agent-example.js +241 -0
  23. package/dist/agents/queen-agent-example.js.map +1 -0
  24. package/dist/agents/queen-agent.d.ts +180 -0
  25. package/dist/agents/queen-agent.d.ts.map +1 -0
  26. package/dist/agents/queen-agent.js +909 -0
  27. package/dist/agents/queen-agent.js.map +1 -0
  28. package/dist/agents/queen-agent.test.d.ts +6 -0
  29. package/dist/agents/queen-agent.test.d.ts.map +1 -0
  30. package/dist/agents/queen-agent.test.js.map +1 -0
  31. package/dist/agents/script-writer-agent.d.ts +22 -0
  32. package/dist/agents/script-writer-agent.d.ts.map +1 -0
  33. package/dist/agents/script-writer-agent.js +695 -0
  34. package/dist/agents/script-writer-agent.js.map +1 -0
  35. package/dist/agents/security-agent.d.ts +23 -0
  36. package/dist/agents/security-agent.d.ts.map +1 -0
  37. package/dist/agents/security-agent.js +619 -0
  38. package/dist/agents/security-agent.js.map +1 -0
  39. package/dist/agents/test-agent.d.ts +26 -0
  40. package/dist/agents/test-agent.d.ts.map +1 -0
  41. package/dist/agents/test-agent.js +735 -0
  42. package/dist/agents/test-agent.js.map +1 -0
  43. package/dist/agents/test-agents.d.ts +7 -0
  44. package/dist/agents/test-agents.d.ts.map +1 -0
  45. package/dist/agents/test-agents.js +65 -0
  46. package/dist/agents/test-agents.js.map +1 -0
  47. package/dist/agents/widget-creator-agent.d.ts +18 -0
  48. package/dist/agents/widget-creator-agent.d.ts.map +1 -0
  49. package/dist/agents/widget-creator-agent.js +440 -0
  50. package/dist/agents/widget-creator-agent.js.map +1 -0
  51. package/dist/cli/snow-flow-cli-integration.d.ts +30 -0
  52. package/dist/cli/snow-flow-cli-integration.d.ts.map +1 -0
  53. package/dist/cli/snow-flow-cli-integration.js +385 -0
  54. package/dist/cli/snow-flow-cli-integration.js.map +1 -0
  55. package/dist/cli.js +466 -150
  56. package/dist/cli.js.map +1 -1
  57. package/dist/config/snow-flow-config.d.ts +1454 -0
  58. package/dist/config/snow-flow-config.d.ts.map +1 -0
  59. package/dist/config/snow-flow-config.js +403 -0
  60. package/dist/config/snow-flow-config.js.map +1 -0
  61. package/dist/health/system-health.d.ts +123 -0
  62. package/dist/health/system-health.d.ts.map +1 -0
  63. package/dist/health/system-health.js +580 -0
  64. package/dist/health/system-health.js.map +1 -0
  65. package/dist/index.d.ts +12 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +19 -3
  68. package/dist/index.js.map +1 -1
  69. package/dist/mcp/servicenow-deployment-mcp-refactored.d.ts +58 -0
  70. package/dist/mcp/servicenow-deployment-mcp-refactored.d.ts.map +1 -0
  71. package/dist/mcp/servicenow-deployment-mcp-refactored.js +651 -0
  72. package/dist/mcp/servicenow-deployment-mcp-refactored.js.map +1 -0
  73. package/dist/mcp/servicenow-intelligent-mcp-refactored.d.ts +43 -0
  74. package/dist/mcp/servicenow-intelligent-mcp-refactored.d.ts.map +1 -0
  75. package/dist/mcp/servicenow-intelligent-mcp-refactored.js +576 -0
  76. package/dist/mcp/servicenow-intelligent-mcp-refactored.js.map +1 -0
  77. package/dist/mcp/servicenow-intelligent-mcp.d.ts +102 -1
  78. package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -1
  79. package/dist/mcp/servicenow-intelligent-mcp.js +2 -0
  80. package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -1
  81. package/dist/mcp/shared/agent-context-provider.d.ts +77 -0
  82. package/dist/mcp/shared/agent-context-provider.d.ts.map +1 -0
  83. package/dist/mcp/shared/agent-context-provider.js +292 -0
  84. package/dist/mcp/shared/agent-context-provider.js.map +1 -0
  85. package/dist/mcp/shared/base-mcp-server.d.ts +97 -0
  86. package/dist/mcp/shared/base-mcp-server.d.ts.map +1 -0
  87. package/dist/mcp/shared/base-mcp-server.js +216 -0
  88. package/dist/mcp/shared/base-mcp-server.js.map +1 -0
  89. package/dist/mcp/shared/mcp-memory-manager.d.ts +87 -0
  90. package/dist/mcp/shared/mcp-memory-manager.d.ts.map +1 -0
  91. package/dist/mcp/shared/mcp-memory-manager.js +423 -0
  92. package/dist/mcp/shared/mcp-memory-manager.js.map +1 -0
  93. package/dist/memory/index.d.ts +9 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +20 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/mcp-integration-example.d.ts +6 -0
  98. package/dist/memory/mcp-integration-example.d.ts.map +1 -0
  99. package/dist/memory/mcp-integration-example.js +282 -0
  100. package/dist/memory/mcp-integration-example.js.map +1 -0
  101. package/dist/memory/memory-client.d.ts +184 -0
  102. package/dist/memory/memory-client.d.ts.map +1 -0
  103. package/dist/memory/memory-client.js +325 -0
  104. package/dist/memory/memory-client.js.map +1 -0
  105. package/dist/memory/memory-operations.d.ts +170 -0
  106. package/dist/memory/memory-operations.d.ts.map +1 -0
  107. package/dist/memory/memory-operations.js +639 -0
  108. package/dist/memory/memory-operations.js.map +1 -0
  109. package/dist/memory/memory-system.d.ts +118 -0
  110. package/dist/memory/memory-system.d.ts.map +1 -0
  111. package/dist/memory/memory-system.js +477 -0
  112. package/dist/memory/memory-system.js.map +1 -0
  113. package/dist/memory/memory-test.d.ts +6 -0
  114. package/dist/memory/memory-test.d.ts.map +1 -0
  115. package/dist/memory/memory-test.js +162 -0
  116. package/dist/memory/memory-test.js.map +1 -0
  117. package/dist/memory/swarm-memory.d.ts +135 -0
  118. package/dist/memory/swarm-memory.d.ts.map +1 -0
  119. package/dist/memory/swarm-memory.js +378 -0
  120. package/dist/memory/swarm-memory.js.map +1 -0
  121. package/dist/monitoring/performance-tracker.d.ts +157 -0
  122. package/dist/monitoring/performance-tracker.d.ts.map +1 -0
  123. package/dist/monitoring/performance-tracker.js +571 -0
  124. package/dist/monitoring/performance-tracker.js.map +1 -0
  125. package/dist/queen/agent-factory.d.ts +3 -0
  126. package/dist/queen/agent-factory.d.ts.map +1 -1
  127. package/dist/queen/agent-factory.js +52 -0
  128. package/dist/queen/agent-factory.js.map +1 -1
  129. package/dist/queen/queen-memory.d.ts +8 -2
  130. package/dist/queen/queen-memory.d.ts.map +1 -1
  131. package/dist/queen/queen-memory.js +46 -4
  132. package/dist/queen/queen-memory.js.map +1 -1
  133. package/dist/snow-flow-system.d.ts +132 -0
  134. package/dist/snow-flow-system.d.ts.map +1 -0
  135. package/dist/snow-flow-system.js +396 -0
  136. package/dist/snow-flow-system.js.map +1 -0
  137. package/dist/types/todo.types.d.ts +61 -0
  138. package/dist/types/todo.types.d.ts.map +1 -0
  139. package/dist/types/todo.types.js +7 -0
  140. package/dist/types/todo.types.js.map +1 -0
  141. package/dist/utils/error-recovery.d.ts +101 -0
  142. package/dist/utils/error-recovery.d.ts.map +1 -0
  143. package/dist/utils/error-recovery.js +548 -0
  144. package/dist/utils/error-recovery.js.map +1 -0
  145. package/dist/version.d.ts +1 -1
  146. package/dist/version.js +1 -1
  147. package/package.json +7 -2
  148. package/deploy.sh +0 -366
  149. package/docker/base/Dockerfile.base +0 -45
  150. package/docker/generate-services.js +0 -244
  151. package/docker/nginx/Dockerfile +0 -71
  152. package/docker/nginx/consul-template.hcl +0 -64
  153. package/docker/nginx/healthcheck.sh +0 -178
  154. package/docker/nginx/nginx.conf +0 -210
  155. package/docker/nginx/supervisord.conf +0 -57
  156. package/docker/nginx/templates/upstreams.conf.tpl +0 -48
  157. package/docker/services/automation-mcp/Dockerfile +0 -32
  158. package/docker/services/automation-mcp/config/service.json +0 -28
  159. package/docker/services/automation-mcp/entrypoint.js +0 -51
  160. package/docker/services/deployment-mcp/Dockerfile +0 -32
  161. package/docker/services/deployment-mcp/entrypoint.js +0 -51
  162. package/docker/services/flow-composer-mcp/Dockerfile +0 -32
  163. package/docker/services/flow-composer-mcp/config/service.json +0 -28
  164. package/docker/services/flow-composer-mcp/entrypoint.js +0 -51
  165. package/docker/services/graph-memory-mcp/Dockerfile +0 -32
  166. package/docker/services/graph-memory-mcp/config/service.json +0 -28
  167. package/docker/services/graph-memory-mcp/entrypoint.js +0 -51
  168. package/docker/services/integration-mcp/Dockerfile +0 -32
  169. package/docker/services/integration-mcp/config/service.json +0 -28
  170. package/docker/services/integration-mcp/entrypoint.js +0 -51
  171. package/docker/services/intelligent-mcp/Dockerfile +0 -32
  172. package/docker/services/intelligent-mcp/config/service.json +0 -28
  173. package/docker/services/intelligent-mcp/entrypoint.js +0 -51
  174. package/docker/services/operations-mcp/Dockerfile +0 -32
  175. package/docker/services/operations-mcp/config/service.json +0 -28
  176. package/docker/services/operations-mcp/entrypoint.js +0 -51
  177. package/docker/services/platform-development-mcp/Dockerfile +0 -32
  178. package/docker/services/platform-development-mcp/config/service.json +0 -28
  179. package/docker/services/platform-development-mcp/entrypoint.js +0 -51
  180. package/docker/services/reporting-analytics-mcp/Dockerfile +0 -32
  181. package/docker/services/reporting-analytics-mcp/config/service.json +0 -28
  182. package/docker/services/reporting-analytics-mcp/entrypoint.js +0 -51
  183. package/docker/services/security-compliance-mcp/Dockerfile +0 -32
  184. package/docker/services/security-compliance-mcp/config/service.json +0 -28
  185. package/docker/services/security-compliance-mcp/entrypoint.js +0 -51
  186. package/docker/services/update-set-mcp/Dockerfile +0 -32
  187. package/docker/services/update-set-mcp/config/service.json +0 -28
  188. package/docker/services/update-set-mcp/entrypoint.js +0 -51
  189. package/docker-compose.override.yml +0 -132
  190. package/docker-compose.prod.yml +0 -340
  191. package/docker-compose.yml +0 -579
  192. package/k8s/automation-mcp.yaml +0 -232
  193. package/k8s/configmap.yaml +0 -237
  194. package/k8s/deployment-mcp.yaml +0 -232
  195. package/k8s/flow-composer-mcp.yaml +0 -232
  196. package/k8s/generate-k8s-manifests.js +0 -453
  197. package/k8s/graph-memory-mcp.yaml +0 -232
  198. package/k8s/infrastructure.yaml +0 -456
  199. package/k8s/ingress.yaml +0 -361
  200. package/k8s/integration-mcp.yaml +0 -232
  201. package/k8s/intelligent-mcp.yaml +0 -232
  202. package/k8s/kustomization.yaml +0 -111
  203. package/k8s/mcp-services.yaml +0 -2552
  204. package/k8s/monitoring.yaml +0 -515
  205. package/k8s/namespace.yaml +0 -80
  206. package/k8s/operations-mcp.yaml +0 -232
  207. package/k8s/platform-development-mcp.yaml +0 -232
  208. package/k8s/rbac.yaml +0 -140
  209. package/k8s/reporting-analytics-mcp.yaml +0 -232
  210. package/k8s/security-compliance-mcp.yaml +0 -232
  211. package/k8s/update-set-mcp.yaml +0 -232
  212. package/test-clean-install/.claude/config.json +0 -12
  213. package/test-clean-install/.env.example +0 -49
  214. package/test-clean-install/CLAUDE.md +0 -26
  215. package/test-clean-install/README.md +0 -23
  216. package/test-global-install/.claude/config.json +0 -12
  217. package/test-global-install/CLAUDE.md +0 -26
  218. package/test-global-install/README.md +0 -23
  219. package/test-global-install/test-global-install/.claude/config.json +0 -12
  220. package/test-global-install/test-global-install/CLAUDE.md +0 -26
  221. package/test-global-install/test-global-install/README.md +0 -23
  222. package/test-global-install/test-global-install/test-global-install/.claude/config.json +0 -12
  223. package/test-global-install/test-global-install/test-global-install/.env.example +0 -49
  224. package/test-global-install/test-global-install/test-global-install/CLAUDE.md +0 -26
  225. package/test-global-install/test-global-install/test-global-install/README.md +0 -23
  226. package/test-init-debug/.claude/config.json +0 -12
  227. package/test-init-debug/CLAUDE.md +0 -693
  228. package/test-init-debug/README.md +0 -392
  229. package/test-init-real/.claude/config.json +0 -12
  230. package/test-init-real/.claude/mcp-config.json +0 -128
  231. package/test-init-real/.claude/settings.json +0 -37
  232. package/test-init-real/CLAUDE.md +0 -693
  233. package/test-init-real/README.md +0 -392
  234. package/test-init-real/activate-mcp.sh +0 -15
@@ -0,0 +1,735 @@
1
+ "use strict";
2
+ /**
3
+ * Test Agent
4
+ * Specializes in testing ServiceNow artifacts and ensuring quality
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.TestAgent = void 0;
8
+ const base_agent_1 = require("./base-agent");
9
+ class TestAgent extends base_agent_1.BaseAgent {
10
+ constructor(config) {
11
+ super({
12
+ type: 'tester',
13
+ capabilities: [
14
+ 'Test scenario creation',
15
+ 'Mock data generation',
16
+ 'Integration testing',
17
+ 'Performance validation',
18
+ 'Quality assurance',
19
+ 'Automated test execution',
20
+ 'Edge case identification',
21
+ 'Security testing',
22
+ 'User acceptance testing'
23
+ ],
24
+ mcpTools: [
25
+ 'snow_test_flow_with_mock',
26
+ 'snow_widget_test',
27
+ 'snow_comprehensive_flow_test',
28
+ 'snow_cleanup_test_artifacts',
29
+ 'snow_preview_widget',
30
+ 'snow_validate_flow_definition',
31
+ 'snow_performance_test'
32
+ ],
33
+ ...config
34
+ });
35
+ }
36
+ async execute(instruction, context) {
37
+ try {
38
+ this.setStatus('working');
39
+ await this.reportProgress('Starting test execution', 0);
40
+ // Analyze what needs to be tested
41
+ const testRequirements = await this.analyzeTestRequirements(instruction, context);
42
+ await this.reportProgress('Analyzed test requirements', 15);
43
+ // Retrieve artifacts to test
44
+ const artifacts = await this.retrieveArtifacts(testRequirements);
45
+ if (!artifacts || artifacts.length === 0) {
46
+ throw new Error('No artifacts found to test');
47
+ }
48
+ await this.reportProgress('Retrieved artifacts for testing', 25);
49
+ // Generate test scenarios
50
+ const testScenarios = await this.generateTestScenarios(artifacts, testRequirements);
51
+ await this.reportProgress(`Generated ${testScenarios.length} test scenarios`, 35);
52
+ // Generate mock data
53
+ const mockData = await this.generateMockData(testScenarios, artifacts);
54
+ await this.reportProgress('Generated mock test data', 45);
55
+ // Execute tests
56
+ const testResults = [];
57
+ let currentProgress = 50;
58
+ const progressPerTest = 40 / testScenarios.length;
59
+ for (const scenario of testScenarios) {
60
+ const result = await this.executeTestScenario(scenario, artifacts[0], mockData);
61
+ testResults.push(result);
62
+ currentProgress += progressPerTest;
63
+ await this.reportProgress(`Executed test: ${scenario.name}`, Math.round(currentProgress));
64
+ }
65
+ // Analyze test results
66
+ const analysis = await this.analyzeTestResults(testResults);
67
+ await this.reportProgress('Analyzed test results', 92);
68
+ // Clean up test artifacts if all tests passed
69
+ if (analysis.allPassed && testRequirements.cleanupAfterTest) {
70
+ await this.cleanupTestArtifacts();
71
+ await this.reportProgress('Cleaned up test artifacts', 95);
72
+ }
73
+ // Generate test report
74
+ const testReport = this.generateTestReport(testResults, analysis);
75
+ await this.reportProgress('Test execution completed', 100);
76
+ this.setStatus('completed');
77
+ await this.logActivity('test_execution', analysis.allPassed, {
78
+ totalTests: testScenarios.length,
79
+ passed: analysis.passedCount,
80
+ failed: analysis.failedCount,
81
+ coverage: analysis.coverage
82
+ });
83
+ return {
84
+ success: analysis.allPassed,
85
+ message: analysis.allPassed ?
86
+ `All ${testScenarios.length} tests passed successfully` :
87
+ `${analysis.failedCount} of ${testScenarios.length} tests failed`,
88
+ metadata: {
89
+ testReport,
90
+ testResults,
91
+ analysis,
92
+ mockDataGenerated: true,
93
+ artifactsTested: artifacts.map(a => ({ type: a.type, name: a.name }))
94
+ }
95
+ };
96
+ }
97
+ catch (error) {
98
+ this.setStatus('failed');
99
+ await this.logActivity('test_execution', false, { error: error.message });
100
+ return {
101
+ success: false,
102
+ error: error,
103
+ message: `Test execution failed: ${error.message}`
104
+ };
105
+ }
106
+ }
107
+ async analyzeTestRequirements(instruction, context) {
108
+ const requirements = {
109
+ artifactTypes: [],
110
+ testTypes: [],
111
+ coverage: 'standard', // minimal, standard, comprehensive
112
+ includeNegativeTests: true,
113
+ includePerformanceTests: false,
114
+ includeSecurityTests: false,
115
+ cleanupAfterTest: true,
116
+ specificArtifact: null
117
+ };
118
+ // Detect artifact types to test
119
+ if (/widget/i.test(instruction)) {
120
+ requirements.artifactTypes.push('widget');
121
+ }
122
+ if (/flow/i.test(instruction)) {
123
+ requirements.artifactTypes.push('flow');
124
+ }
125
+ if (/script/i.test(instruction)) {
126
+ requirements.artifactTypes.push('script');
127
+ }
128
+ if (!requirements.artifactTypes.length) {
129
+ // Test whatever is in context
130
+ requirements.artifactTypes = ['widget', 'flow', 'script'];
131
+ }
132
+ // Detect test types
133
+ if (/integration/i.test(instruction)) {
134
+ requirements.testTypes.push('integration');
135
+ }
136
+ if (/performance/i.test(instruction)) {
137
+ requirements.testTypes.push('performance');
138
+ requirements.includePerformanceTests = true;
139
+ }
140
+ if (/security/i.test(instruction)) {
141
+ requirements.testTypes.push('security');
142
+ requirements.includeSecurityTests = true;
143
+ }
144
+ if (/comprehensive|thorough|extensive/i.test(instruction)) {
145
+ requirements.coverage = 'comprehensive';
146
+ }
147
+ if (/minimal|basic|quick/i.test(instruction)) {
148
+ requirements.coverage = 'minimal';
149
+ requirements.includeNegativeTests = false;
150
+ }
151
+ // Check if specific artifact is mentioned
152
+ const artifactMatch = instruction.match(/test\s+(?:the\s+)?([a-zA-Z0-9_]+)\s+(?:widget|flow|script)/i);
153
+ if (artifactMatch) {
154
+ requirements.specificArtifact = artifactMatch[1];
155
+ }
156
+ return requirements;
157
+ }
158
+ async retrieveArtifacts(requirements) {
159
+ const artifacts = [];
160
+ // Try to retrieve specific artifact first
161
+ if (requirements.specificArtifact) {
162
+ for (const type of requirements.artifactTypes) {
163
+ const artifact = await this.getArtifact(type, requirements.specificArtifact);
164
+ if (artifact) {
165
+ artifacts.push(artifact);
166
+ return artifacts;
167
+ }
168
+ }
169
+ }
170
+ // Otherwise, get recent artifacts of requested types
171
+ for (const type of requirements.artifactTypes) {
172
+ // This would retrieve from shared memory
173
+ // For now, we'll use a placeholder
174
+ const recentArtifact = await this.getArtifact(type, `recent_${type}`);
175
+ if (recentArtifact) {
176
+ artifacts.push(recentArtifact);
177
+ }
178
+ }
179
+ return artifacts;
180
+ }
181
+ async generateTestScenarios(artifacts, requirements) {
182
+ const scenarios = [];
183
+ for (const artifact of artifacts) {
184
+ switch (artifact.type) {
185
+ case 'widget':
186
+ scenarios.push(...this.generateWidgetTestScenarios(artifact, requirements));
187
+ break;
188
+ case 'flow':
189
+ scenarios.push(...this.generateFlowTestScenarios(artifact, requirements));
190
+ break;
191
+ case 'script':
192
+ scenarios.push(...this.generateScriptTestScenarios(artifact, requirements));
193
+ break;
194
+ }
195
+ }
196
+ return scenarios;
197
+ }
198
+ generateWidgetTestScenarios(widget, requirements) {
199
+ const scenarios = [];
200
+ const config = widget.config;
201
+ // Basic rendering test
202
+ scenarios.push({
203
+ name: 'Widget Basic Rendering',
204
+ type: 'positive',
205
+ description: 'Test that widget renders without errors',
206
+ inputs: {
207
+ options: {},
208
+ data: {}
209
+ },
210
+ assertions: [
211
+ 'Widget should render without JavaScript errors',
212
+ 'HTML template should be valid',
213
+ 'CSS should load correctly'
214
+ ]
215
+ });
216
+ // Data loading test
217
+ scenarios.push({
218
+ name: 'Widget Data Loading',
219
+ type: 'positive',
220
+ description: 'Test that widget loads and displays data correctly',
221
+ inputs: {
222
+ server_data: {
223
+ rows: [
224
+ { id: 1, name: 'Test Item 1', status: 'Active' },
225
+ { id: 2, name: 'Test Item 2', status: 'Inactive' }
226
+ ]
227
+ }
228
+ },
229
+ assertions: [
230
+ 'Data should be displayed in the widget',
231
+ 'All rows should be visible',
232
+ 'Data formatting should be correct'
233
+ ]
234
+ });
235
+ // Empty data test
236
+ if (requirements.includeNegativeTests) {
237
+ scenarios.push({
238
+ name: 'Widget Empty Data Handling',
239
+ type: 'negative',
240
+ description: 'Test widget behavior with no data',
241
+ inputs: {
242
+ server_data: {
243
+ rows: []
244
+ }
245
+ },
246
+ assertions: [
247
+ 'Widget should display appropriate empty state message',
248
+ 'No JavaScript errors should occur',
249
+ 'Widget should remain functional'
250
+ ]
251
+ });
252
+ }
253
+ // Responsive design test
254
+ scenarios.push({
255
+ name: 'Widget Responsive Design',
256
+ type: 'edge_case',
257
+ description: 'Test widget on different screen sizes',
258
+ inputs: {
259
+ viewport_sizes: [
260
+ { width: 320, height: 568 }, // Mobile
261
+ { width: 768, height: 1024 }, // Tablet
262
+ { width: 1920, height: 1080 } // Desktop
263
+ ]
264
+ },
265
+ assertions: [
266
+ 'Widget should be responsive on all screen sizes',
267
+ 'Text should remain readable',
268
+ 'No horizontal scrolling on mobile'
269
+ ]
270
+ });
271
+ // Performance test
272
+ if (requirements.includePerformanceTests) {
273
+ scenarios.push({
274
+ name: 'Widget Performance',
275
+ type: 'performance',
276
+ description: 'Test widget performance with large datasets',
277
+ inputs: {
278
+ server_data: {
279
+ rows: Array(1000).fill(null).map((_, i) => ({
280
+ id: i,
281
+ name: `Item ${i}`,
282
+ status: i % 2 === 0 ? 'Active' : 'Inactive'
283
+ }))
284
+ }
285
+ },
286
+ assertions: [
287
+ 'Widget should render within 3 seconds',
288
+ 'Scrolling should be smooth',
289
+ 'Memory usage should be reasonable'
290
+ ]
291
+ });
292
+ }
293
+ return scenarios;
294
+ }
295
+ generateFlowTestScenarios(flow, requirements) {
296
+ const scenarios = [];
297
+ // Basic flow execution
298
+ scenarios.push({
299
+ name: 'Flow Basic Execution',
300
+ type: 'positive',
301
+ description: 'Test that flow executes successfully with valid inputs',
302
+ inputs: {
303
+ trigger_record: {
304
+ number: 'TST0001',
305
+ short_description: 'Test Record',
306
+ priority: 2,
307
+ state: 1
308
+ }
309
+ },
310
+ assertions: [
311
+ 'Flow should trigger correctly',
312
+ 'All actions should execute in order',
313
+ 'Flow should complete without errors'
314
+ ]
315
+ });
316
+ // Approval path test
317
+ if (flow.config.metadata?.hasApprovals) {
318
+ scenarios.push({
319
+ name: 'Flow Approval Path - Approved',
320
+ type: 'positive',
321
+ description: 'Test flow behavior when approval is granted',
322
+ inputs: {
323
+ trigger_record: {
324
+ number: 'TST0002',
325
+ priority: 1
326
+ },
327
+ approval_response: 'approved',
328
+ approver: 'admin'
329
+ },
330
+ assertions: [
331
+ 'Approval request should be created',
332
+ 'Flow should continue after approval',
333
+ 'Approved actions should execute'
334
+ ]
335
+ });
336
+ if (requirements.includeNegativeTests) {
337
+ scenarios.push({
338
+ name: 'Flow Approval Path - Rejected',
339
+ type: 'negative',
340
+ description: 'Test flow behavior when approval is rejected',
341
+ inputs: {
342
+ trigger_record: {
343
+ number: 'TST0003',
344
+ priority: 1
345
+ },
346
+ approval_response: 'rejected',
347
+ approver: 'admin'
348
+ },
349
+ assertions: [
350
+ 'Approval request should be created',
351
+ 'Flow should handle rejection gracefully',
352
+ 'Rejection path should execute',
353
+ 'Notification should be sent'
354
+ ]
355
+ });
356
+ }
357
+ }
358
+ // Error handling test
359
+ scenarios.push({
360
+ name: 'Flow Error Handling',
361
+ type: 'negative',
362
+ description: 'Test flow error handling capabilities',
363
+ inputs: {
364
+ trigger_record: {
365
+ number: 'TST0004',
366
+ force_error: true
367
+ }
368
+ },
369
+ assertions: [
370
+ 'Flow should catch errors',
371
+ 'Error handler should execute',
372
+ 'Flow should not leave data in inconsistent state'
373
+ ]
374
+ });
375
+ // Performance test
376
+ if (requirements.includePerformanceTests) {
377
+ scenarios.push({
378
+ name: 'Flow Performance Under Load',
379
+ type: 'performance',
380
+ description: 'Test flow performance with multiple simultaneous executions',
381
+ inputs: {
382
+ concurrent_executions: 10,
383
+ trigger_records: Array(10).fill(null).map((_, i) => ({
384
+ number: `PERF${i.toString().padStart(4, '0')}`,
385
+ priority: (i % 3) + 1
386
+ }))
387
+ },
388
+ assertions: [
389
+ 'All flows should complete within reasonable time',
390
+ 'No deadlocks should occur',
391
+ 'System resources should not be exhausted'
392
+ ]
393
+ });
394
+ }
395
+ return scenarios;
396
+ }
397
+ generateScriptTestScenarios(script, requirements) {
398
+ const scenarios = [];
399
+ const scriptType = script.config.type || 'business_rule';
400
+ // Basic execution test
401
+ scenarios.push({
402
+ name: 'Script Basic Execution',
403
+ type: 'positive',
404
+ description: 'Test that script executes without errors',
405
+ inputs: {
406
+ current: {
407
+ sys_id: 'test123',
408
+ number: 'TST0001',
409
+ short_description: 'Test Record'
410
+ },
411
+ previous: null
412
+ },
413
+ assertions: [
414
+ 'Script should execute without throwing errors',
415
+ 'Expected fields should be set',
416
+ 'No infinite loops should occur'
417
+ ]
418
+ });
419
+ // Field validation test (for business rules)
420
+ if (scriptType === 'business_rule') {
421
+ scenarios.push({
422
+ name: 'Business Rule Field Validation',
423
+ type: 'positive',
424
+ description: 'Test that business rule validates fields correctly',
425
+ inputs: {
426
+ current: {
427
+ short_description: '',
428
+ priority: 1
429
+ }
430
+ },
431
+ expectedOutput: {
432
+ abort_action: true,
433
+ error_messages: ['Short description is required']
434
+ },
435
+ assertions: [
436
+ 'Validation should trigger for empty required fields',
437
+ 'Appropriate error messages should be set',
438
+ 'Record save should be prevented'
439
+ ]
440
+ });
441
+ }
442
+ // Script include method test
443
+ if (scriptType === 'script_include') {
444
+ scenarios.push({
445
+ name: 'Script Include Method Test',
446
+ type: 'positive',
447
+ description: 'Test script include methods work correctly',
448
+ inputs: {
449
+ method: 'processRecords',
450
+ params: {
451
+ tableName: 'incident',
452
+ query: 'active=true^priority=1',
453
+ callback: 'function(gr) { return gr.number; }'
454
+ }
455
+ },
456
+ assertions: [
457
+ 'Method should be callable',
458
+ 'Return value should match expected format',
459
+ 'No memory leaks should occur'
460
+ ]
461
+ });
462
+ }
463
+ // Edge case test
464
+ scenarios.push({
465
+ name: 'Script Edge Case - Null Values',
466
+ type: 'edge_case',
467
+ description: 'Test script handling of null/undefined values',
468
+ inputs: {
469
+ current: {
470
+ sys_id: 'test123',
471
+ short_description: null,
472
+ assigned_to: undefined
473
+ }
474
+ },
475
+ assertions: [
476
+ 'Script should handle null values gracefully',
477
+ 'No null pointer exceptions should occur',
478
+ 'Default values should be applied where appropriate'
479
+ ]
480
+ });
481
+ return scenarios;
482
+ }
483
+ async generateMockData(scenarios, artifacts) {
484
+ const mockData = {
485
+ users: [
486
+ { sys_id: 'user1', user_name: 'test.user', name: 'Test User', email: 'test@example.com' },
487
+ { sys_id: 'user2', user_name: 'admin', name: 'Admin User', email: 'admin@example.com' }
488
+ ],
489
+ groups: [
490
+ { sys_id: 'group1', name: 'Service Desk', manager: 'user2' },
491
+ { sys_id: 'group2', name: 'IT Support', manager: 'user1' }
492
+ ],
493
+ catalog_items: [
494
+ { sys_id: 'cat1', name: 'Laptop Request', category: 'Hardware' },
495
+ { sys_id: 'cat2', name: 'Software Installation', category: 'Software' }
496
+ ]
497
+ };
498
+ // Generate specific mock data based on artifact types
499
+ for (const artifact of artifacts) {
500
+ if (artifact.type === 'widget' && artifact.config.dataSource) {
501
+ mockData[artifact.config.dataSource] = this.generateTableMockData(artifact.config.dataSource);
502
+ }
503
+ }
504
+ return mockData;
505
+ }
506
+ generateTableMockData(tableName) {
507
+ const baseRecord = {
508
+ sys_id: '',
509
+ sys_created_on: new Date().toISOString(),
510
+ sys_updated_on: new Date().toISOString(),
511
+ sys_created_by: 'test.user',
512
+ sys_updated_by: 'test.user'
513
+ };
514
+ switch (tableName) {
515
+ case 'incident':
516
+ return Array(5).fill(null).map((_, i) => ({
517
+ ...baseRecord,
518
+ sys_id: `inc${i}`,
519
+ number: `INC000100${i}`,
520
+ short_description: `Test Incident ${i}`,
521
+ description: `This is a test incident for automated testing`,
522
+ priority: (i % 3) + 1,
523
+ state: i % 4 + 1,
524
+ assigned_to: i % 2 === 0 ? 'user1' : 'user2',
525
+ assignment_group: i % 2 === 0 ? 'group1' : 'group2'
526
+ }));
527
+ case 'sc_request':
528
+ return Array(3).fill(null).map((_, i) => ({
529
+ ...baseRecord,
530
+ sys_id: `req${i}`,
531
+ number: `REQ000100${i}`,
532
+ short_description: `Test Request ${i}`,
533
+ requested_for: 'user1',
534
+ state: 'pending_approval',
535
+ cat_item: `cat${i % 2 + 1}`
536
+ }));
537
+ default:
538
+ return Array(3).fill(null).map((_, i) => ({
539
+ ...baseRecord,
540
+ sys_id: `rec${i}`,
541
+ number: `REC000100${i}`,
542
+ short_description: `Test Record ${i}`
543
+ }));
544
+ }
545
+ }
546
+ async executeTestScenario(scenario, artifact, mockData) {
547
+ const startTime = Date.now();
548
+ const result = {
549
+ scenario: scenario.name,
550
+ passed: true,
551
+ executionTime: 0,
552
+ assertions: []
553
+ };
554
+ try {
555
+ // Execute test based on artifact type
556
+ let testOutput;
557
+ switch (artifact.type) {
558
+ case 'widget':
559
+ testOutput = await this.executeWidgetTest(scenario, artifact, mockData);
560
+ break;
561
+ case 'flow':
562
+ testOutput = await this.executeFlowTest(scenario, artifact, mockData);
563
+ break;
564
+ case 'script':
565
+ testOutput = await this.executeScriptTest(scenario, artifact, mockData);
566
+ break;
567
+ }
568
+ result.actualOutput = testOutput;
569
+ // Evaluate assertions
570
+ for (const assertion of scenario.assertions) {
571
+ const assertionResult = await this.evaluateAssertion(assertion, testOutput, scenario);
572
+ result.assertions.push(assertionResult);
573
+ if (!assertionResult.passed) {
574
+ result.passed = false;
575
+ }
576
+ }
577
+ }
578
+ catch (error) {
579
+ result.passed = false;
580
+ result.error = error.message;
581
+ result.assertions.push({
582
+ assertion: 'Test execution',
583
+ passed: false,
584
+ message: `Test failed with error: ${error.message}`
585
+ });
586
+ }
587
+ result.executionTime = Date.now() - startTime;
588
+ return result;
589
+ }
590
+ async executeWidgetTest(scenario, widget, mockData) {
591
+ // This would use snow_widget_test MCP tool
592
+ // For now, simulate test execution
593
+ return {
594
+ renderSuccess: true,
595
+ loadTime: 250,
596
+ errors: [],
597
+ dataDisplayed: scenario.inputs.server_data?.rows?.length || 0,
598
+ responsive: true
599
+ };
600
+ }
601
+ async executeFlowTest(scenario, flow, mockData) {
602
+ // This would use snow_test_flow_with_mock MCP tool
603
+ // For now, simulate test execution
604
+ return {
605
+ executionId: `flow_test_${Date.now()}`,
606
+ status: 'completed',
607
+ duration: 1500,
608
+ stagesExecuted: ['Start', 'Validate', 'Process', 'End'],
609
+ errors: [],
610
+ outputs: {
611
+ success: true,
612
+ recordUpdated: true
613
+ }
614
+ };
615
+ }
616
+ async executeScriptTest(scenario, script, mockData) {
617
+ // Simulate script test execution
618
+ return {
619
+ executionSuccess: true,
620
+ errors: [],
621
+ fieldsModified: ['work_notes', 'state'],
622
+ validationsPassed: true,
623
+ performanceMetrics: {
624
+ executionTime: 50,
625
+ memoryUsed: 1024
626
+ }
627
+ };
628
+ }
629
+ async evaluateAssertion(assertion, actualOutput, scenario) {
630
+ // Simple assertion evaluation logic
631
+ // In a real implementation, this would be more sophisticated
632
+ const assertionResult = {
633
+ assertion,
634
+ passed: true,
635
+ message: 'Assertion passed'
636
+ };
637
+ // Check for specific assertion patterns
638
+ if (assertion.includes('without errors') && actualOutput.errors?.length > 0) {
639
+ assertionResult.passed = false;
640
+ assertionResult.message = `Found ${actualOutput.errors.length} errors`;
641
+ }
642
+ if (assertion.includes('should be displayed') && actualOutput.dataDisplayed === 0) {
643
+ assertionResult.passed = false;
644
+ assertionResult.message = 'No data was displayed';
645
+ }
646
+ if (assertion.includes('within') && assertion.includes('seconds')) {
647
+ const timeMatch = assertion.match(/within (\d+) seconds/);
648
+ if (timeMatch) {
649
+ const maxTime = parseInt(timeMatch[1]) * 1000;
650
+ if (actualOutput.executionTime > maxTime || actualOutput.loadTime > maxTime) {
651
+ assertionResult.passed = false;
652
+ assertionResult.message = `Execution took longer than ${maxTime}ms`;
653
+ }
654
+ }
655
+ }
656
+ return assertionResult;
657
+ }
658
+ async analyzeTestResults(results) {
659
+ const analysis = {
660
+ totalTests: results.length,
661
+ passedCount: results.filter(r => r.passed).length,
662
+ failedCount: results.filter(r => !r.passed).length,
663
+ allPassed: results.every(r => r.passed),
664
+ averageExecutionTime: results.reduce((sum, r) => sum + r.executionTime, 0) / results.length,
665
+ coverage: 0,
666
+ failedTests: results.filter(r => !r.passed).map(r => ({
667
+ name: r.scenario,
668
+ error: r.error,
669
+ failedAssertions: r.assertions.filter(a => !a.passed)
670
+ })),
671
+ performanceIssues: results.filter(r => r.executionTime > 5000).map(r => r.scenario)
672
+ };
673
+ // Calculate coverage based on test types
674
+ const testTypes = new Set(results.map(r => r.scenario.split(' ')[1]));
675
+ analysis.coverage = (testTypes.size / 5) * 100; // Assume 5 main test categories
676
+ return analysis;
677
+ }
678
+ async cleanupTestArtifacts() {
679
+ // This would use snow_cleanup_test_artifacts MCP tool
680
+ // Clean up any test data created during testing
681
+ await this.logActivity('cleanup_test_artifacts', true, {
682
+ timestamp: new Date()
683
+ });
684
+ }
685
+ generateTestReport(results, analysis) {
686
+ let report = '# Test Execution Report\n\n';
687
+ report += `**Date**: ${new Date().toISOString()}\n`;
688
+ report += `**Total Tests**: ${analysis.totalTests}\n`;
689
+ report += `**Passed**: ${analysis.passedCount}\n`;
690
+ report += `**Failed**: ${analysis.failedCount}\n`;
691
+ report += `**Coverage**: ${analysis.coverage.toFixed(1)}%\n`;
692
+ report += `**Average Execution Time**: ${analysis.averageExecutionTime.toFixed(0)}ms\n\n`;
693
+ report += '## Test Results\n\n';
694
+ for (const result of results) {
695
+ const icon = result.passed ? '✅' : '❌';
696
+ report += `### ${icon} ${result.scenario}\n`;
697
+ report += `- **Status**: ${result.passed ? 'PASSED' : 'FAILED'}\n`;
698
+ report += `- **Execution Time**: ${result.executionTime}ms\n`;
699
+ if (result.error) {
700
+ report += `- **Error**: ${result.error}\n`;
701
+ }
702
+ report += `- **Assertions**:\n`;
703
+ for (const assertion of result.assertions) {
704
+ const assertionIcon = assertion.passed ? '✓' : '✗';
705
+ report += ` - ${assertionIcon} ${assertion.assertion}\n`;
706
+ if (!assertion.passed && assertion.message) {
707
+ report += ` - ${assertion.message}\n`;
708
+ }
709
+ }
710
+ report += '\n';
711
+ }
712
+ if (analysis.failedCount > 0) {
713
+ report += '## Failed Tests Summary\n\n';
714
+ for (const failed of analysis.failedTests) {
715
+ report += `- **${failed.name}**\n`;
716
+ if (failed.error) {
717
+ report += ` - Error: ${failed.error}\n`;
718
+ }
719
+ for (const assertion of failed.failedAssertions) {
720
+ report += ` - Failed: ${assertion.assertion}\n`;
721
+ }
722
+ }
723
+ }
724
+ if (analysis.performanceIssues.length > 0) {
725
+ report += '\n## Performance Issues\n\n';
726
+ report += 'The following tests took longer than 5 seconds:\n';
727
+ for (const test of analysis.performanceIssues) {
728
+ report += `- ${test}\n`;
729
+ }
730
+ }
731
+ return report;
732
+ }
733
+ }
734
+ exports.TestAgent = TestAgent;
735
+ //# sourceMappingURL=test-agent.js.map