erosolar-cli 2.1.248 → 2.1.252

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 (470) hide show
  1. package/agents/general.rules.json +10 -133
  2. package/agents/general.rules.json.bak +278 -0
  3. package/agents/general.rules.json.bak2 +306 -0
  4. package/dist/bin/erosolar.js +9 -5
  5. package/dist/bin/erosolar.js.map +1 -1
  6. package/dist/capabilities/bidirectionalAuditCapability.d.ts +26 -0
  7. package/dist/capabilities/bidirectionalAuditCapability.d.ts.map +1 -0
  8. package/dist/capabilities/bidirectionalAuditCapability.js +44 -0
  9. package/dist/capabilities/bidirectionalAuditCapability.js.map +1 -0
  10. package/dist/capabilities/globCapability.d.ts +3 -6
  11. package/dist/capabilities/globCapability.d.ts.map +1 -1
  12. package/dist/capabilities/globCapability.js +6 -10
  13. package/dist/capabilities/globCapability.js.map +1 -1
  14. package/dist/capabilities/index.d.ts +1 -18
  15. package/dist/capabilities/index.d.ts.map +1 -1
  16. package/dist/capabilities/index.js +1 -18
  17. package/dist/capabilities/index.js.map +1 -1
  18. package/dist/capabilities/orchestrationCapability.d.ts +177 -3
  19. package/dist/capabilities/orchestrationCapability.d.ts.map +1 -1
  20. package/dist/capabilities/orchestrationCapability.js +1592 -85
  21. package/dist/capabilities/orchestrationCapability.js.map +1 -1
  22. package/dist/capabilities/searchCapability.d.ts +8 -2
  23. package/dist/capabilities/searchCapability.d.ts.map +1 -1
  24. package/dist/capabilities/searchCapability.js +11 -6
  25. package/dist/capabilities/searchCapability.js.map +1 -1
  26. package/dist/contracts/tools.schema.json +9 -133
  27. package/dist/core/agentOrchestrator.d.ts.map +1 -1
  28. package/dist/core/agentOrchestrator.js +18 -1
  29. package/dist/core/agentOrchestrator.js.map +1 -1
  30. package/dist/core/aiErrorFixer.d.ts +1 -14
  31. package/dist/core/aiErrorFixer.d.ts.map +1 -1
  32. package/dist/core/aiErrorFixer.js +51 -239
  33. package/dist/core/aiErrorFixer.js.map +1 -1
  34. package/dist/core/alphaZeroEngine.d.ts +16 -256
  35. package/dist/core/alphaZeroEngine.d.ts.map +1 -1
  36. package/dist/core/alphaZeroEngine.js +22 -513
  37. package/dist/core/alphaZeroEngine.js.map +1 -1
  38. package/dist/core/completeAttackOrchestrator.d.ts +102 -0
  39. package/dist/core/completeAttackOrchestrator.d.ts.map +1 -0
  40. package/dist/core/completeAttackOrchestrator.js +293 -0
  41. package/dist/core/completeAttackOrchestrator.js.map +1 -0
  42. package/dist/core/defensiveSecurityToolkit.d.ts +373 -0
  43. package/dist/core/defensiveSecurityToolkit.d.ts.map +1 -0
  44. package/dist/core/defensiveSecurityToolkit.js +1304 -0
  45. package/dist/core/defensiveSecurityToolkit.js.map +1 -0
  46. package/dist/core/errors/errorTypes.d.ts +30 -57
  47. package/dist/core/errors/errorTypes.d.ts.map +1 -1
  48. package/dist/core/errors/errorTypes.js +51 -228
  49. package/dist/core/errors/errorTypes.js.map +1 -1
  50. package/dist/core/errors/safetyValidator.d.ts +19 -3
  51. package/dist/core/errors/safetyValidator.d.ts.map +1 -1
  52. package/dist/core/errors/safetyValidator.js +33 -71
  53. package/dist/core/errors/safetyValidator.js.map +1 -1
  54. package/dist/core/failureRecovery.d.ts +4 -100
  55. package/dist/core/failureRecovery.d.ts.map +1 -1
  56. package/dist/core/failureRecovery.js +16 -440
  57. package/dist/core/failureRecovery.js.map +1 -1
  58. package/dist/core/intelligentTargetResearcher.d.ts +142 -0
  59. package/dist/core/intelligentTargetResearcher.d.ts.map +1 -0
  60. package/dist/core/intelligentTargetResearcher.js +367 -0
  61. package/dist/core/intelligentTargetResearcher.js.map +1 -0
  62. package/dist/core/intelligentTestFlows.d.ts +26 -107
  63. package/dist/core/intelligentTestFlows.d.ts.map +1 -1
  64. package/dist/core/intelligentTestFlows.js +15 -659
  65. package/dist/core/intelligentTestFlows.js.map +1 -1
  66. package/dist/core/learningPersistence.d.ts +45 -132
  67. package/dist/core/learningPersistence.d.ts.map +1 -1
  68. package/dist/core/learningPersistence.js +32 -463
  69. package/dist/core/learningPersistence.js.map +1 -1
  70. package/dist/core/metricsTracker.d.ts +22 -139
  71. package/dist/core/metricsTracker.d.ts.map +1 -1
  72. package/dist/core/metricsTracker.js +51 -241
  73. package/dist/core/metricsTracker.js.map +1 -1
  74. package/dist/core/performanceMonitor.d.ts +15 -109
  75. package/dist/core/performanceMonitor.d.ts.map +1 -1
  76. package/dist/core/performanceMonitor.js +27 -184
  77. package/dist/core/performanceMonitor.js.map +1 -1
  78. package/dist/core/resultVerification.d.ts +6 -100
  79. package/dist/core/resultVerification.d.ts.map +1 -1
  80. package/dist/core/resultVerification.js +31 -400
  81. package/dist/core/resultVerification.js.map +1 -1
  82. package/dist/core/selfEvolution.d.ts +32 -126
  83. package/dist/core/selfEvolution.d.ts.map +1 -1
  84. package/dist/core/selfEvolution.js +24 -967
  85. package/dist/core/selfEvolution.js.map +1 -1
  86. package/dist/core/selfImprovement.d.ts +50 -109
  87. package/dist/core/selfImprovement.d.ts.map +1 -1
  88. package/dist/core/selfImprovement.js +14 -689
  89. package/dist/core/selfImprovement.js.map +1 -1
  90. package/dist/core/sourceCodeManager.d.ts +89 -0
  91. package/dist/core/sourceCodeManager.d.ts.map +1 -0
  92. package/dist/core/sourceCodeManager.js +332 -0
  93. package/dist/core/sourceCodeManager.js.map +1 -0
  94. package/dist/core/unifiedOrchestrator.d.ts +88 -0
  95. package/dist/core/unifiedOrchestrator.d.ts.map +1 -0
  96. package/dist/core/unifiedOrchestrator.js +284 -0
  97. package/dist/core/unifiedOrchestrator.js.map +1 -0
  98. package/dist/core/userDefenseOrchestrator.d.ts +202 -0
  99. package/dist/core/userDefenseOrchestrator.d.ts.map +1 -0
  100. package/dist/core/userDefenseOrchestrator.js +1006 -0
  101. package/dist/core/userDefenseOrchestrator.js.map +1 -0
  102. package/dist/plugins/index.d.ts +1 -1
  103. package/dist/plugins/index.d.ts.map +1 -1
  104. package/dist/plugins/index.js +36 -26
  105. package/dist/plugins/index.js.map +1 -1
  106. package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.d.ts +8 -0
  107. package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.d.ts.map +1 -0
  108. package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.js +17 -0
  109. package/dist/plugins/tools/bidirectionalAudit/bidirectionalAuditPlugin.js.map +1 -0
  110. package/dist/plugins/tools/nodeDefaults.d.ts +14 -0
  111. package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
  112. package/dist/plugins/tools/nodeDefaults.js +17 -54
  113. package/dist/plugins/tools/nodeDefaults.js.map +1 -1
  114. package/dist/plugins/tools/orchestration/orchestrationPlugin.d.ts +9 -0
  115. package/dist/plugins/tools/orchestration/orchestrationPlugin.d.ts.map +1 -0
  116. package/dist/plugins/tools/orchestration/orchestrationPlugin.js +18 -0
  117. package/dist/plugins/tools/orchestration/orchestrationPlugin.js.map +1 -0
  118. package/dist/shell/interactiveShell.d.ts +101 -2
  119. package/dist/shell/interactiveShell.d.ts.map +1 -1
  120. package/dist/shell/interactiveShell.js +1041 -25
  121. package/dist/shell/interactiveShell.js.map +1 -1
  122. package/dist/tools/appleExposureTools.d.ts +108 -0
  123. package/dist/tools/appleExposureTools.d.ts.map +1 -0
  124. package/dist/tools/appleExposureTools.js +850 -0
  125. package/dist/tools/appleExposureTools.js.map +1 -0
  126. package/dist/tools/bidirectionalAuditTools.d.ts +104 -0
  127. package/dist/tools/bidirectionalAuditTools.d.ts.map +1 -0
  128. package/dist/tools/bidirectionalAuditTools.js +1280 -0
  129. package/dist/tools/bidirectionalAuditTools.js.map +1 -0
  130. package/dist/tools/defensiveSecurityTools.d.ts +152 -0
  131. package/dist/tools/defensiveSecurityTools.d.ts.map +1 -0
  132. package/dist/tools/defensiveSecurityTools.js +576 -0
  133. package/dist/tools/defensiveSecurityTools.js.map +1 -0
  134. package/dist/tools/forwardAttackChainTracer.d.ts +73 -0
  135. package/dist/tools/forwardAttackChainTracer.d.ts.map +1 -0
  136. package/dist/tools/forwardAttackChainTracer.js +604 -0
  137. package/dist/tools/forwardAttackChainTracer.js.map +1 -0
  138. package/dist/tools/localExplore.d.ts +12 -199
  139. package/dist/tools/localExplore.d.ts.map +1 -1
  140. package/dist/tools/localExplore.js +18 -1352
  141. package/dist/tools/localExplore.js.map +1 -1
  142. package/dist/tools/offensiveTransparencyTools.d.ts +188 -0
  143. package/dist/tools/offensiveTransparencyTools.d.ts.map +1 -0
  144. package/dist/tools/offensiveTransparencyTools.js +890 -0
  145. package/dist/tools/offensiveTransparencyTools.js.map +1 -0
  146. package/dist/tools/planningTools.d.ts +8 -17
  147. package/dist/tools/planningTools.d.ts.map +1 -1
  148. package/dist/tools/planningTools.js +31 -141
  149. package/dist/tools/planningTools.js.map +1 -1
  150. package/dist/tools/searchTools.d.ts +9 -0
  151. package/dist/tools/searchTools.d.ts.map +1 -1
  152. package/dist/tools/searchTools.js +305 -189
  153. package/dist/tools/searchTools.js.map +1 -1
  154. package/dist/tools/skillTools.d.ts +7 -5
  155. package/dist/tools/skillTools.d.ts.map +1 -1
  156. package/dist/tools/skillTools.js +13 -155
  157. package/dist/tools/skillTools.js.map +1 -1
  158. package/dist/tools/threatIntelligenceTools.d.ts +128 -0
  159. package/dist/tools/threatIntelligenceTools.d.ts.map +1 -0
  160. package/dist/tools/threatIntelligenceTools.js +712 -0
  161. package/dist/tools/threatIntelligenceTools.js.map +1 -0
  162. package/dist/ui/PromptController.d.ts +4 -0
  163. package/dist/ui/PromptController.d.ts.map +1 -1
  164. package/dist/ui/PromptController.js +32 -11
  165. package/dist/ui/PromptController.js.map +1 -1
  166. package/dist/ui/UnifiedUIRenderer.d.ts +36 -0
  167. package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
  168. package/dist/ui/UnifiedUIRenderer.js +308 -43
  169. package/dist/ui/UnifiedUIRenderer.js.map +1 -1
  170. package/dist/ui/animatedStatus.d.ts +2 -0
  171. package/dist/ui/animatedStatus.d.ts.map +1 -1
  172. package/dist/ui/animatedStatus.js +36 -2
  173. package/dist/ui/animatedStatus.js.map +1 -1
  174. package/dist/ui/orchestration/StatusOrchestrator.d.ts +10 -0
  175. package/dist/ui/orchestration/StatusOrchestrator.d.ts.map +1 -1
  176. package/dist/ui/orchestration/StatusOrchestrator.js +36 -4
  177. package/dist/ui/orchestration/StatusOrchestrator.js.map +1 -1
  178. package/package.json +2 -2
  179. package/dist/capabilities/advancedTestGenerationCapability.d.ts +0 -17
  180. package/dist/capabilities/advancedTestGenerationCapability.d.ts.map +0 -1
  181. package/dist/capabilities/advancedTestGenerationCapability.js +0 -28
  182. package/dist/capabilities/advancedTestGenerationCapability.js.map +0 -1
  183. package/dist/capabilities/browserAutomationCapability.d.ts +0 -37
  184. package/dist/capabilities/browserAutomationCapability.d.ts.map +0 -1
  185. package/dist/capabilities/browserAutomationCapability.js +0 -49
  186. package/dist/capabilities/browserAutomationCapability.js.map +0 -1
  187. package/dist/capabilities/buildCapability.d.ts +0 -24
  188. package/dist/capabilities/buildCapability.d.ts.map +0 -1
  189. package/dist/capabilities/buildCapability.js +0 -25
  190. package/dist/capabilities/buildCapability.js.map +0 -1
  191. package/dist/capabilities/cloudCapability.d.ts +0 -13
  192. package/dist/capabilities/cloudCapability.d.ts.map +0 -1
  193. package/dist/capabilities/cloudCapability.js +0 -38
  194. package/dist/capabilities/cloudCapability.js.map +0 -1
  195. package/dist/capabilities/codeAnalysisCapability.d.ts +0 -13
  196. package/dist/capabilities/codeAnalysisCapability.d.ts.map +0 -1
  197. package/dist/capabilities/codeAnalysisCapability.js +0 -24
  198. package/dist/capabilities/codeAnalysisCapability.js.map +0 -1
  199. package/dist/capabilities/codeQualityCapability.d.ts +0 -13
  200. package/dist/capabilities/codeQualityCapability.d.ts.map +0 -1
  201. package/dist/capabilities/codeQualityCapability.js +0 -25
  202. package/dist/capabilities/codeQualityCapability.js.map +0 -1
  203. package/dist/capabilities/dependencySecurityCapability.d.ts +0 -13
  204. package/dist/capabilities/dependencySecurityCapability.d.ts.map +0 -1
  205. package/dist/capabilities/dependencySecurityCapability.js +0 -24
  206. package/dist/capabilities/dependencySecurityCapability.js.map +0 -1
  207. package/dist/capabilities/devCapability.d.ts +0 -13
  208. package/dist/capabilities/devCapability.d.ts.map +0 -1
  209. package/dist/capabilities/devCapability.js +0 -24
  210. package/dist/capabilities/devCapability.js.map +0 -1
  211. package/dist/capabilities/emailCapability.d.ts +0 -12
  212. package/dist/capabilities/emailCapability.d.ts.map +0 -1
  213. package/dist/capabilities/emailCapability.js +0 -22
  214. package/dist/capabilities/emailCapability.js.map +0 -1
  215. package/dist/capabilities/enhancedAnalysisCapability.d.ts +0 -13
  216. package/dist/capabilities/enhancedAnalysisCapability.d.ts.map +0 -1
  217. package/dist/capabilities/enhancedAnalysisCapability.js +0 -20
  218. package/dist/capabilities/enhancedAnalysisCapability.js.map +0 -1
  219. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts +0 -17
  220. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts.map +0 -1
  221. package/dist/capabilities/enhancedCodeIntelligenceCapability.js +0 -28
  222. package/dist/capabilities/enhancedCodeIntelligenceCapability.js.map +0 -1
  223. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts +0 -17
  224. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts.map +0 -1
  225. package/dist/capabilities/enhancedDevWorkflowCapability.js +0 -28
  226. package/dist/capabilities/enhancedDevWorkflowCapability.js.map +0 -1
  227. package/dist/capabilities/frontendTestingCapability.d.ts +0 -13
  228. package/dist/capabilities/frontendTestingCapability.d.ts.map +0 -1
  229. package/dist/capabilities/frontendTestingCapability.js +0 -28
  230. package/dist/capabilities/frontendTestingCapability.js.map +0 -1
  231. package/dist/capabilities/interactionCapability.d.ts +0 -12
  232. package/dist/capabilities/interactionCapability.d.ts.map +0 -1
  233. package/dist/capabilities/interactionCapability.js +0 -22
  234. package/dist/capabilities/interactionCapability.js.map +0 -1
  235. package/dist/capabilities/learnCapability.d.ts +0 -22
  236. package/dist/capabilities/learnCapability.d.ts.map +0 -1
  237. package/dist/capabilities/learnCapability.js +0 -37
  238. package/dist/capabilities/learnCapability.js.map +0 -1
  239. package/dist/capabilities/notebookCapability.d.ts +0 -17
  240. package/dist/capabilities/notebookCapability.d.ts.map +0 -1
  241. package/dist/capabilities/notebookCapability.js +0 -27
  242. package/dist/capabilities/notebookCapability.js.map +0 -1
  243. package/dist/capabilities/planningCapability.d.ts +0 -16
  244. package/dist/capabilities/planningCapability.d.ts.map +0 -1
  245. package/dist/capabilities/planningCapability.js +0 -26
  246. package/dist/capabilities/planningCapability.js.map +0 -1
  247. package/dist/capabilities/refactoringCapability.d.ts +0 -13
  248. package/dist/capabilities/refactoringCapability.d.ts.map +0 -1
  249. package/dist/capabilities/refactoringCapability.js +0 -25
  250. package/dist/capabilities/refactoringCapability.js.map +0 -1
  251. package/dist/capabilities/repoChecksCapability.d.ts +0 -10
  252. package/dist/capabilities/repoChecksCapability.d.ts.map +0 -1
  253. package/dist/capabilities/repoChecksCapability.js +0 -24
  254. package/dist/capabilities/repoChecksCapability.js.map +0 -1
  255. package/dist/capabilities/taskManagementCapability.d.ts +0 -12
  256. package/dist/capabilities/taskManagementCapability.d.ts.map +0 -1
  257. package/dist/capabilities/taskManagementCapability.js +0 -22
  258. package/dist/capabilities/taskManagementCapability.js.map +0 -1
  259. package/dist/capabilities/testingCapability.d.ts +0 -13
  260. package/dist/capabilities/testingCapability.d.ts.map +0 -1
  261. package/dist/capabilities/testingCapability.js +0 -25
  262. package/dist/capabilities/testingCapability.js.map +0 -1
  263. package/dist/capabilities/validationCapability.d.ts +0 -13
  264. package/dist/capabilities/validationCapability.d.ts.map +0 -1
  265. package/dist/capabilities/validationCapability.js +0 -24
  266. package/dist/capabilities/validationCapability.js.map +0 -1
  267. package/dist/capabilities/webCapability.d.ts +0 -12
  268. package/dist/capabilities/webCapability.d.ts.map +0 -1
  269. package/dist/capabilities/webCapability.js +0 -22
  270. package/dist/capabilities/webCapability.js.map +0 -1
  271. package/dist/core/deepBugAnalyzer.d.ts +0 -128
  272. package/dist/core/deepBugAnalyzer.d.ts.map +0 -1
  273. package/dist/core/deepBugAnalyzer.js +0 -406
  274. package/dist/core/deepBugAnalyzer.js.map +0 -1
  275. package/dist/core/hypothesisEngine.d.ts +0 -113
  276. package/dist/core/hypothesisEngine.d.ts.map +0 -1
  277. package/dist/core/hypothesisEngine.js +0 -264
  278. package/dist/core/hypothesisEngine.js.map +0 -1
  279. package/dist/core/productTestHarness.d.ts +0 -113
  280. package/dist/core/productTestHarness.d.ts.map +0 -1
  281. package/dist/core/productTestHarness.js +0 -351
  282. package/dist/core/productTestHarness.js.map +0 -1
  283. package/dist/core/validationRunner.d.ts +0 -106
  284. package/dist/core/validationRunner.d.ts.map +0 -1
  285. package/dist/core/validationRunner.js +0 -892
  286. package/dist/core/validationRunner.js.map +0 -1
  287. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts +0 -14
  288. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts.map +0 -1
  289. package/dist/plugins/tools/browser/browserAutomationPlugin.js +0 -26
  290. package/dist/plugins/tools/browser/browserAutomationPlugin.js.map +0 -1
  291. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts +0 -3
  292. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts.map +0 -1
  293. package/dist/plugins/tools/checks/localRepoChecksPlugin.js +0 -14
  294. package/dist/plugins/tools/checks/localRepoChecksPlugin.js.map +0 -1
  295. package/dist/plugins/tools/cloud/cloudPlugin.d.ts +0 -3
  296. package/dist/plugins/tools/cloud/cloudPlugin.d.ts.map +0 -1
  297. package/dist/plugins/tools/cloud/cloudPlugin.js +0 -14
  298. package/dist/plugins/tools/cloud/cloudPlugin.js.map +0 -1
  299. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts +0 -3
  300. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts.map +0 -1
  301. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js +0 -14
  302. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js.map +0 -1
  303. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts +0 -3
  304. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts.map +0 -1
  305. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js +0 -14
  306. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js.map +0 -1
  307. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts +0 -3
  308. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts.map +0 -1
  309. package/dist/plugins/tools/dependency/dependencyPlugin.js +0 -12
  310. package/dist/plugins/tools/dependency/dependencyPlugin.js.map +0 -1
  311. package/dist/plugins/tools/development/devPlugin.d.ts +0 -3
  312. package/dist/plugins/tools/development/devPlugin.d.ts.map +0 -1
  313. package/dist/plugins/tools/development/devPlugin.js +0 -14
  314. package/dist/plugins/tools/development/devPlugin.js.map +0 -1
  315. package/dist/plugins/tools/email/emailPlugin.d.ts +0 -3
  316. package/dist/plugins/tools/email/emailPlugin.d.ts.map +0 -1
  317. package/dist/plugins/tools/email/emailPlugin.js +0 -12
  318. package/dist/plugins/tools/email/emailPlugin.js.map +0 -1
  319. package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.d.ts +0 -3
  320. package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.d.ts.map +0 -1
  321. package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.js +0 -14
  322. package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.js.map +0 -1
  323. package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.d.ts +0 -3
  324. package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.d.ts.map +0 -1
  325. package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.js +0 -12
  326. package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.js.map +0 -1
  327. package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.d.ts +0 -3
  328. package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.d.ts.map +0 -1
  329. package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.js +0 -12
  330. package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.js.map +0 -1
  331. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts +0 -3
  332. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts.map +0 -1
  333. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js +0 -14
  334. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js.map +0 -1
  335. package/dist/plugins/tools/interaction/interactionPlugin.d.ts +0 -3
  336. package/dist/plugins/tools/interaction/interactionPlugin.d.ts.map +0 -1
  337. package/dist/plugins/tools/interaction/interactionPlugin.js +0 -12
  338. package/dist/plugins/tools/interaction/interactionPlugin.js.map +0 -1
  339. package/dist/plugins/tools/learn/learnPlugin.d.ts +0 -3
  340. package/dist/plugins/tools/learn/learnPlugin.d.ts.map +0 -1
  341. package/dist/plugins/tools/learn/learnPlugin.js +0 -14
  342. package/dist/plugins/tools/learn/learnPlugin.js.map +0 -1
  343. package/dist/plugins/tools/notebook/notebookPlugin.d.ts +0 -9
  344. package/dist/plugins/tools/notebook/notebookPlugin.d.ts.map +0 -1
  345. package/dist/plugins/tools/notebook/notebookPlugin.js +0 -15
  346. package/dist/plugins/tools/notebook/notebookPlugin.js.map +0 -1
  347. package/dist/plugins/tools/planning/planningPlugin.d.ts +0 -9
  348. package/dist/plugins/tools/planning/planningPlugin.d.ts.map +0 -1
  349. package/dist/plugins/tools/planning/planningPlugin.js +0 -15
  350. package/dist/plugins/tools/planning/planningPlugin.js.map +0 -1
  351. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts +0 -3
  352. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts.map +0 -1
  353. package/dist/plugins/tools/refactoring/refactoringPlugin.js +0 -12
  354. package/dist/plugins/tools/refactoring/refactoringPlugin.js.map +0 -1
  355. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts +0 -3
  356. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts.map +0 -1
  357. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js +0 -12
  358. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js.map +0 -1
  359. package/dist/plugins/tools/testing/testingPlugin.d.ts +0 -3
  360. package/dist/plugins/tools/testing/testingPlugin.d.ts.map +0 -1
  361. package/dist/plugins/tools/testing/testingPlugin.js +0 -12
  362. package/dist/plugins/tools/testing/testingPlugin.js.map +0 -1
  363. package/dist/plugins/tools/validation/validationPlugin.d.ts +0 -3
  364. package/dist/plugins/tools/validation/validationPlugin.d.ts.map +0 -1
  365. package/dist/plugins/tools/validation/validationPlugin.js +0 -14
  366. package/dist/plugins/tools/validation/validationPlugin.js.map +0 -1
  367. package/dist/plugins/tools/web/webPlugin.d.ts +0 -3
  368. package/dist/plugins/tools/web/webPlugin.d.ts.map +0 -1
  369. package/dist/plugins/tools/web/webPlugin.js +0 -12
  370. package/dist/plugins/tools/web/webPlugin.js.map +0 -1
  371. package/dist/tools/advancedTestGenerationTools.d.ts +0 -21
  372. package/dist/tools/advancedTestGenerationTools.d.ts.map +0 -1
  373. package/dist/tools/advancedTestGenerationTools.js +0 -304
  374. package/dist/tools/advancedTestGenerationTools.js.map +0 -1
  375. package/dist/tools/browserAutomationTools.d.ts +0 -23
  376. package/dist/tools/browserAutomationTools.d.ts.map +0 -1
  377. package/dist/tools/browserAutomationTools.js +0 -916
  378. package/dist/tools/browserAutomationTools.js.map +0 -1
  379. package/dist/tools/buildTools.d.ts +0 -9
  380. package/dist/tools/buildTools.d.ts.map +0 -1
  381. package/dist/tools/buildTools.js +0 -346
  382. package/dist/tools/buildTools.js.map +0 -1
  383. package/dist/tools/cloudTools.d.ts +0 -49
  384. package/dist/tools/cloudTools.d.ts.map +0 -1
  385. package/dist/tools/cloudTools.js +0 -1258
  386. package/dist/tools/cloudTools.js.map +0 -1
  387. package/dist/tools/codeAnalysisTools.d.ts +0 -74
  388. package/dist/tools/codeAnalysisTools.d.ts.map +0 -1
  389. package/dist/tools/codeAnalysisTools.js +0 -664
  390. package/dist/tools/codeAnalysisTools.js.map +0 -1
  391. package/dist/tools/codeGenerationTools.d.ts +0 -3
  392. package/dist/tools/codeGenerationTools.d.ts.map +0 -1
  393. package/dist/tools/codeGenerationTools.js +0 -439
  394. package/dist/tools/codeGenerationTools.js.map +0 -1
  395. package/dist/tools/codeQualityTools.d.ts +0 -3
  396. package/dist/tools/codeQualityTools.d.ts.map +0 -1
  397. package/dist/tools/codeQualityTools.js +0 -297
  398. package/dist/tools/codeQualityTools.js.map +0 -1
  399. package/dist/tools/dependencyTools.d.ts +0 -3
  400. package/dist/tools/dependencyTools.d.ts.map +0 -1
  401. package/dist/tools/dependencyTools.js +0 -284
  402. package/dist/tools/dependencyTools.js.map +0 -1
  403. package/dist/tools/devTools.d.ts +0 -10
  404. package/dist/tools/devTools.d.ts.map +0 -1
  405. package/dist/tools/devTools.js +0 -2126
  406. package/dist/tools/devTools.js.map +0 -1
  407. package/dist/tools/emailTools.d.ts +0 -21
  408. package/dist/tools/emailTools.d.ts.map +0 -1
  409. package/dist/tools/emailTools.js +0 -449
  410. package/dist/tools/emailTools.js.map +0 -1
  411. package/dist/tools/enhancedAnalysisTools.d.ts +0 -9
  412. package/dist/tools/enhancedAnalysisTools.d.ts.map +0 -1
  413. package/dist/tools/enhancedAnalysisTools.js +0 -370
  414. package/dist/tools/enhancedAnalysisTools.js.map +0 -1
  415. package/dist/tools/enhancedCodeIntelligenceTools.d.ts +0 -7
  416. package/dist/tools/enhancedCodeIntelligenceTools.d.ts.map +0 -1
  417. package/dist/tools/enhancedCodeIntelligenceTools.js +0 -540
  418. package/dist/tools/enhancedCodeIntelligenceTools.js.map +0 -1
  419. package/dist/tools/enhancedDevWorkflowTools.d.ts +0 -7
  420. package/dist/tools/enhancedDevWorkflowTools.d.ts.map +0 -1
  421. package/dist/tools/enhancedDevWorkflowTools.js +0 -432
  422. package/dist/tools/enhancedDevWorkflowTools.js.map +0 -1
  423. package/dist/tools/frontendTestingTools.d.ts +0 -35
  424. package/dist/tools/frontendTestingTools.d.ts.map +0 -1
  425. package/dist/tools/frontendTestingTools.js +0 -1258
  426. package/dist/tools/frontendTestingTools.js.map +0 -1
  427. package/dist/tools/globTools.d.ts +0 -15
  428. package/dist/tools/globTools.d.ts.map +0 -1
  429. package/dist/tools/globTools.js +0 -174
  430. package/dist/tools/globTools.js.map +0 -1
  431. package/dist/tools/grepTools.d.ts +0 -19
  432. package/dist/tools/grepTools.d.ts.map +0 -1
  433. package/dist/tools/grepTools.js +0 -411
  434. package/dist/tools/grepTools.js.map +0 -1
  435. package/dist/tools/interactionTools.d.ts +0 -6
  436. package/dist/tools/interactionTools.d.ts.map +0 -1
  437. package/dist/tools/interactionTools.js +0 -209
  438. package/dist/tools/interactionTools.js.map +0 -1
  439. package/dist/tools/learnTools.d.ts +0 -164
  440. package/dist/tools/learnTools.d.ts.map +0 -1
  441. package/dist/tools/learnTools.js +0 -2098
  442. package/dist/tools/learnTools.js.map +0 -1
  443. package/dist/tools/notebookEditTools.d.ts +0 -15
  444. package/dist/tools/notebookEditTools.d.ts.map +0 -1
  445. package/dist/tools/notebookEditTools.js +0 -197
  446. package/dist/tools/notebookEditTools.js.map +0 -1
  447. package/dist/tools/refactoringTools.d.ts +0 -3
  448. package/dist/tools/refactoringTools.d.ts.map +0 -1
  449. package/dist/tools/refactoringTools.js +0 -294
  450. package/dist/tools/refactoringTools.js.map +0 -1
  451. package/dist/tools/repoChecksTools.d.ts +0 -3
  452. package/dist/tools/repoChecksTools.d.ts.map +0 -1
  453. package/dist/tools/repoChecksTools.js +0 -276
  454. package/dist/tools/repoChecksTools.js.map +0 -1
  455. package/dist/tools/taskManagementTools.d.ts +0 -10
  456. package/dist/tools/taskManagementTools.d.ts.map +0 -1
  457. package/dist/tools/taskManagementTools.js +0 -133
  458. package/dist/tools/taskManagementTools.js.map +0 -1
  459. package/dist/tools/testingTools.d.ts +0 -3
  460. package/dist/tools/testingTools.d.ts.map +0 -1
  461. package/dist/tools/testingTools.js +0 -237
  462. package/dist/tools/testingTools.js.map +0 -1
  463. package/dist/tools/validationTools.d.ts +0 -7
  464. package/dist/tools/validationTools.d.ts.map +0 -1
  465. package/dist/tools/validationTools.js +0 -344
  466. package/dist/tools/validationTools.js.map +0 -1
  467. package/dist/tools/webTools.d.ts +0 -3
  468. package/dist/tools/webTools.d.ts.map +0 -1
  469. package/dist/tools/webTools.js +0 -502
  470. package/dist/tools/webTools.js.map +0 -1
@@ -1,1258 +0,0 @@
1
- /**
2
- * Frontend Testing Tools - Comprehensive frontend testing and verification capabilities
3
- *
4
- * Provides tools for:
5
- * - E2E Testing (Cypress, Playwright, Selenium)
6
- * - Build Verification (bundle analysis, build output validation)
7
- * - Deployment Verification (URL health checks, asset verification, smoke tests)
8
- * - Accessibility Testing (axe-core, pa11y integration)
9
- * - Performance Testing (Lighthouse, Web Vitals)
10
- * - Visual Regression Testing (screenshot comparison)
11
- *
12
- * @license MIT
13
- * @author Bo Shang
14
- */
15
- import { spawn } from 'child_process';
16
- import * as fs from 'fs';
17
- import * as path from 'path';
18
- const E2E_FRAMEWORKS = {
19
- cypress: {
20
- id: 'cypress',
21
- name: 'Cypress',
22
- cliCommand: 'cypress',
23
- installCommand: 'npm install -D cypress',
24
- configFile: 'cypress.config.js',
25
- runCommand: 'npx cypress run',
26
- headlessFlag: '--headless',
27
- },
28
- playwright: {
29
- id: 'playwright',
30
- name: 'Playwright',
31
- cliCommand: 'playwright',
32
- installCommand: 'npm install -D @playwright/test && npx playwright install',
33
- configFile: 'playwright.config.ts',
34
- runCommand: 'npx playwright test',
35
- headlessFlag: '--headed=false',
36
- },
37
- puppeteer: {
38
- id: 'puppeteer',
39
- name: 'Puppeteer',
40
- cliCommand: 'puppeteer',
41
- installCommand: 'npm install -D puppeteer',
42
- configFile: 'puppeteer.config.js',
43
- runCommand: 'npx jest --config=jest-puppeteer.config.js',
44
- headlessFlag: '',
45
- },
46
- };
47
- const BUILD_CONFIGS = {
48
- react: {
49
- framework: 'React',
50
- outputDir: 'build',
51
- indexFile: 'index.html',
52
- expectedAssets: ['static/js', 'static/css'],
53
- },
54
- nextjs: {
55
- framework: 'Next.js',
56
- outputDir: '.next',
57
- indexFile: '',
58
- expectedAssets: ['static', 'server'],
59
- },
60
- angular: {
61
- framework: 'Angular',
62
- outputDir: 'dist',
63
- indexFile: 'index.html',
64
- expectedAssets: ['main.js', 'polyfills.js', 'styles.css'],
65
- },
66
- vue: {
67
- framework: 'Vue',
68
- outputDir: 'dist',
69
- indexFile: 'index.html',
70
- expectedAssets: ['js', 'css'],
71
- },
72
- svelte: {
73
- framework: 'Svelte',
74
- outputDir: 'build',
75
- indexFile: 'index.html',
76
- expectedAssets: ['_app'],
77
- },
78
- vite: {
79
- framework: 'Vite',
80
- outputDir: 'dist',
81
- indexFile: 'index.html',
82
- expectedAssets: ['assets'],
83
- },
84
- };
85
- async function runCommand(command, cwd, timeout = 300000) {
86
- return new Promise((resolve) => {
87
- let killed = false;
88
- let stdout = '';
89
- let stderr = '';
90
- const child = spawn('sh', ['-c', command], {
91
- cwd,
92
- env: { ...process.env },
93
- });
94
- // Set up timeout with proper cleanup
95
- const timeoutId = setTimeout(() => {
96
- killed = true;
97
- child.kill('SIGTERM');
98
- // Force kill if not terminated after 5 seconds
99
- setTimeout(() => {
100
- if (!child.killed) {
101
- child.kill('SIGKILL');
102
- }
103
- }, 5000);
104
- }, timeout);
105
- child.stdout?.on('data', (data) => {
106
- stdout += data.toString();
107
- });
108
- child.stderr?.on('data', (data) => {
109
- stderr += data.toString();
110
- });
111
- child.on('close', (code) => {
112
- clearTimeout(timeoutId);
113
- if (killed) {
114
- resolve({
115
- stdout: stdout.trim(),
116
- stderr: `${stderr.trim()}\n[Process timed out and was terminated]`,
117
- exitCode: code ?? 1,
118
- timedOut: true,
119
- });
120
- }
121
- else {
122
- resolve({ stdout: stdout.trim(), stderr: stderr.trim(), exitCode: code ?? 1 });
123
- }
124
- });
125
- child.on('error', (err) => {
126
- clearTimeout(timeoutId);
127
- resolve({ stdout: '', stderr: err.message, exitCode: 1 });
128
- });
129
- });
130
- }
131
- /**
132
- * Safely parse JSON with helpful error messages
133
- */
134
- function safeJsonParse(content, source) {
135
- try {
136
- return { data: JSON.parse(content), error: null };
137
- }
138
- catch (e) {
139
- const preview = content.slice(0, 100).replace(/\n/g, '\\n');
140
- return {
141
- data: null,
142
- error: `Failed to parse ${source}: ${e instanceof Error ? e.message : 'Invalid JSON'}. Content preview: "${preview}..."`,
143
- };
144
- }
145
- }
146
- /**
147
- * Validate URL format and protocol
148
- */
149
- function validateUrl(url) {
150
- if (!url || typeof url !== 'string') {
151
- return { valid: false, error: 'URL is required and must be a string' };
152
- }
153
- try {
154
- const parsed = new URL(url);
155
- if (!['http:', 'https:'].includes(parsed.protocol)) {
156
- return { valid: false, error: `Invalid protocol "${parsed.protocol}". Only http: and https: are supported` };
157
- }
158
- return { valid: true, normalized: parsed.toString() };
159
- }
160
- catch {
161
- return { valid: false, error: `Invalid URL format: "${url}"` };
162
- }
163
- }
164
- /**
165
- * Validate file path for path traversal attacks
166
- */
167
- function validateFilePath(filePath, baseDir) {
168
- if (!filePath || typeof filePath !== 'string') {
169
- return { valid: false, error: 'File path is required and must be a string' };
170
- }
171
- const resolved = path.resolve(baseDir, filePath);
172
- const normalizedBase = path.resolve(baseDir);
173
- if (!resolved.startsWith(normalizedBase)) {
174
- return { valid: false, error: 'Path traversal not allowed - path must be within working directory' };
175
- }
176
- return { valid: true, resolved };
177
- }
178
- /**
179
- * Format output with truncation warning
180
- */
181
- function truncateOutput(output, maxLength, label) {
182
- if (output.length <= maxLength) {
183
- return output;
184
- }
185
- return `${output.slice(0, maxLength)}\n\n[${label} truncated - ${output.length - maxLength} more characters not shown]`;
186
- }
187
- function detectFramework(workingDir) {
188
- const packageJsonPath = path.join(workingDir, 'package.json');
189
- if (fs.existsSync(packageJsonPath)) {
190
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
191
- const { data: pkg } = safeJsonParse(content, 'package.json');
192
- if (pkg) {
193
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
194
- if (deps['next'])
195
- return 'nextjs';
196
- if (deps['@angular/core'])
197
- return 'angular';
198
- if (deps['vue'])
199
- return 'vue';
200
- if (deps['svelte'])
201
- return 'svelte';
202
- if (deps['vite'])
203
- return 'vite';
204
- if (deps['react'])
205
- return 'react';
206
- }
207
- }
208
- return 'unknown';
209
- }
210
- function detectE2EFramework(workingDir) {
211
- const packageJsonPath = path.join(workingDir, 'package.json');
212
- if (fs.existsSync(packageJsonPath)) {
213
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
214
- const { data: pkg } = safeJsonParse(content, 'package.json');
215
- if (pkg) {
216
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
217
- if (deps['cypress'])
218
- return 'cypress';
219
- if (deps['@playwright/test'] || deps['playwright'])
220
- return 'playwright';
221
- if (deps['puppeteer'])
222
- return 'puppeteer';
223
- }
224
- }
225
- // Check for config files
226
- if (fs.existsSync(path.join(workingDir, 'cypress.config.js')) ||
227
- fs.existsSync(path.join(workingDir, 'cypress.config.ts'))) {
228
- return 'cypress';
229
- }
230
- if (fs.existsSync(path.join(workingDir, 'playwright.config.ts')) ||
231
- fs.existsSync(path.join(workingDir, 'playwright.config.js'))) {
232
- return 'playwright';
233
- }
234
- return null;
235
- }
236
- async function fetchUrl(url, timeout = 10000) {
237
- try {
238
- const controller = new AbortController();
239
- const timeoutId = setTimeout(() => controller.abort(), timeout);
240
- const response = await fetch(url, {
241
- signal: controller.signal,
242
- headers: { 'User-Agent': 'erosolar-cli/frontend-testing' },
243
- });
244
- clearTimeout(timeoutId);
245
- const body = await response.text();
246
- return { status: response.status, body: body.slice(0, 5000) };
247
- }
248
- catch (error) {
249
- const errorMessage = error instanceof Error ? error.message : String(error);
250
- let errorType = 'UNKNOWN';
251
- let userFriendlyError = errorMessage;
252
- // Categorize common network errors
253
- if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('getaddrinfo')) {
254
- errorType = 'DNS_FAILURE';
255
- userFriendlyError = 'DNS lookup failed - check if the domain exists and your internet connection';
256
- }
257
- else if (errorMessage.includes('ECONNREFUSED')) {
258
- errorType = 'CONNECTION_REFUSED';
259
- userFriendlyError = 'Connection refused - is the server running?';
260
- }
261
- else if (errorMessage.includes('ETIMEDOUT') || errorMessage.includes('timeout') || errorMessage.includes('aborted')) {
262
- errorType = 'TIMEOUT';
263
- userFriendlyError = `Request timed out after ${timeout}ms - server may be slow or unreachable`;
264
- }
265
- else if (errorMessage.includes('EHOSTUNREACH')) {
266
- errorType = 'HOST_UNREACHABLE';
267
- userFriendlyError = 'Host unreachable - check your network connection';
268
- }
269
- else if (errorMessage.includes('certificate') || errorMessage.includes('SSL') || errorMessage.includes('TLS')) {
270
- errorType = 'SSL_ERROR';
271
- userFriendlyError = 'SSL/TLS certificate error - the site may have an invalid certificate';
272
- }
273
- return {
274
- status: 0,
275
- body: '',
276
- error: userFriendlyError,
277
- errorType,
278
- };
279
- }
280
- }
281
- function analyzeBundle(dir) {
282
- const result = {
283
- totalSize: 0,
284
- jsSize: 0,
285
- cssSize: 0,
286
- imageSize: 0,
287
- files: [],
288
- };
289
- function walk(currentDir) {
290
- if (!fs.existsSync(currentDir))
291
- return;
292
- const entries = fs.readdirSync(currentDir, { withFileTypes: true });
293
- for (const entry of entries) {
294
- const fullPath = path.join(currentDir, entry.name);
295
- if (entry.isDirectory()) {
296
- walk(fullPath);
297
- }
298
- else if (entry.isFile()) {
299
- const stats = fs.statSync(fullPath);
300
- const size = stats.size;
301
- const ext = path.extname(entry.name).toLowerCase();
302
- result.totalSize += size;
303
- result.files.push({ name: path.relative(dir, fullPath), size });
304
- if (['.js', '.mjs', '.cjs'].includes(ext)) {
305
- result.jsSize += size;
306
- }
307
- else if (['.css', '.scss', '.sass', '.less'].includes(ext)) {
308
- result.cssSize += size;
309
- }
310
- else if (['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.avif'].includes(ext)) {
311
- result.imageSize += size;
312
- }
313
- }
314
- }
315
- }
316
- walk(dir);
317
- // Sort by size descending
318
- result.files.sort((a, b) => b.size - a.size);
319
- return result;
320
- }
321
- function formatBytes(bytes) {
322
- if (bytes === 0)
323
- return '0 B';
324
- const k = 1024;
325
- const sizes = ['B', 'KB', 'MB', 'GB'];
326
- const i = Math.floor(Math.log(bytes) / Math.log(k));
327
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
328
- }
329
- export function createFrontendTestingTools(workingDir = process.cwd()) {
330
- return [
331
- {
332
- name: 'run_e2e_tests',
333
- description: `Run end-to-end tests using Cypress, Playwright, or Puppeteer.
334
-
335
- Automatically detects the E2E framework from your project and runs tests.
336
- Supports:
337
- - Cypress (cypress run)
338
- - Playwright (npx playwright test)
339
- - Puppeteer (jest with puppeteer)
340
-
341
- Features:
342
- - Headless mode for CI/CD
343
- - Spec/test file filtering
344
- - Browser selection
345
- - Screenshot capture on failure
346
- - Video recording (Cypress/Playwright)`,
347
- parameters: {
348
- type: 'object',
349
- properties: {
350
- framework: {
351
- type: 'string',
352
- enum: ['cypress', 'playwright', 'puppeteer', 'auto'],
353
- description: 'E2E framework to use (default: auto-detect)',
354
- },
355
- spec: {
356
- type: 'string',
357
- description: 'Specific test file or pattern to run',
358
- },
359
- browser: {
360
- type: 'string',
361
- enum: ['chrome', 'chromium', 'firefox', 'webkit', 'electron'],
362
- description: 'Browser to use for testing',
363
- },
364
- headed: {
365
- type: 'boolean',
366
- description: 'Run in headed mode (show browser window)',
367
- },
368
- baseUrl: {
369
- type: 'string',
370
- description: 'Base URL for the application under test',
371
- },
372
- timeout: {
373
- type: 'number',
374
- description: 'Timeout in milliseconds (default: 300000)',
375
- },
376
- },
377
- },
378
- handler: async (args) => {
379
- let frameworkId = args['framework'] || 'auto';
380
- const spec = args['spec'];
381
- const browser = args['browser'];
382
- const headed = args['headed'] === true;
383
- const baseUrl = args['baseUrl'];
384
- const timeout = args['timeout'] || 300000;
385
- // Auto-detect framework
386
- if (frameworkId === 'auto') {
387
- const detected = detectE2EFramework(workingDir);
388
- if (!detected) {
389
- return `No E2E testing framework detected in ${workingDir}
390
-
391
- To get started, install one of the supported frameworks:
392
- - Cypress: npm install -D cypress && npx cypress open
393
- - Playwright: npm install -D @playwright/test && npx playwright install
394
-
395
- Then run this tool again.`;
396
- }
397
- frameworkId = detected;
398
- }
399
- const framework = E2E_FRAMEWORKS[frameworkId];
400
- if (!framework) {
401
- return `Unknown E2E framework: ${frameworkId}\n\nSupported: cypress, playwright, puppeteer`;
402
- }
403
- // Build command
404
- let command = framework.runCommand;
405
- if (spec) {
406
- if (frameworkId === 'cypress') {
407
- command += ` --spec "${spec}"`;
408
- }
409
- else if (frameworkId === 'playwright') {
410
- command += ` "${spec}"`;
411
- }
412
- }
413
- if (browser) {
414
- if (frameworkId === 'cypress') {
415
- command += ` --browser ${browser}`;
416
- }
417
- else if (frameworkId === 'playwright') {
418
- command += ` --project=${browser}`;
419
- }
420
- }
421
- if (!headed && framework.headlessFlag) {
422
- command += ` ${framework.headlessFlag}`;
423
- }
424
- else if (headed && frameworkId === 'playwright') {
425
- command += ' --headed';
426
- }
427
- if (baseUrl && frameworkId === 'cypress') {
428
- command += ` --config baseUrl=${baseUrl}`;
429
- }
430
- const results = [`🧪 Running ${framework.name} E2E Tests\n`];
431
- results.push(`Command: ${command}\n`);
432
- const result = await runCommand(command, workingDir, timeout);
433
- if (result.exitCode === 0) {
434
- results.push(`✅ All E2E tests passed!\n`);
435
- }
436
- else {
437
- results.push(`❌ E2E tests failed (exit code: ${result.exitCode})\n`);
438
- }
439
- if (result.stdout) {
440
- results.push(`Output:\n${truncateOutput(result.stdout, 10000, 'output')}\n`);
441
- }
442
- if (result.stderr) {
443
- results.push(`Errors:\n${truncateOutput(result.stderr, 5000, 'errors')}\n`);
444
- }
445
- return results.join('\n');
446
- },
447
- },
448
- {
449
- name: 'verify_build_output',
450
- description: `Verify frontend build output and analyze bundle.
451
-
452
- Checks:
453
- - Build directory exists and contains expected files
454
- - Bundle size analysis (JS, CSS, images)
455
- - Source map presence
456
- - Index.html integrity
457
- - Large file detection
458
- - Missing asset detection
459
-
460
- Works with: React, Next.js, Angular, Vue, Svelte, Vite`,
461
- parameters: {
462
- type: 'object',
463
- properties: {
464
- buildDir: {
465
- type: 'string',
466
- description: 'Build output directory (auto-detected if not specified)',
467
- },
468
- framework: {
469
- type: 'string',
470
- enum: ['react', 'nextjs', 'angular', 'vue', 'svelte', 'vite', 'auto'],
471
- description: 'Frontend framework (default: auto-detect)',
472
- },
473
- maxBundleSize: {
474
- type: 'number',
475
- description: 'Maximum total bundle size in bytes (default: 5MB)',
476
- },
477
- warnLargeFiles: {
478
- type: 'number',
479
- description: 'Warn about files larger than this (bytes, default: 500KB)',
480
- },
481
- },
482
- },
483
- handler: async (args) => {
484
- let frameworkId = args['framework'] || 'auto';
485
- const maxBundleSize = args['maxBundleSize'] || 5 * 1024 * 1024; // 5MB
486
- const warnLargeFiles = args['warnLargeFiles'] || 500 * 1024; // 500KB
487
- // Auto-detect framework
488
- if (frameworkId === 'auto') {
489
- frameworkId = detectFramework(workingDir);
490
- }
491
- const config = BUILD_CONFIGS[frameworkId] ?? BUILD_CONFIGS['react'];
492
- const buildDir = args['buildDir'] || path.join(workingDir, config.outputDir);
493
- const results = [`📦 Build Output Verification\n`];
494
- results.push(`Framework: ${config.framework}`);
495
- results.push(`Build directory: ${buildDir}\n`);
496
- // Check if build directory exists
497
- if (!fs.existsSync(buildDir)) {
498
- return `❌ Build directory not found: ${buildDir}
499
-
500
- Run your build command first:
501
- - React: npm run build
502
- - Next.js: npm run build
503
- - Angular: ng build
504
- - Vue: npm run build
505
- - Vite: npm run build`;
506
- }
507
- results.push(`✅ Build directory exists\n`);
508
- // Check for index.html (if applicable)
509
- if (config.indexFile) {
510
- const indexPath = path.join(buildDir, config.indexFile);
511
- if (fs.existsSync(indexPath)) {
512
- results.push(`✅ ${config.indexFile} found`);
513
- }
514
- else {
515
- results.push(`⚠️ ${config.indexFile} not found`);
516
- }
517
- }
518
- // Check for expected assets
519
- const missingAssets = [];
520
- for (const asset of config.expectedAssets) {
521
- const assetPath = path.join(buildDir, asset);
522
- if (!fs.existsSync(assetPath)) {
523
- missingAssets.push(asset);
524
- }
525
- }
526
- if (missingAssets.length > 0) {
527
- results.push(`⚠️ Missing expected assets: ${missingAssets.join(', ')}`);
528
- }
529
- else {
530
- results.push(`✅ All expected assets present`);
531
- }
532
- // Analyze bundle
533
- const analysis = analyzeBundle(buildDir);
534
- results.push(`\n📊 Bundle Analysis:`);
535
- results.push(`Total size: ${formatBytes(analysis.totalSize)}`);
536
- results.push(`JavaScript: ${formatBytes(analysis.jsSize)}`);
537
- results.push(`CSS: ${formatBytes(analysis.cssSize)}`);
538
- results.push(`Images: ${formatBytes(analysis.imageSize)}`);
539
- // Check bundle size limit
540
- if (analysis.totalSize > maxBundleSize) {
541
- results.push(`\n❌ Bundle exceeds size limit (${formatBytes(maxBundleSize)})`);
542
- }
543
- else {
544
- results.push(`\n✅ Bundle within size limit`);
545
- }
546
- // Large files warning
547
- const largeFiles = analysis.files.filter((f) => f.size > warnLargeFiles);
548
- if (largeFiles.length > 0) {
549
- results.push(`\n⚠️ Large files detected (>${formatBytes(warnLargeFiles)}):`);
550
- largeFiles.slice(0, 10).forEach((f) => {
551
- results.push(` - ${f.name}: ${formatBytes(f.size)}`);
552
- });
553
- }
554
- // Top 10 largest files
555
- results.push(`\n📁 Largest files:`);
556
- analysis.files.slice(0, 10).forEach((f, i) => {
557
- results.push(` ${i + 1}. ${f.name}: ${formatBytes(f.size)}`);
558
- });
559
- return results.join('\n');
560
- },
561
- },
562
- {
563
- name: 'verify_deployment',
564
- description: `Verify a frontend deployment by checking the deployed URL.
565
-
566
- Performs:
567
- - URL health check (HTTP status)
568
- - HTML content validation
569
- - Asset loading verification
570
- - Response time measurement
571
- - Basic smoke tests
572
- - SSL certificate check
573
-
574
- Use this after deploying to verify the deployment was successful.`,
575
- parameters: {
576
- type: 'object',
577
- properties: {
578
- url: {
579
- type: 'string',
580
- description: 'URL of the deployed frontend (required)',
581
- },
582
- checkAssets: {
583
- type: 'boolean',
584
- description: 'Check if CSS/JS assets are accessible (default: true)',
585
- },
586
- expectedContent: {
587
- type: 'string',
588
- description: 'String that should be present in the HTML',
589
- },
590
- expectedTitle: {
591
- type: 'string',
592
- description: 'Expected page title',
593
- },
594
- timeout: {
595
- type: 'number',
596
- description: 'Request timeout in milliseconds (default: 10000)',
597
- },
598
- },
599
- required: ['url'],
600
- },
601
- handler: async (args) => {
602
- const rawUrl = args['url'];
603
- const checkAssets = args['checkAssets'] !== false;
604
- const expectedContent = args['expectedContent'];
605
- const expectedTitle = args['expectedTitle'];
606
- const timeout = args['timeout'] || 10000;
607
- // Validate URL
608
- const urlValidation = validateUrl(rawUrl);
609
- if (!urlValidation.valid) {
610
- return `❌ Invalid URL: ${urlValidation.error}`;
611
- }
612
- const url = urlValidation.normalized;
613
- const results = [`🌐 Deployment Verification\n`];
614
- results.push(`URL: ${url}\n`);
615
- const startTime = Date.now();
616
- const response = await fetchUrl(url, timeout);
617
- const responseTime = Date.now() - startTime;
618
- results.push(`⏱️ Response time: ${responseTime}ms`);
619
- if (response.error) {
620
- results.push(`\n❌ Failed to reach URL: ${response.error}`);
621
- if (response.errorType) {
622
- results.push(`Error type: ${response.errorType}`);
623
- }
624
- return results.join('\n');
625
- }
626
- // HTTP status check with helpful context
627
- if (response.status >= 200 && response.status < 300) {
628
- results.push(`✅ HTTP Status: ${response.status}`);
629
- }
630
- else {
631
- let statusContext = '';
632
- if (response.status === 404)
633
- statusContext = ' (page not found - check URL path)';
634
- else if (response.status === 403)
635
- statusContext = ' (forbidden - authentication may be required)';
636
- else if (response.status === 500)
637
- statusContext = ' (server error - check server logs)';
638
- else if (response.status === 502)
639
- statusContext = ' (bad gateway - upstream server issue)';
640
- else if (response.status === 503)
641
- statusContext = ' (service unavailable - server may be overloaded)';
642
- results.push(`❌ HTTP Status: ${response.status}${statusContext}`);
643
- }
644
- // SSL check
645
- if (url.startsWith('https://')) {
646
- results.push(`✅ HTTPS enabled`);
647
- }
648
- else {
649
- results.push(`⚠️ Not using HTTPS`);
650
- }
651
- // Content checks
652
- const body = response.body;
653
- // Check for HTML doctype
654
- if (body.toLowerCase().includes('<!doctype html')) {
655
- results.push(`✅ Valid HTML document`);
656
- }
657
- else {
658
- results.push(`⚠️ HTML doctype not found`);
659
- }
660
- // Check for expected content
661
- if (expectedContent) {
662
- if (body.includes(expectedContent)) {
663
- results.push(`✅ Expected content found: "${expectedContent.slice(0, 50)}..."`);
664
- }
665
- else {
666
- results.push(`❌ Expected content not found: "${expectedContent.slice(0, 50)}..."`);
667
- }
668
- }
669
- // Check title
670
- const titleMatch = body.match(/<title>([^<]*)<\/title>/i);
671
- const actualTitle = titleMatch?.[1] || '';
672
- if (expectedTitle) {
673
- if (actualTitle.includes(expectedTitle)) {
674
- results.push(`✅ Title matches: "${actualTitle}"`);
675
- }
676
- else {
677
- results.push(`❌ Title mismatch. Expected: "${expectedTitle}", Got: "${actualTitle}"`);
678
- }
679
- }
680
- else if (actualTitle) {
681
- results.push(`📄 Page title: "${actualTitle}"`);
682
- }
683
- // Check for common SPA indicators
684
- if (body.includes('id="root"') || body.includes('id="app"') || body.includes('id="__next"')) {
685
- results.push(`✅ SPA mount point detected`);
686
- }
687
- // Extract and check assets
688
- if (checkAssets) {
689
- results.push(`\n🔍 Asset Verification:`);
690
- // Find JS files
691
- const jsMatches = body.match(/src="([^"]+\.js[^"]*)"/g) || [];
692
- const jsFiles = jsMatches.map((m) => m.match(/src="([^"]+)"/)?.[1]).filter(Boolean);
693
- // Find CSS files
694
- const cssMatches = body.match(/href="([^"]+\.css[^"]*)"/g) || [];
695
- const cssFiles = cssMatches.map((m) => m.match(/href="([^"]+)"/)?.[1]).filter(Boolean);
696
- results.push(`Found ${jsFiles.length} JavaScript file(s)`);
697
- results.push(`Found ${cssFiles.length} CSS file(s)`);
698
- // Check first few assets in parallel for faster feedback
699
- const assetsToCheck = [...jsFiles.slice(0, 2), ...cssFiles.slice(0, 2)];
700
- const assetPromises = assetsToCheck
701
- .filter((assetPath) => typeof assetPath === 'string' && assetPath.length > 0)
702
- .map(async (assetPath) => {
703
- const assetUrl = assetPath.startsWith('http') ? assetPath : new URL(assetPath, url).toString();
704
- const response = await fetchUrl(assetUrl, 5000);
705
- return { assetPath, response };
706
- });
707
- const assetResponses = await Promise.all(assetPromises);
708
- for (const { assetPath, response } of assetResponses) {
709
- if (response.status === 200) {
710
- results.push(` ✅ ${assetPath.slice(0, 50)}...`);
711
- }
712
- else {
713
- results.push(` ❌ ${assetPath.slice(0, 50)}... (${response.status || response.error})`);
714
- }
715
- }
716
- }
717
- // Summary
718
- results.push(`\n📋 Summary:`);
719
- if (response.status >= 200 && response.status < 300 && responseTime < 3000) {
720
- results.push(`✅ Deployment appears healthy`);
721
- }
722
- else if (response.status >= 200 && response.status < 300) {
723
- results.push(`⚠️ Deployment working but slow (${responseTime}ms)`);
724
- }
725
- else {
726
- results.push(`❌ Deployment issues detected`);
727
- }
728
- return results.join('\n');
729
- },
730
- },
731
- {
732
- name: 'run_accessibility_tests',
733
- description: `Run accessibility tests on a URL or HTML file using axe-core.
734
-
735
- Checks for:
736
- - WCAG 2.1 Level A and AA compliance
737
- - Color contrast issues
738
- - Missing alt text
739
- - Form label issues
740
- - Keyboard navigation problems
741
- - ARIA attribute errors
742
-
743
- Requires: axe-core (will offer to install if not found)`,
744
- parameters: {
745
- type: 'object',
746
- properties: {
747
- url: {
748
- type: 'string',
749
- description: 'URL to test (can be local dev server)',
750
- },
751
- htmlFile: {
752
- type: 'string',
753
- description: 'Path to HTML file to test (alternative to URL)',
754
- },
755
- rules: {
756
- type: 'string',
757
- enum: ['wcag2a', 'wcag2aa', 'wcag2aaa', 'best-practice', 'all'],
758
- description: 'Accessibility rules to check (default: wcag2aa)',
759
- },
760
- timeout: {
761
- type: 'number',
762
- description: 'Timeout in milliseconds (default: 60000)',
763
- },
764
- },
765
- },
766
- handler: async (args) => {
767
- const rawUrl = args['url'];
768
- const rawHtmlFile = args['htmlFile'];
769
- const rules = args['rules'] || 'wcag2aa';
770
- const timeout = args['timeout'] || 60000;
771
- if (!rawUrl && !rawHtmlFile) {
772
- return `Please provide either a URL or HTML file path to test.
773
-
774
- Examples:
775
- - URL: http://localhost:3000
776
- - HTML file: ./build/index.html`;
777
- }
778
- // Validate URL if provided
779
- let validatedUrl;
780
- if (rawUrl) {
781
- const urlValidation = validateUrl(rawUrl);
782
- if (!urlValidation.valid) {
783
- return `❌ Invalid URL: ${urlValidation.error}`;
784
- }
785
- validatedUrl = urlValidation.normalized;
786
- }
787
- // Validate file path if provided (with path traversal protection)
788
- let validatedHtmlFile;
789
- if (rawHtmlFile) {
790
- const fileValidation = validateFilePath(rawHtmlFile, workingDir);
791
- if (!fileValidation.valid) {
792
- return `❌ Invalid file path: ${fileValidation.error}`;
793
- }
794
- validatedHtmlFile = fileValidation.resolved;
795
- }
796
- // Check for axe-core in project
797
- const packageJsonPath = path.join(workingDir, 'package.json');
798
- let hasAxe = false;
799
- if (fs.existsSync(packageJsonPath)) {
800
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
801
- const { data: pkg } = safeJsonParse(content, 'package.json');
802
- if (pkg) {
803
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
804
- hasAxe = !!(deps['axe-core'] || deps['@axe-core/puppeteer'] || deps['@axe-core/playwright']);
805
- }
806
- }
807
- // Try to use pa11y or axe-cli if available
808
- const result = await runCommand('which pa11y || which axe', workingDir, 5000);
809
- const hasCli = result.exitCode === 0;
810
- if (!hasAxe && !hasCli) {
811
- return `Accessibility testing tools not found.
812
-
813
- Install one of the following:
814
-
815
- Option 1 - pa11y (recommended for CLI):
816
- npm install -g pa11y
817
-
818
- Option 2 - axe-cli:
819
- npm install -g @axe-core/cli
820
-
821
- Option 3 - Add to project:
822
- npm install -D axe-core @axe-core/playwright
823
-
824
- After installation, run this tool again.`;
825
- }
826
- const target = validatedUrl || validatedHtmlFile;
827
- const results = [`♿ Accessibility Testing\n`];
828
- results.push(`Target: ${target}`);
829
- results.push(`Rules: ${rules}\n`);
830
- // Try pa11y first
831
- if (hasCli) {
832
- let command = `pa11y "${target}" --standard ${rules.toUpperCase().replace('WCAG2', 'WCAG2').replace('aa', 'AA').replace('a', 'A')} --reporter json 2>&1`;
833
- if (validatedUrl) {
834
- command = `pa11y "${validatedUrl}" --reporter cli --standard WCAG2AA 2>&1`;
835
- }
836
- const testResult = await runCommand(command, workingDir, timeout);
837
- if (testResult.exitCode === 0 && !testResult.stdout.includes('Error:')) {
838
- results.push(`✅ No accessibility violations found!\n`);
839
- }
840
- else if (testResult.stdout.includes('Error:')) {
841
- results.push(`⚠️ Could not run pa11y: ${truncateOutput(testResult.stdout, 500, 'output')}`);
842
- }
843
- else {
844
- results.push(`❌ Accessibility issues found:\n`);
845
- results.push(truncateOutput(testResult.stdout, 8000, 'output'));
846
- }
847
- if (testResult.stderr && !testResult.stderr.includes('Deprecation')) {
848
- results.push(`\nWarnings:\n${truncateOutput(testResult.stderr, 2000, 'warnings')}`);
849
- }
850
- }
851
- else {
852
- // Fallback to basic HTML analysis
853
- results.push(`Using basic HTML analysis (install pa11y for comprehensive testing)\n`);
854
- if (validatedHtmlFile && fs.existsSync(validatedHtmlFile)) {
855
- const html = fs.readFileSync(validatedHtmlFile, 'utf-8');
856
- // Basic checks
857
- const issues = [];
858
- // Check for images without alt
859
- const imgWithoutAlt = html.match(/<img(?![^>]*\balt=)[^>]*>/gi);
860
- if (imgWithoutAlt?.length) {
861
- issues.push(`- ${imgWithoutAlt.length} image(s) missing alt attribute`);
862
- }
863
- // Check for inputs without labels
864
- const inputsWithoutId = html.match(/<input(?![^>]*\bid=)[^>]*>/gi);
865
- if (inputsWithoutId?.length) {
866
- issues.push(`- ${inputsWithoutId.length} input(s) may be missing associated labels`);
867
- }
868
- // Check for lang attribute
869
- if (!html.includes('lang=')) {
870
- issues.push(`- Missing lang attribute on <html> element`);
871
- }
872
- // Check for viewport
873
- if (!html.includes('viewport')) {
874
- issues.push(`- Missing viewport meta tag`);
875
- }
876
- if (issues.length > 0) {
877
- results.push(`Found ${issues.length} potential issue(s):\n${issues.join('\n')}`);
878
- }
879
- else {
880
- results.push(`✅ No basic accessibility issues detected`);
881
- }
882
- }
883
- else if (validatedUrl) {
884
- const response = await fetchUrl(validatedUrl);
885
- if (response.status === 200) {
886
- // Basic analysis of fetched HTML
887
- const html = response.body;
888
- const issues = [];
889
- if (!html.includes('lang=')) {
890
- issues.push(`- Missing lang attribute`);
891
- }
892
- const imgWithoutAlt = html.match(/<img(?![^>]*\balt=)[^>]*>/gi);
893
- if (imgWithoutAlt?.length) {
894
- issues.push(`- ${imgWithoutAlt.length} image(s) missing alt attribute`);
895
- }
896
- if (issues.length > 0) {
897
- results.push(`Found ${issues.length} potential issue(s):\n${issues.join('\n')}`);
898
- }
899
- else {
900
- results.push(`✅ No basic accessibility issues detected`);
901
- }
902
- }
903
- }
904
- }
905
- return results.join('\n');
906
- },
907
- },
908
- {
909
- name: 'run_lighthouse',
910
- description: `Run Lighthouse performance audit on a URL.
911
-
912
- Generates reports for:
913
- - Performance (LCP, FID, CLS, etc.)
914
- - Accessibility
915
- - Best Practices
916
- - SEO
917
- - PWA (optional)
918
-
919
- Requires: lighthouse CLI or Chrome browser`,
920
- parameters: {
921
- type: 'object',
922
- properties: {
923
- url: {
924
- type: 'string',
925
- description: 'URL to audit (required)',
926
- },
927
- categories: {
928
- type: 'array',
929
- items: { type: 'string' },
930
- description: 'Categories to audit: performance, accessibility, best-practices, seo, pwa',
931
- },
932
- output: {
933
- type: 'string',
934
- enum: ['json', 'html', 'csv'],
935
- description: 'Output format (default: json)',
936
- },
937
- outputPath: {
938
- type: 'string',
939
- description: 'Path to save report (optional)',
940
- },
941
- device: {
942
- type: 'string',
943
- enum: ['mobile', 'desktop'],
944
- description: 'Device emulation (default: mobile)',
945
- },
946
- timeout: {
947
- type: 'number',
948
- description: 'Timeout in milliseconds (default: 120000)',
949
- },
950
- },
951
- required: ['url'],
952
- },
953
- handler: async (args) => {
954
- const rawUrl = args['url'];
955
- const categories = args['categories'] || ['performance', 'accessibility', 'best-practices', 'seo'];
956
- const output = args['output'] || 'json';
957
- const rawOutputPath = args['outputPath'];
958
- const device = args['device'] || 'mobile';
959
- const timeout = args['timeout'] || 120000;
960
- // Validate URL
961
- const urlValidation = validateUrl(rawUrl);
962
- if (!urlValidation.valid) {
963
- return `❌ Invalid URL: ${urlValidation.error}`;
964
- }
965
- const url = urlValidation.normalized;
966
- // Validate output path if provided (with path traversal protection)
967
- let outputPath;
968
- if (rawOutputPath) {
969
- const pathValidation = validateFilePath(rawOutputPath, workingDir);
970
- if (!pathValidation.valid) {
971
- return `❌ Invalid output path: ${pathValidation.error}`;
972
- }
973
- outputPath = pathValidation.resolved;
974
- }
975
- // Check for lighthouse
976
- const checkResult = await runCommand('which lighthouse', workingDir, 5000);
977
- if (checkResult.exitCode !== 0) {
978
- return `Lighthouse CLI not found.
979
-
980
- Install with:
981
- npm install -g lighthouse
982
-
983
- Or use Chrome DevTools Lighthouse panel for manual audits.`;
984
- }
985
- const results = [`🔦 Lighthouse Audit\n`];
986
- results.push(`URL: ${url}`);
987
- results.push(`Device: ${device}`);
988
- results.push(`Categories: ${categories.join(', ')}\n`);
989
- // Build command
990
- let command = `lighthouse "${url}" --output=${output} --quiet`;
991
- command += ` --only-categories=${categories.join(',')}`;
992
- command += device === 'desktop' ? ' --preset=desktop' : '';
993
- command += ' --chrome-flags="--headless --no-sandbox"';
994
- if (outputPath) {
995
- command += ` --output-path="${outputPath}"`;
996
- }
997
- const auditResult = await runCommand(command, workingDir, timeout);
998
- if (auditResult.exitCode !== 0) {
999
- results.push(`❌ Lighthouse audit failed:\n${truncateOutput(auditResult.stderr || auditResult.stdout, 3000, 'error output')}`);
1000
- return results.join('\n');
1001
- }
1002
- // Parse JSON output
1003
- if (output === 'json') {
1004
- const { data: report, error: parseError } = safeJsonParse(auditResult.stdout, 'Lighthouse report');
1005
- if (parseError || !report) {
1006
- results.push(`⚠️ Could not parse Lighthouse results: ${parseError}`);
1007
- results.push(`Raw output:\n${truncateOutput(auditResult.stdout, 5000, 'output')}`);
1008
- return results.join('\n');
1009
- }
1010
- const cats = report.categories || {};
1011
- results.push(`📊 Scores:\n`);
1012
- for (const cat of Object.values(cats)) {
1013
- const score = Math.round((cat.score || 0) * 100);
1014
- const emoji = score >= 90 ? '🟢' : score >= 50 ? '🟡' : '🔴';
1015
- results.push(`${emoji} ${cat.title}: ${score}/100`);
1016
- }
1017
- // Show key metrics if available
1018
- const metrics = report.audits;
1019
- if (metrics) {
1020
- results.push(`\n📈 Key Metrics:`);
1021
- const keyMetrics = [
1022
- { id: 'first-contentful-paint', label: 'First Contentful Paint' },
1023
- { id: 'largest-contentful-paint', label: 'Largest Contentful Paint' },
1024
- { id: 'total-blocking-time', label: 'Total Blocking Time' },
1025
- { id: 'cumulative-layout-shift', label: 'Cumulative Layout Shift' },
1026
- { id: 'speed-index', label: 'Speed Index' },
1027
- ];
1028
- for (const metric of keyMetrics) {
1029
- const audit = metrics[metric.id];
1030
- if (audit) {
1031
- const score = Math.round((audit.score || 0) * 100);
1032
- const emoji = score >= 90 ? '✅' : score >= 50 ? '⚠️' : '❌';
1033
- results.push(`${emoji} ${metric.label}: ${audit.displayValue || 'N/A'}`);
1034
- }
1035
- }
1036
- }
1037
- }
1038
- else {
1039
- results.push(`✅ Report generated`);
1040
- if (outputPath) {
1041
- results.push(`Saved to: ${outputPath}`);
1042
- }
1043
- }
1044
- return results.join('\n');
1045
- },
1046
- },
1047
- {
1048
- name: 'frontend_test_workflow',
1049
- description: `Run a complete frontend testing workflow.
1050
-
1051
- Executes a series of tests in order:
1052
- 1. Build verification
1053
- 2. Unit tests (if present)
1054
- 3. E2E tests (if present)
1055
- 4. Accessibility tests
1056
- 5. Performance audit (optional)
1057
-
1058
- Perfect for CI/CD pipelines or pre-deployment verification.`,
1059
- parameters: {
1060
- type: 'object',
1061
- properties: {
1062
- skipBuild: {
1063
- type: 'boolean',
1064
- description: 'Skip build verification (default: false)',
1065
- },
1066
- skipUnit: {
1067
- type: 'boolean',
1068
- description: 'Skip unit tests (default: false)',
1069
- },
1070
- skipE2e: {
1071
- type: 'boolean',
1072
- description: 'Skip E2E tests (default: false)',
1073
- },
1074
- skipA11y: {
1075
- type: 'boolean',
1076
- description: 'Skip accessibility tests (default: false)',
1077
- },
1078
- runLighthouse: {
1079
- type: 'boolean',
1080
- description: 'Run Lighthouse performance audit (default: false)',
1081
- },
1082
- baseUrl: {
1083
- type: 'string',
1084
- description: 'Base URL for tests (uses local server if not specified)',
1085
- },
1086
- timeout: {
1087
- type: 'number',
1088
- description: 'Timeout per step in milliseconds (default: 300000)',
1089
- },
1090
- },
1091
- },
1092
- handler: async (args) => {
1093
- const skipBuild = args['skipBuild'] === true;
1094
- const skipUnit = args['skipUnit'] === true;
1095
- const skipE2e = args['skipE2e'] === true;
1096
- const skipA11y = args['skipA11y'] === true;
1097
- const runLighthouseArg = args['runLighthouse'] === true;
1098
- const rawBaseUrl = args['baseUrl'];
1099
- const timeout = args['timeout'] || 300000;
1100
- // Validate baseUrl if provided
1101
- let baseUrl;
1102
- if (rawBaseUrl) {
1103
- const urlValidation = validateUrl(rawBaseUrl);
1104
- if (!urlValidation.valid) {
1105
- return `❌ Invalid baseUrl: ${urlValidation.error}`;
1106
- }
1107
- baseUrl = urlValidation.normalized;
1108
- }
1109
- const results = [`🚀 Frontend Testing Workflow\n`];
1110
- const summary = [];
1111
- // Step 1: Build Verification
1112
- if (!skipBuild) {
1113
- results.push(`\n━━━ Step 1: Build Verification ━━━\n`);
1114
- const startTime = Date.now();
1115
- // Run build first
1116
- const buildResult = await runCommand('npm run build', workingDir, timeout);
1117
- const buildTime = Date.now() - startTime;
1118
- if (buildResult.exitCode === 0) {
1119
- results.push(`✅ Build succeeded (${buildTime}ms)\n`);
1120
- summary.push({ step: 'Build', status: 'PASS', time: buildTime });
1121
- // Verify output
1122
- const detectedFramework = detectFramework(workingDir);
1123
- const buildConfig = BUILD_CONFIGS[detectedFramework] ?? BUILD_CONFIGS['react'];
1124
- const buildDir = path.join(workingDir, buildConfig.outputDir);
1125
- if (fs.existsSync(buildDir)) {
1126
- const analysis = analyzeBundle(buildDir);
1127
- results.push(`Bundle size: ${formatBytes(analysis.totalSize)}`);
1128
- }
1129
- }
1130
- else {
1131
- results.push(`❌ Build failed\n${truncateOutput(buildResult.stderr || buildResult.stdout, 3000, 'build output')}`);
1132
- summary.push({ step: 'Build', status: 'FAIL', time: buildTime });
1133
- }
1134
- }
1135
- // Step 2: Unit Tests
1136
- if (!skipUnit) {
1137
- results.push(`\n━━━ Step 2: Unit Tests ━━━\n`);
1138
- const startTime = Date.now();
1139
- const testResult = await runCommand('npm test -- --watchAll=false --passWithNoTests', workingDir, timeout);
1140
- const testTime = Date.now() - startTime;
1141
- if (testResult.exitCode === 0) {
1142
- results.push(`✅ Unit tests passed (${testTime}ms)\n`);
1143
- summary.push({ step: 'Unit Tests', status: 'PASS', time: testTime });
1144
- }
1145
- else {
1146
- results.push(`❌ Unit tests failed\n${truncateOutput(testResult.stdout, 3000, 'test output')}`);
1147
- summary.push({ step: 'Unit Tests', status: 'FAIL', time: testTime });
1148
- }
1149
- }
1150
- // Step 3: E2E Tests
1151
- if (!skipE2e) {
1152
- results.push(`\n━━━ Step 3: E2E Tests ━━━\n`);
1153
- const startTime = Date.now();
1154
- const e2eFramework = detectE2EFramework(workingDir);
1155
- if (e2eFramework) {
1156
- const e2eConfig = E2E_FRAMEWORKS[e2eFramework];
1157
- let command = e2eConfig.runCommand;
1158
- if (baseUrl && e2eFramework === 'cypress') {
1159
- command += ` --config baseUrl=${baseUrl}`;
1160
- }
1161
- const e2eResult = await runCommand(command, workingDir, timeout);
1162
- const e2eTime = Date.now() - startTime;
1163
- if (e2eResult.exitCode === 0) {
1164
- results.push(`✅ E2E tests passed (${e2eTime}ms)\n`);
1165
- summary.push({ step: 'E2E Tests', status: 'PASS', time: e2eTime });
1166
- }
1167
- else {
1168
- results.push(`❌ E2E tests failed\n${truncateOutput(e2eResult.stdout, 3000, 'E2E test output')}`);
1169
- summary.push({ step: 'E2E Tests', status: 'FAIL', time: e2eTime });
1170
- }
1171
- }
1172
- else {
1173
- results.push(`⏭️ No E2E framework detected, skipping`);
1174
- summary.push({ step: 'E2E Tests', status: 'SKIP', time: 0 });
1175
- }
1176
- }
1177
- // Step 4: Accessibility Tests
1178
- if (!skipA11y && baseUrl) {
1179
- results.push(`\n━━━ Step 4: Accessibility Tests ━━━\n`);
1180
- const startTime = Date.now();
1181
- const a11yResult = await runCommand(`pa11y "${baseUrl}" --reporter cli 2>&1 || echo "pa11y not available"`, workingDir, 60000);
1182
- const a11yTime = Date.now() - startTime;
1183
- if (a11yResult.stdout.includes('pa11y not available')) {
1184
- results.push(`⏭️ pa11y not installed, skipping accessibility tests`);
1185
- summary.push({ step: 'Accessibility', status: 'SKIP', time: 0 });
1186
- }
1187
- else if (a11yResult.exitCode === 0) {
1188
- results.push(`✅ No accessibility violations (${a11yTime}ms)\n`);
1189
- summary.push({ step: 'Accessibility', status: 'PASS', time: a11yTime });
1190
- }
1191
- else {
1192
- results.push(`⚠️ Accessibility issues found\n${truncateOutput(a11yResult.stdout, 2000, 'accessibility report')}`);
1193
- summary.push({ step: 'Accessibility', status: 'WARN', time: a11yTime });
1194
- }
1195
- }
1196
- else if (!skipA11y) {
1197
- results.push(`\n⏭️ Accessibility tests skipped (no baseUrl provided)`);
1198
- summary.push({ step: 'Accessibility', status: 'SKIP', time: 0 });
1199
- }
1200
- // Step 5: Lighthouse (optional)
1201
- if (runLighthouseArg && baseUrl) {
1202
- results.push(`\n━━━ Step 5: Performance Audit ━━━\n`);
1203
- const startTime = Date.now();
1204
- const lhResult = await runCommand(`lighthouse "${baseUrl}" --output=json --quiet --chrome-flags="--headless --no-sandbox" --only-categories=performance 2>&1 || echo "lighthouse not available"`, workingDir, 120000);
1205
- const lhTime = Date.now() - startTime;
1206
- if (lhResult.stdout.includes('lighthouse not available')) {
1207
- results.push(`⏭️ Lighthouse not installed, skipping performance audit`);
1208
- summary.push({ step: 'Performance', status: 'SKIP', time: 0 });
1209
- }
1210
- else {
1211
- const { data: report } = safeJsonParse(lhResult.stdout, 'Lighthouse report');
1212
- if (report) {
1213
- const perfScore = Math.round((report.categories?.performance?.score || 0) * 100);
1214
- const emoji = perfScore >= 90 ? '🟢' : perfScore >= 50 ? '🟡' : '🔴';
1215
- results.push(`${emoji} Performance Score: ${perfScore}/100 (${lhTime}ms)`);
1216
- summary.push({
1217
- step: 'Performance',
1218
- status: perfScore >= 90 ? 'PASS' : perfScore >= 50 ? 'WARN' : 'FAIL',
1219
- time: lhTime,
1220
- });
1221
- }
1222
- else {
1223
- results.push(`⚠️ Could not parse Lighthouse results`);
1224
- summary.push({ step: 'Performance', status: 'WARN', time: lhTime });
1225
- }
1226
- }
1227
- }
1228
- // Summary
1229
- results.push(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
1230
- results.push(`📋 WORKFLOW SUMMARY\n`);
1231
- const passed = summary.filter((s) => s.status === 'PASS').length;
1232
- const failed = summary.filter((s) => s.status === 'FAIL').length;
1233
- const warned = summary.filter((s) => s.status === 'WARN').length;
1234
- const skipped = summary.filter((s) => s.status === 'SKIP').length;
1235
- const totalTime = summary.reduce((acc, s) => acc + s.time, 0);
1236
- summary.forEach((s) => {
1237
- const statusEmoji = s.status === 'PASS' ? '✅' : s.status === 'FAIL' ? '❌' : s.status === 'WARN' ? '⚠️' : '⏭️';
1238
- const timeStr = s.time > 0 ? ` (${s.time}ms)` : '';
1239
- results.push(`${statusEmoji} ${s.step}: ${s.status}${timeStr}`);
1240
- });
1241
- results.push(`\n📊 Results: ${passed} passed, ${failed} failed, ${warned} warnings, ${skipped} skipped`);
1242
- results.push(`⏱️ Total time: ${totalTime}ms`);
1243
- if (failed > 0) {
1244
- results.push(`\n❌ WORKFLOW FAILED`);
1245
- }
1246
- else if (warned > 0) {
1247
- results.push(`\n⚠️ WORKFLOW COMPLETED WITH WARNINGS`);
1248
- }
1249
- else {
1250
- results.push(`\n✅ WORKFLOW PASSED`);
1251
- }
1252
- return results.join('\n');
1253
- },
1254
- },
1255
- ];
1256
- }
1257
- export { E2E_FRAMEWORKS, BUILD_CONFIGS };
1258
- //# sourceMappingURL=frontendTestingTools.js.map