@avi770/testteam 1.2.0 → 3.0.0

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 (324) hide show
  1. package/CHANGELOG.md +53 -1
  2. package/README.md +72 -7
  3. package/agents/15-regression-sentinel.ts +3 -2
  4. package/agents/24-signup-onboarding-tester.ts +429 -0
  5. package/agents/25-crud-flow-tester.ts +302 -0
  6. package/agents/26-form-validator.ts +297 -0
  7. package/agents/27-search-filter-tester.ts +326 -0
  8. package/agents/28-navigation-routing-tester.ts +425 -0
  9. package/agents/29-responsive-interaction-tester.ts +350 -0
  10. package/agents/30-multi-user-scenario-tester.ts +319 -0
  11. package/agents/31-load-tester.ts +134 -0
  12. package/agents/32-memory-leak-detector.ts +194 -0
  13. package/agents/33-bundle-analyzer.ts +132 -0
  14. package/agents/34-xss-scanner.ts +191 -0
  15. package/agents/35-csrf-tester.ts +82 -0
  16. package/agents/36-auth-fuzzer.ts +194 -0
  17. package/agents/37-dependency-scanner.ts +176 -0
  18. package/agents/38-secrets-scanner.ts +137 -0
  19. package/agents/39-api-contract-tester.ts +199 -0
  20. package/agents/40-rate-limit-tester.ts +94 -0
  21. package/agents/41-api-pagination-tester.ts +97 -0
  22. package/agents/42-graphql-tester.ts +222 -0
  23. package/agents/43-data-consistency-checker.ts +205 -0
  24. package/agents/44-backup-recovery-tester.ts +152 -0
  25. package/agents/45-data-privacy-scanner.ts +125 -0
  26. package/agents/46-seo-auditor.ts +294 -0
  27. package/agents/47-social-preview-tester.ts +232 -0
  28. package/agents/48-lighthouse-auditor.ts +213 -0
  29. package/agents/49-i18n-tester.ts +198 -0
  30. package/agents/50-timezone-tester.ts +173 -0
  31. package/agents/51-error-recovery-tester.ts +155 -0
  32. package/agents/52-offline-mode-tester.ts +180 -0
  33. package/agents/53-graceful-degradation-tester.ts +156 -0
  34. package/agents/54-websocket-tester.ts +151 -0
  35. package/agents/55-realtime-sync-tester.ts +194 -0
  36. package/agents/56-file-upload-tester.ts +194 -0
  37. package/agents/57-export-tester.ts +174 -0
  38. package/agents/58-payment-flow-tester.ts +183 -0
  39. package/agents/59-ssl-tls-auditor.ts +141 -0
  40. package/agents/60-dns-cdn-tester.ts +117 -0
  41. package/agents/61-docker-health-checker.ts +111 -0
  42. package/agents/62-env-config-validator.ts +152 -0
  43. package/agents/63-log-quality-auditor.ts +136 -0
  44. package/agents/64-analytics-tracker-tester.ts +165 -0
  45. package/agents/65-gdpr-compliance-tester.ts +215 -0
  46. package/agents/66-soc2-control-validator.ts +210 -0
  47. package/agents/67-wcag-aaa-tester.ts +241 -0
  48. package/agents/68-dead-code-detector.ts +135 -0
  49. package/agents/69-type-safety-auditor.ts +164 -0
  50. package/agents/70-complexity-analyzer.ts +179 -0
  51. package/agents/__tests__/24-signup-onboarding-tester.test.ts +274 -0
  52. package/agents/__tests__/25-crud-flow-tester.test.ts +322 -0
  53. package/agents/__tests__/26-form-validator.test.ts +345 -0
  54. package/agents/__tests__/27-search-filter-tester.test.ts +311 -0
  55. package/agents/__tests__/28-navigation-routing-tester.test.ts +328 -0
  56. package/agents/__tests__/29-responsive-interaction-tester.test.ts +297 -0
  57. package/agents/__tests__/30-multi-user-scenario-tester.test.ts +328 -0
  58. package/agents/__tests__/31-load-tester.test.ts +189 -0
  59. package/agents/__tests__/32-memory-leak-detector.test.ts +251 -0
  60. package/agents/__tests__/33-bundle-analyzer.test.ts +237 -0
  61. package/agents/__tests__/34-xss-scanner.test.ts +258 -0
  62. package/agents/__tests__/35-csrf-tester.test.ts +200 -0
  63. package/agents/__tests__/36-auth-fuzzer.test.ts +214 -0
  64. package/agents/__tests__/37-dependency-scanner.test.ts +266 -0
  65. package/agents/__tests__/38-secrets-scanner.test.ts +224 -0
  66. package/agents/__tests__/39-api-contract-tester.test.ts +312 -0
  67. package/agents/__tests__/40-rate-limit-tester.test.ts +192 -0
  68. package/agents/__tests__/41-api-pagination-tester.test.ts +198 -0
  69. package/agents/__tests__/42-graphql-tester.test.ts +252 -0
  70. package/agents/__tests__/43-data-consistency-checker.test.ts +232 -0
  71. package/agents/__tests__/44-backup-recovery-tester.test.ts +222 -0
  72. package/agents/__tests__/45-data-privacy-scanner.test.ts +223 -0
  73. package/agents/__tests__/46-seo-auditor.test.ts +261 -0
  74. package/agents/__tests__/47-social-preview-tester.test.ts +245 -0
  75. package/agents/__tests__/48-lighthouse-auditor.test.ts +276 -0
  76. package/agents/__tests__/49-i18n-tester.test.ts +201 -0
  77. package/agents/__tests__/50-timezone-tester.test.ts +172 -0
  78. package/agents/__tests__/51-error-recovery-tester.test.ts +162 -0
  79. package/agents/__tests__/52-offline-mode-tester.test.ts +164 -0
  80. package/agents/__tests__/53-graceful-degradation-tester.test.ts +168 -0
  81. package/agents/__tests__/54-websocket-tester.test.ts +157 -0
  82. package/agents/__tests__/55-realtime-sync-tester.test.ts +181 -0
  83. package/agents/__tests__/56-file-upload-tester.test.ts +172 -0
  84. package/agents/__tests__/57-export-tester.test.ts +169 -0
  85. package/agents/__tests__/58-payment-flow-tester.test.ts +182 -0
  86. package/agents/__tests__/59-ssl-tls-auditor.test.ts +179 -0
  87. package/agents/__tests__/60-dns-cdn-tester.test.ts +176 -0
  88. package/agents/__tests__/61-docker-health-checker.test.ts +150 -0
  89. package/agents/__tests__/62-env-config-validator.test.ts +166 -0
  90. package/agents/__tests__/63-log-quality-auditor.test.ts +175 -0
  91. package/agents/__tests__/64-analytics-tracker-tester.test.ts +158 -0
  92. package/agents/__tests__/65-gdpr-compliance-tester.test.ts +174 -0
  93. package/agents/__tests__/66-soc2-control-validator.test.ts +183 -0
  94. package/agents/__tests__/67-wcag-aaa-tester.test.ts +190 -0
  95. package/agents/__tests__/68-dead-code-detector.test.ts +174 -0
  96. package/agents/__tests__/69-type-safety-auditor.test.ts +173 -0
  97. package/agents/__tests__/70-complexity-analyzer.test.ts +177 -0
  98. package/agents/__tests__/registry.test.ts +13 -13
  99. package/agents/base-agent.ts +8 -0
  100. package/agents/registry.ts +171 -28
  101. package/core/__tests__/integration.test.ts +4 -4
  102. package/core/__tests__/orchestrator.test.ts +17 -16
  103. package/core/cli.ts +128 -6
  104. package/core/license.ts +208 -211
  105. package/core/orchestrator.ts +78 -5
  106. package/dist/agents/15-regression-sentinel.d.ts +2 -1
  107. package/dist/agents/15-regression-sentinel.d.ts.map +1 -1
  108. package/dist/agents/15-regression-sentinel.js +2 -2
  109. package/dist/agents/15-regression-sentinel.js.map +1 -1
  110. package/dist/agents/24-signup-onboarding-tester.d.ts +35 -0
  111. package/dist/agents/24-signup-onboarding-tester.d.ts.map +1 -0
  112. package/dist/agents/24-signup-onboarding-tester.js +357 -0
  113. package/dist/agents/24-signup-onboarding-tester.js.map +1 -0
  114. package/dist/agents/25-crud-flow-tester.d.ts +11 -0
  115. package/dist/agents/25-crud-flow-tester.d.ts.map +1 -0
  116. package/dist/agents/25-crud-flow-tester.js +253 -0
  117. package/dist/agents/25-crud-flow-tester.js.map +1 -0
  118. package/dist/agents/26-form-validator.d.ts +12 -0
  119. package/dist/agents/26-form-validator.d.ts.map +1 -0
  120. package/dist/agents/26-form-validator.js +257 -0
  121. package/dist/agents/26-form-validator.js.map +1 -0
  122. package/dist/agents/27-search-filter-tester.d.ts +20 -0
  123. package/dist/agents/27-search-filter-tester.d.ts.map +1 -0
  124. package/dist/agents/27-search-filter-tester.js +267 -0
  125. package/dist/agents/27-search-filter-tester.js.map +1 -0
  126. package/dist/agents/28-navigation-routing-tester.d.ts +32 -0
  127. package/dist/agents/28-navigation-routing-tester.d.ts.map +1 -0
  128. package/dist/agents/28-navigation-routing-tester.js +363 -0
  129. package/dist/agents/28-navigation-routing-tester.js.map +1 -0
  130. package/dist/agents/29-responsive-interaction-tester.d.ts +26 -0
  131. package/dist/agents/29-responsive-interaction-tester.d.ts.map +1 -0
  132. package/dist/agents/29-responsive-interaction-tester.js +272 -0
  133. package/dist/agents/29-responsive-interaction-tester.js.map +1 -0
  134. package/dist/agents/30-multi-user-scenario-tester.d.ts +24 -0
  135. package/dist/agents/30-multi-user-scenario-tester.d.ts.map +1 -0
  136. package/dist/agents/30-multi-user-scenario-tester.js +254 -0
  137. package/dist/agents/30-multi-user-scenario-tester.js.map +1 -0
  138. package/dist/agents/31-load-tester.d.ts +12 -0
  139. package/dist/agents/31-load-tester.d.ts.map +1 -0
  140. package/dist/agents/31-load-tester.js +110 -0
  141. package/dist/agents/31-load-tester.js.map +1 -0
  142. package/dist/agents/32-memory-leak-detector.d.ts +12 -0
  143. package/dist/agents/32-memory-leak-detector.d.ts.map +1 -0
  144. package/dist/agents/32-memory-leak-detector.js +167 -0
  145. package/dist/agents/32-memory-leak-detector.js.map +1 -0
  146. package/dist/agents/33-bundle-analyzer.d.ts +10 -0
  147. package/dist/agents/33-bundle-analyzer.d.ts.map +1 -0
  148. package/dist/agents/33-bundle-analyzer.js +111 -0
  149. package/dist/agents/33-bundle-analyzer.js.map +1 -0
  150. package/dist/agents/34-xss-scanner.d.ts +11 -0
  151. package/dist/agents/34-xss-scanner.d.ts.map +1 -0
  152. package/dist/agents/34-xss-scanner.js +164 -0
  153. package/dist/agents/34-xss-scanner.js.map +1 -0
  154. package/dist/agents/35-csrf-tester.d.ts +11 -0
  155. package/dist/agents/35-csrf-tester.d.ts.map +1 -0
  156. package/dist/agents/35-csrf-tester.js +70 -0
  157. package/dist/agents/35-csrf-tester.js.map +1 -0
  158. package/dist/agents/36-auth-fuzzer.d.ts +13 -0
  159. package/dist/agents/36-auth-fuzzer.d.ts.map +1 -0
  160. package/dist/agents/36-auth-fuzzer.js +163 -0
  161. package/dist/agents/36-auth-fuzzer.js.map +1 -0
  162. package/dist/agents/37-dependency-scanner.d.ts +11 -0
  163. package/dist/agents/37-dependency-scanner.d.ts.map +1 -0
  164. package/dist/agents/37-dependency-scanner.js +139 -0
  165. package/dist/agents/37-dependency-scanner.js.map +1 -0
  166. package/dist/agents/38-secrets-scanner.d.ts +11 -0
  167. package/dist/agents/38-secrets-scanner.d.ts.map +1 -0
  168. package/dist/agents/38-secrets-scanner.js +116 -0
  169. package/dist/agents/38-secrets-scanner.js.map +1 -0
  170. package/dist/agents/39-api-contract-tester.d.ts +12 -0
  171. package/dist/agents/39-api-contract-tester.d.ts.map +1 -0
  172. package/dist/agents/39-api-contract-tester.js +142 -0
  173. package/dist/agents/39-api-contract-tester.js.map +1 -0
  174. package/dist/agents/40-rate-limit-tester.d.ts +12 -0
  175. package/dist/agents/40-rate-limit-tester.d.ts.map +1 -0
  176. package/dist/agents/40-rate-limit-tester.js +79 -0
  177. package/dist/agents/40-rate-limit-tester.js.map +1 -0
  178. package/dist/agents/41-api-pagination-tester.d.ts +12 -0
  179. package/dist/agents/41-api-pagination-tester.d.ts.map +1 -0
  180. package/dist/agents/41-api-pagination-tester.js +79 -0
  181. package/dist/agents/41-api-pagination-tester.js.map +1 -0
  182. package/dist/agents/42-graphql-tester.d.ts +13 -0
  183. package/dist/agents/42-graphql-tester.d.ts.map +1 -0
  184. package/dist/agents/42-graphql-tester.js +187 -0
  185. package/dist/agents/42-graphql-tester.js.map +1 -0
  186. package/dist/agents/43-data-consistency-checker.d.ts +11 -0
  187. package/dist/agents/43-data-consistency-checker.d.ts.map +1 -0
  188. package/dist/agents/43-data-consistency-checker.js +176 -0
  189. package/dist/agents/43-data-consistency-checker.js.map +1 -0
  190. package/dist/agents/44-backup-recovery-tester.d.ts +11 -0
  191. package/dist/agents/44-backup-recovery-tester.d.ts.map +1 -0
  192. package/dist/agents/44-backup-recovery-tester.js +128 -0
  193. package/dist/agents/44-backup-recovery-tester.js.map +1 -0
  194. package/dist/agents/45-data-privacy-scanner.d.ts +11 -0
  195. package/dist/agents/45-data-privacy-scanner.d.ts.map +1 -0
  196. package/dist/agents/45-data-privacy-scanner.js +100 -0
  197. package/dist/agents/45-data-privacy-scanner.js.map +1 -0
  198. package/dist/agents/46-seo-auditor.d.ts +12 -0
  199. package/dist/agents/46-seo-auditor.d.ts.map +1 -0
  200. package/dist/agents/46-seo-auditor.js +275 -0
  201. package/dist/agents/46-seo-auditor.js.map +1 -0
  202. package/dist/agents/47-social-preview-tester.d.ts +11 -0
  203. package/dist/agents/47-social-preview-tester.d.ts.map +1 -0
  204. package/dist/agents/47-social-preview-tester.js +219 -0
  205. package/dist/agents/47-social-preview-tester.js.map +1 -0
  206. package/dist/agents/48-lighthouse-auditor.d.ts +11 -0
  207. package/dist/agents/48-lighthouse-auditor.d.ts.map +1 -0
  208. package/dist/agents/48-lighthouse-auditor.js +192 -0
  209. package/dist/agents/48-lighthouse-auditor.js.map +1 -0
  210. package/dist/agents/49-i18n-tester.d.ts +13 -0
  211. package/dist/agents/49-i18n-tester.d.ts.map +1 -0
  212. package/dist/agents/49-i18n-tester.js +172 -0
  213. package/dist/agents/49-i18n-tester.js.map +1 -0
  214. package/dist/agents/50-timezone-tester.d.ts +11 -0
  215. package/dist/agents/50-timezone-tester.d.ts.map +1 -0
  216. package/dist/agents/50-timezone-tester.js +152 -0
  217. package/dist/agents/50-timezone-tester.js.map +1 -0
  218. package/dist/agents/51-error-recovery-tester.d.ts +11 -0
  219. package/dist/agents/51-error-recovery-tester.d.ts.map +1 -0
  220. package/dist/agents/51-error-recovery-tester.js +134 -0
  221. package/dist/agents/51-error-recovery-tester.js.map +1 -0
  222. package/dist/agents/52-offline-mode-tester.d.ts +12 -0
  223. package/dist/agents/52-offline-mode-tester.d.ts.map +1 -0
  224. package/dist/agents/52-offline-mode-tester.js +161 -0
  225. package/dist/agents/52-offline-mode-tester.js.map +1 -0
  226. package/dist/agents/53-graceful-degradation-tester.d.ts +12 -0
  227. package/dist/agents/53-graceful-degradation-tester.d.ts.map +1 -0
  228. package/dist/agents/53-graceful-degradation-tester.js +130 -0
  229. package/dist/agents/53-graceful-degradation-tester.js.map +1 -0
  230. package/dist/agents/54-websocket-tester.d.ts +10 -0
  231. package/dist/agents/54-websocket-tester.d.ts.map +1 -0
  232. package/dist/agents/54-websocket-tester.js +132 -0
  233. package/dist/agents/54-websocket-tester.js.map +1 -0
  234. package/dist/agents/55-realtime-sync-tester.d.ts +11 -0
  235. package/dist/agents/55-realtime-sync-tester.d.ts.map +1 -0
  236. package/dist/agents/55-realtime-sync-tester.js +175 -0
  237. package/dist/agents/55-realtime-sync-tester.js.map +1 -0
  238. package/dist/agents/56-file-upload-tester.d.ts +12 -0
  239. package/dist/agents/56-file-upload-tester.d.ts.map +1 -0
  240. package/dist/agents/56-file-upload-tester.js +166 -0
  241. package/dist/agents/56-file-upload-tester.js.map +1 -0
  242. package/dist/agents/57-export-tester.d.ts +11 -0
  243. package/dist/agents/57-export-tester.d.ts.map +1 -0
  244. package/dist/agents/57-export-tester.js +155 -0
  245. package/dist/agents/57-export-tester.js.map +1 -0
  246. package/dist/agents/58-payment-flow-tester.d.ts +11 -0
  247. package/dist/agents/58-payment-flow-tester.d.ts.map +1 -0
  248. package/dist/agents/58-payment-flow-tester.js +159 -0
  249. package/dist/agents/58-payment-flow-tester.js.map +1 -0
  250. package/dist/agents/59-ssl-tls-auditor.d.ts +10 -0
  251. package/dist/agents/59-ssl-tls-auditor.d.ts.map +1 -0
  252. package/dist/agents/59-ssl-tls-auditor.js +132 -0
  253. package/dist/agents/59-ssl-tls-auditor.js.map +1 -0
  254. package/dist/agents/60-dns-cdn-tester.d.ts +10 -0
  255. package/dist/agents/60-dns-cdn-tester.d.ts.map +1 -0
  256. package/dist/agents/60-dns-cdn-tester.js +105 -0
  257. package/dist/agents/60-dns-cdn-tester.js.map +1 -0
  258. package/dist/agents/61-docker-health-checker.d.ts +10 -0
  259. package/dist/agents/61-docker-health-checker.d.ts.map +1 -0
  260. package/dist/agents/61-docker-health-checker.js +95 -0
  261. package/dist/agents/61-docker-health-checker.js.map +1 -0
  262. package/dist/agents/62-env-config-validator.d.ts +10 -0
  263. package/dist/agents/62-env-config-validator.d.ts.map +1 -0
  264. package/dist/agents/62-env-config-validator.js +132 -0
  265. package/dist/agents/62-env-config-validator.js.map +1 -0
  266. package/dist/agents/63-log-quality-auditor.d.ts +9 -0
  267. package/dist/agents/63-log-quality-auditor.d.ts.map +1 -0
  268. package/dist/agents/63-log-quality-auditor.js +121 -0
  269. package/dist/agents/63-log-quality-auditor.js.map +1 -0
  270. package/dist/agents/64-analytics-tracker-tester.d.ts +10 -0
  271. package/dist/agents/64-analytics-tracker-tester.d.ts.map +1 -0
  272. package/dist/agents/64-analytics-tracker-tester.js +146 -0
  273. package/dist/agents/64-analytics-tracker-tester.js.map +1 -0
  274. package/dist/agents/65-gdpr-compliance-tester.d.ts +13 -0
  275. package/dist/agents/65-gdpr-compliance-tester.d.ts.map +1 -0
  276. package/dist/agents/65-gdpr-compliance-tester.js +186 -0
  277. package/dist/agents/65-gdpr-compliance-tester.js.map +1 -0
  278. package/dist/agents/66-soc2-control-validator.d.ts +14 -0
  279. package/dist/agents/66-soc2-control-validator.d.ts.map +1 -0
  280. package/dist/agents/66-soc2-control-validator.js +178 -0
  281. package/dist/agents/66-soc2-control-validator.js.map +1 -0
  282. package/dist/agents/67-wcag-aaa-tester.d.ts +13 -0
  283. package/dist/agents/67-wcag-aaa-tester.d.ts.map +1 -0
  284. package/dist/agents/67-wcag-aaa-tester.js +207 -0
  285. package/dist/agents/67-wcag-aaa-tester.js.map +1 -0
  286. package/dist/agents/68-dead-code-detector.d.ts +9 -0
  287. package/dist/agents/68-dead-code-detector.d.ts.map +1 -0
  288. package/dist/agents/68-dead-code-detector.js +116 -0
  289. package/dist/agents/68-dead-code-detector.js.map +1 -0
  290. package/dist/agents/69-type-safety-auditor.d.ts +9 -0
  291. package/dist/agents/69-type-safety-auditor.d.ts.map +1 -0
  292. package/dist/agents/69-type-safety-auditor.js +148 -0
  293. package/dist/agents/69-type-safety-auditor.js.map +1 -0
  294. package/dist/agents/70-complexity-analyzer.d.ts +10 -0
  295. package/dist/agents/70-complexity-analyzer.d.ts.map +1 -0
  296. package/dist/agents/70-complexity-analyzer.js +154 -0
  297. package/dist/agents/70-complexity-analyzer.js.map +1 -0
  298. package/dist/agents/base-agent.d.ts +3 -1
  299. package/dist/agents/base-agent.d.ts.map +1 -1
  300. package/dist/agents/base-agent.js +7 -1
  301. package/dist/agents/base-agent.js.map +1 -1
  302. package/dist/agents/registry.d.ts +5 -4
  303. package/dist/agents/registry.d.ts.map +1 -1
  304. package/dist/agents/registry.js +170 -29
  305. package/dist/agents/registry.js.map +1 -1
  306. package/dist/clients/agent-mvp.d.ts +66 -0
  307. package/dist/clients/agent-mvp.d.ts.map +1 -0
  308. package/dist/clients/agent-mvp.js +91 -0
  309. package/dist/clients/agent-mvp.js.map +1 -0
  310. package/dist/clients/total-recall.d.ts +37 -0
  311. package/dist/clients/total-recall.d.ts.map +1 -0
  312. package/dist/clients/total-recall.js +224 -0
  313. package/dist/clients/total-recall.js.map +1 -0
  314. package/dist/core/cli.d.ts +3 -0
  315. package/dist/core/cli.d.ts.map +1 -1
  316. package/dist/core/cli.js +122 -6
  317. package/dist/core/cli.js.map +1 -1
  318. package/dist/core/license.js +2 -5
  319. package/dist/core/license.js.map +1 -1
  320. package/dist/core/orchestrator.d.ts +10 -1
  321. package/dist/core/orchestrator.d.ts.map +1 -1
  322. package/dist/core/orchestrator.js +66 -5
  323. package/dist/core/orchestrator.js.map +1 -1
  324. package/package.json +2 -2
@@ -0,0 +1,201 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import type { ValidatedConfig } from '../../core/config';
3
+ import type { Phase } from '../../core/types';
4
+
5
+ function makeConfig(overrides: Partial<ValidatedConfig> = {}): ValidatedConfig {
6
+ return {
7
+ schemaVersion: 1,
8
+ name: 'test',
9
+ auth: {
10
+ loginUrl: 'http://localhost/login',
11
+ credentials: { admin: { email: 'admin@test.com', password: 'secret' } },
12
+ },
13
+ modules: [
14
+ { id: 'dashboard', route: '/dashboard', sidebarIcon: true },
15
+ { id: 'tasks', route: '/tasks', sidebarIcon: true },
16
+ ],
17
+ environments: { alpha: { baseUrl: 'http://localhost:3000', seed: false } },
18
+ portals: [],
19
+ breakpoints: [],
20
+ integrations: [],
21
+ workers: [],
22
+ workflows: [],
23
+ accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
24
+ tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
25
+ costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' },
26
+ agentClassification: { blocking: [], advisory: [49] },
27
+ thresholds: {
28
+ unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 },
29
+ lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 },
30
+ apiResponseTime: 2000,
31
+ bundleSizeLimit: 500000,
32
+ maxConsoleErrors: 0,
33
+ },
34
+ disabledAgents: [],
35
+ disabledAgentSet: new Set<number>(),
36
+ ...overrides,
37
+ };
38
+ }
39
+
40
+ const fetchMock = vi.fn();
41
+ vi.stubGlobal('fetch', fetchMock);
42
+
43
+ const loginMock = vi.fn().mockResolvedValue(undefined);
44
+ vi.mock('../../helpers/navigation', () => ({
45
+ login: (...args: unknown[]) => loginMock(...args),
46
+ waitForSectionLoad: vi.fn().mockResolvedValue(undefined),
47
+ navigateToSection: vi.fn().mockResolvedValue(undefined),
48
+ switchPortal: vi.fn().mockResolvedValue(undefined),
49
+ }));
50
+
51
+ function makeMockLocator(countVal = 0) {
52
+ const locator: Record<string, ReturnType<typeof vi.fn>> = {
53
+ count: vi.fn().mockResolvedValue(countVal),
54
+ first: vi.fn(),
55
+ nth: vi.fn(),
56
+ click: vi.fn().mockResolvedValue(undefined),
57
+ fill: vi.fn().mockResolvedValue(undefined),
58
+ };
59
+ locator.first.mockReturnValue(locator);
60
+ locator.nth.mockReturnValue(locator);
61
+ return locator;
62
+ }
63
+
64
+ function makeMockPage() {
65
+ const defaultLocator = makeMockLocator(0);
66
+ return {
67
+ close: vi.fn().mockResolvedValue(undefined),
68
+ goto: vi.fn().mockResolvedValue(undefined),
69
+ locator: vi.fn().mockReturnValue(defaultLocator),
70
+ evaluate: vi.fn().mockResolvedValue(''),
71
+ on: vi.fn(),
72
+ route: vi.fn().mockResolvedValue(undefined),
73
+ unroute: vi.fn().mockResolvedValue(undefined),
74
+ keyboard: { press: vi.fn().mockResolvedValue(undefined) },
75
+ waitForSelector: vi.fn().mockResolvedValue(undefined),
76
+ };
77
+ }
78
+
79
+ let currentMockPage: ReturnType<typeof makeMockPage>;
80
+ let mockBrowser: { newPage: ReturnType<typeof vi.fn>; newContext: ReturnType<typeof vi.fn>; close: ReturnType<typeof vi.fn> };
81
+
82
+ vi.mock('playwright', async () => ({
83
+ chromium: {
84
+ launch: vi.fn().mockImplementation(async () => mockBrowser),
85
+ },
86
+ }));
87
+
88
+ const { I18nTesterAgent } = await import('../49-i18n-tester');
89
+
90
+ function createAgent(config: ValidatedConfig = makeConfig(), phase: Phase = 'beta') {
91
+ return new I18nTesterAgent(config, phase, '/tmp/test-run');
92
+ }
93
+
94
+ describe('I18nTesterAgent', () => {
95
+ beforeEach(() => {
96
+ fetchMock.mockReset().mockResolvedValue({ ok: true, status: 200 });
97
+ loginMock.mockReset().mockResolvedValue(undefined);
98
+ currentMockPage = makeMockPage();
99
+ mockBrowser = {
100
+ newPage: vi.fn().mockResolvedValue(currentMockPage),
101
+ newContext: vi.fn().mockResolvedValue({ newPage: vi.fn().mockResolvedValue(currentMockPage), close: vi.fn() }),
102
+ close: vi.fn().mockResolvedValue(undefined),
103
+ };
104
+ });
105
+
106
+ it('has agentId 49 and correct name', () => {
107
+ const agent = createAgent();
108
+ expect(agent.agentId).toBe(49);
109
+ expect(agent.agentName).toBe('i18n Tester');
110
+ });
111
+
112
+ it('throws when modules array is empty', async () => {
113
+ const agent = createAgent(makeConfig({ modules: [] }));
114
+ const result = await agent.run();
115
+ expect(result.status).toBe('failed');
116
+ });
117
+
118
+ it('reports no language switcher when none found', async () => {
119
+ currentMockPage.evaluate.mockResolvedValue('Hello world');
120
+ const agent = createAgent();
121
+ const result = await agent.run();
122
+ const finding = result.findings.find(f => f.id.includes('no-lang-switcher'));
123
+ expect(finding).toBeDefined();
124
+ expect(finding!.severity).toBe('low');
125
+ });
126
+
127
+ it('detects untranslated i18n keys', async () => {
128
+ currentMockPage.evaluate.mockResolvedValueOnce('') // findLanguageSwitcher
129
+ .mockResolvedValueOnce('home.title.subtitle') // body text with i18n key
130
+ .mockResolvedValue('');
131
+ const agent = createAgent();
132
+ const result = await agent.run();
133
+ const finding = result.findings.find(f => f.id.includes('untranslated'));
134
+ expect(finding).toBeDefined();
135
+ });
136
+
137
+ it('handles login failure gracefully', async () => {
138
+ loginMock.mockRejectedValue(new Error('Login failed'));
139
+ const agent = createAgent();
140
+ const result = await agent.run();
141
+ const finding = result.findings.find(f => f.id.includes('login-failed'));
142
+ expect(finding).toBeDefined();
143
+ expect(finding!.severity).toBe('medium');
144
+ });
145
+
146
+ it('handles playwright crash gracefully', async () => {
147
+ mockBrowser.newPage.mockRejectedValue(new Error('Browser crashed'));
148
+ const agent = createAgent();
149
+ const result = await agent.run();
150
+ const finding = result.findings.find(f => f.id.includes('playwright-failure'));
151
+ expect(finding).toBeDefined();
152
+ });
153
+
154
+ it('handles navigation failure for module', async () => {
155
+ currentMockPage.goto.mockRejectedValue(new Error('Nav failed'));
156
+ const agent = createAgent();
157
+ const result = await agent.run();
158
+ const finding = result.findings.find(f => f.id.includes('nav-failed'));
159
+ expect(finding).toBeDefined();
160
+ });
161
+
162
+ it('checks RTL layout when language switcher found', async () => {
163
+ currentMockPage.locator.mockReturnValue(makeMockLocator(1)); // lang switcher found
164
+ currentMockPage.evaluate
165
+ .mockResolvedValueOnce('Normal text') // body text
166
+ .mockResolvedValueOnce('Normal text') // body text
167
+ .mockResolvedValueOnce('ltr') // document.dir
168
+ .mockResolvedValueOnce('ar'); // document.lang
169
+ const agent = createAgent();
170
+ const result = await agent.run();
171
+ const finding = result.findings.find(f => f.id.includes('rtl-missing'));
172
+ expect(finding).toBeDefined();
173
+ });
174
+
175
+ it('does not report RTL issue when locale is LTR', async () => {
176
+ currentMockPage.locator.mockReturnValue(makeMockLocator(1));
177
+ currentMockPage.evaluate
178
+ .mockResolvedValueOnce('Normal text')
179
+ .mockResolvedValueOnce('Normal text')
180
+ .mockResolvedValueOnce('ltr')
181
+ .mockResolvedValueOnce('en');
182
+ const agent = createAgent();
183
+ const result = await agent.run();
184
+ const finding = result.findings.find(f => f.id.includes('rtl-missing'));
185
+ expect(finding).toBeUndefined();
186
+ });
187
+
188
+ it('closes browser in finally block', async () => {
189
+ mockBrowser.newPage.mockRejectedValue(new Error('Crash'));
190
+ const agent = createAgent();
191
+ await agent.run();
192
+ expect(mockBrowser.close).toHaveBeenCalled();
193
+ });
194
+
195
+ it('continues without credentials when none configured', async () => {
196
+ const config = makeConfig({ auth: { loginUrl: '/login', credentials: {} } });
197
+ const agent = createAgent(config);
198
+ const result = await agent.run();
199
+ expect(result.status).not.toBe('failed');
200
+ });
201
+ });
@@ -0,0 +1,172 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import type { ValidatedConfig } from '../../core/config';
3
+ import type { Phase } from '../../core/types';
4
+
5
+ function makeConfig(overrides: Partial<ValidatedConfig> = {}): ValidatedConfig {
6
+ return {
7
+ schemaVersion: 1, name: 'test',
8
+ auth: { loginUrl: 'http://localhost/login', credentials: { admin: { email: 'a@t.com', password: 's' } } },
9
+ modules: [
10
+ { id: 'dashboard', route: '/dashboard', sidebarIcon: true },
11
+ { id: 'tasks', route: '/tasks', sidebarIcon: true },
12
+ ],
13
+ environments: { alpha: { baseUrl: 'http://localhost:3000', seed: false } },
14
+ portals: [], breakpoints: [], integrations: [], workers: [], workflows: [],
15
+ accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
16
+ tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
17
+ costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' },
18
+ agentClassification: { blocking: [], advisory: [] },
19
+ thresholds: { unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 }, lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 }, apiResponseTime: 2000, bundleSizeLimit: 500000, maxConsoleErrors: 0 },
20
+ disabledAgents: [], disabledAgentSet: new Set<number>(),
21
+ ...overrides,
22
+ };
23
+ }
24
+
25
+ const fetchMock = vi.fn();
26
+ vi.stubGlobal('fetch', fetchMock);
27
+
28
+ const loginMock = vi.fn().mockResolvedValue(undefined);
29
+ vi.mock('../../helpers/navigation', () => ({
30
+ login: (...args: unknown[]) => loginMock(...args),
31
+ waitForSectionLoad: vi.fn().mockResolvedValue(undefined),
32
+ navigateToSection: vi.fn().mockResolvedValue(undefined),
33
+ switchPortal: vi.fn().mockResolvedValue(undefined),
34
+ }));
35
+
36
+ function makeMockPage() {
37
+ return {
38
+ close: vi.fn().mockResolvedValue(undefined),
39
+ goto: vi.fn().mockResolvedValue(undefined),
40
+ evaluate: vi.fn().mockResolvedValue([]),
41
+ locator: vi.fn().mockReturnValue({ count: vi.fn().mockResolvedValue(0), first: vi.fn() }),
42
+ on: vi.fn(),
43
+ };
44
+ }
45
+
46
+ let currentMockPage: ReturnType<typeof makeMockPage>;
47
+ let mockContext: { newPage: ReturnType<typeof vi.fn>; close: ReturnType<typeof vi.fn> };
48
+ let mockBrowser: { newPage: ReturnType<typeof vi.fn>; newContext: ReturnType<typeof vi.fn>; close: ReturnType<typeof vi.fn> };
49
+
50
+ vi.mock('playwright', async () => ({
51
+ chromium: {
52
+ launch: vi.fn().mockImplementation(async () => mockBrowser),
53
+ },
54
+ }));
55
+
56
+ const { TimezoneTesterAgent } = await import('../50-timezone-tester');
57
+
58
+ function createAgent(config: ValidatedConfig = makeConfig(), phase: Phase = 'beta') {
59
+ return new TimezoneTesterAgent(config, phase, '/tmp/test-run');
60
+ }
61
+
62
+ describe('TimezoneTesterAgent', () => {
63
+ beforeEach(() => {
64
+ fetchMock.mockReset().mockResolvedValue({ ok: true, status: 200 });
65
+ loginMock.mockReset().mockResolvedValue(undefined);
66
+ currentMockPage = makeMockPage();
67
+ mockContext = {
68
+ newPage: vi.fn().mockResolvedValue(currentMockPage),
69
+ close: vi.fn().mockResolvedValue(undefined),
70
+ };
71
+ mockBrowser = {
72
+ newPage: vi.fn().mockResolvedValue(currentMockPage),
73
+ newContext: vi.fn().mockResolvedValue(mockContext),
74
+ close: vi.fn().mockResolvedValue(undefined),
75
+ };
76
+ });
77
+
78
+ it('has agentId 50 and correct name', () => {
79
+ const agent = createAgent();
80
+ expect(agent.agentId).toBe(50);
81
+ expect(agent.agentName).toBe('Timezone Tester');
82
+ });
83
+
84
+ it('throws when modules array is empty', async () => {
85
+ const agent = createAgent(makeConfig({ modules: [] }));
86
+ const result = await agent.run();
87
+ expect(result.status).toBe('failed');
88
+ });
89
+
90
+ it('reports no dates found when page has none', async () => {
91
+ currentMockPage.evaluate.mockResolvedValue([]);
92
+ const agent = createAgent();
93
+ const result = await agent.run();
94
+ const finding = result.findings.find(f => f.id.includes('no-dates-found'));
95
+ expect(finding).toBeDefined();
96
+ });
97
+
98
+ it('detects off-by-one date differences', async () => {
99
+ let callCount = 0;
100
+ currentMockPage.evaluate.mockImplementation(async () => {
101
+ callCount++;
102
+ if (callCount === 1) return ['Jan 15, 2025'];
103
+ if (callCount === 2) return ['Jan 16, 2025'];
104
+ if (callCount === 3) return ['Jan 16, 2025'];
105
+ return [];
106
+ });
107
+ const agent = createAgent();
108
+ const result = await agent.run();
109
+ const finding = result.findings.find(f => f.id.includes('off-by-one'));
110
+ expect(finding).toBeDefined();
111
+ });
112
+
113
+ it('handles navigation failure', async () => {
114
+ currentMockPage.goto.mockRejectedValue(new Error('Nav failed'));
115
+ const agent = createAgent();
116
+ const result = await agent.run();
117
+ const finding = result.findings.find(f => f.id.includes('nav-failed'));
118
+ expect(finding).toBeDefined();
119
+ });
120
+
121
+ it('handles playwright crash gracefully', async () => {
122
+ mockBrowser.newContext.mockRejectedValue(new Error('Crash'));
123
+ const agent = createAgent();
124
+ const result = await agent.run();
125
+ const finding = result.findings.find(f => f.id.includes('playwright-failure'));
126
+ expect(finding).toBeDefined();
127
+ });
128
+
129
+ it('reports date count mismatch across timezones', async () => {
130
+ let callCount = 0;
131
+ currentMockPage.evaluate.mockImplementation(async () => {
132
+ callCount++;
133
+ if (callCount === 1) return ['Jan 15', 'Feb 20'];
134
+ if (callCount === 2) return ['Jan 15'];
135
+ return ['Jan 15'];
136
+ });
137
+ const agent = createAgent();
138
+ const result = await agent.run();
139
+ const finding = result.findings.find(f => f.id.includes('date-count-mismatch'));
140
+ expect(finding).toBeDefined();
141
+ });
142
+
143
+ it('closes browser in finally block', async () => {
144
+ mockBrowser.newContext.mockRejectedValue(new Error('Crash'));
145
+ const agent = createAgent();
146
+ await agent.run();
147
+ expect(mockBrowser.close).toHaveBeenCalled();
148
+ });
149
+
150
+ it('handles login failure gracefully', async () => {
151
+ loginMock.mockRejectedValue(new Error('Login failed'));
152
+ currentMockPage.evaluate.mockResolvedValue([]);
153
+ const agent = createAgent();
154
+ const result = await agent.run();
155
+ expect(result.findings).toBeDefined();
156
+ });
157
+
158
+ it('reports same dates as no issue', async () => {
159
+ currentMockPage.evaluate.mockResolvedValue(['Jan 15, 2025']);
160
+ const agent = createAgent();
161
+ const result = await agent.run();
162
+ const offByOne = result.findings.find(f => f.id.includes('off-by-one'));
163
+ expect(offByOne).toBeUndefined();
164
+ });
165
+
166
+ it('handles evaluate failure', async () => {
167
+ currentMockPage.evaluate.mockRejectedValue(new Error('Eval failed'));
168
+ const agent = createAgent();
169
+ const result = await agent.run();
170
+ expect(result.status).toBeDefined();
171
+ });
172
+ });
@@ -0,0 +1,162 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import type { ValidatedConfig } from '../../core/config';
3
+ import type { Phase } from '../../core/types';
4
+
5
+ function makeConfig(overrides: Partial<ValidatedConfig> = {}): ValidatedConfig {
6
+ return {
7
+ schemaVersion: 1, name: 'test',
8
+ auth: { loginUrl: 'http://localhost/login', credentials: { admin: { email: 'a@t.com', password: 's' } } },
9
+ modules: [{ id: 'dashboard', route: '/dashboard', sidebarIcon: true }],
10
+ environments: { alpha: { baseUrl: 'http://localhost:3000', seed: false } },
11
+ portals: [], breakpoints: [], integrations: [], workers: [], workflows: [],
12
+ accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
13
+ tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
14
+ costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' },
15
+ agentClassification: { blocking: [], advisory: [] },
16
+ thresholds: { unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 }, lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 }, apiResponseTime: 2000, bundleSizeLimit: 500000, maxConsoleErrors: 0 },
17
+ disabledAgents: [], disabledAgentSet: new Set<number>(),
18
+ ...overrides,
19
+ };
20
+ }
21
+
22
+ const fetchMock = vi.fn();
23
+ vi.stubGlobal('fetch', fetchMock);
24
+
25
+ const loginMock = vi.fn().mockResolvedValue(undefined);
26
+ vi.mock('../../helpers/navigation', () => ({
27
+ login: (...args: unknown[]) => loginMock(...args),
28
+ waitForSectionLoad: vi.fn().mockResolvedValue(undefined),
29
+ navigateToSection: vi.fn().mockResolvedValue(undefined),
30
+ switchPortal: vi.fn().mockResolvedValue(undefined),
31
+ }));
32
+
33
+ function makeMockLocator(countVal = 0) {
34
+ const loc: Record<string, ReturnType<typeof vi.fn>> = {
35
+ count: vi.fn().mockResolvedValue(countVal),
36
+ first: vi.fn(),
37
+ };
38
+ loc.first.mockReturnValue(loc);
39
+ return loc;
40
+ }
41
+
42
+ function makeMockPage() {
43
+ return {
44
+ close: vi.fn().mockResolvedValue(undefined),
45
+ goto: vi.fn().mockResolvedValue(undefined),
46
+ evaluate: vi.fn().mockResolvedValue('Some content'),
47
+ locator: vi.fn().mockReturnValue(makeMockLocator(0)),
48
+ route: vi.fn().mockResolvedValue(undefined),
49
+ unroute: vi.fn().mockResolvedValue(undefined),
50
+ on: vi.fn(),
51
+ };
52
+ }
53
+
54
+ let currentMockPage: ReturnType<typeof makeMockPage>;
55
+ let mockBrowser: { newPage: ReturnType<typeof vi.fn>; close: ReturnType<typeof vi.fn> };
56
+
57
+ vi.mock('playwright', async () => ({
58
+ chromium: { launch: vi.fn().mockImplementation(async () => mockBrowser) },
59
+ }));
60
+
61
+ const { ErrorRecoveryTesterAgent } = await import('../51-error-recovery-tester');
62
+
63
+ function createAgent(config: ValidatedConfig = makeConfig(), phase: Phase = 'beta') {
64
+ return new ErrorRecoveryTesterAgent(config, phase, '/tmp/test-run');
65
+ }
66
+
67
+ describe('ErrorRecoveryTesterAgent', () => {
68
+ beforeEach(() => {
69
+ fetchMock.mockReset().mockResolvedValue({ ok: true, status: 200 });
70
+ loginMock.mockReset().mockResolvedValue(undefined);
71
+ currentMockPage = makeMockPage();
72
+ mockBrowser = {
73
+ newPage: vi.fn().mockResolvedValue(currentMockPage),
74
+ close: vi.fn().mockResolvedValue(undefined),
75
+ };
76
+ });
77
+
78
+ it('has agentId 51 and correct name', () => {
79
+ const agent = createAgent();
80
+ expect(agent.agentId).toBe(51);
81
+ expect(agent.agentName).toBe('Error Recovery Tester');
82
+ });
83
+
84
+ it('throws when modules empty', async () => {
85
+ const agent = createAgent(makeConfig({ modules: [] }));
86
+ const result = await agent.run();
87
+ expect(result.status).toBe('failed');
88
+ });
89
+
90
+ it('reports blank screen after recovery as high', async () => {
91
+ currentMockPage.evaluate.mockResolvedValue('');
92
+ const agent = createAgent();
93
+ const result = await agent.run();
94
+ const finding = result.findings.find(f => f.id.includes('blank-screen'));
95
+ expect(finding).toBeDefined();
96
+ expect(finding!.severity).toBe('high');
97
+ });
98
+
99
+ it('reports recovery UI as low', async () => {
100
+ currentMockPage.evaluate.mockResolvedValue('Some content after recovery');
101
+ currentMockPage.locator.mockReturnValue(makeMockLocator(1)); // retry button found
102
+ const agent = createAgent();
103
+ const result = await agent.run();
104
+ const finding = result.findings.find(f => f.id.includes('recovery-ui'));
105
+ expect(finding).toBeDefined();
106
+ expect(finding!.severity).toBe('low');
107
+ });
108
+
109
+ it('handles nav failure', async () => {
110
+ currentMockPage.goto.mockRejectedValue(new Error('Nav failed'));
111
+ const agent = createAgent();
112
+ const result = await agent.run();
113
+ const finding = result.findings.find(f => f.id.includes('nav-failed'));
114
+ expect(finding).toBeDefined();
115
+ });
116
+
117
+ it('handles login failure', async () => {
118
+ loginMock.mockRejectedValue(new Error('Login failed'));
119
+ const agent = createAgent();
120
+ const result = await agent.run();
121
+ const finding = result.findings.find(f => f.id.includes('login-failed'));
122
+ expect(finding).toBeDefined();
123
+ });
124
+
125
+ it('handles playwright crash', async () => {
126
+ mockBrowser.newPage.mockRejectedValue(new Error('Crash'));
127
+ const agent = createAgent();
128
+ const result = await agent.run();
129
+ const finding = result.findings.find(f => f.id.includes('playwright-failure'));
130
+ expect(finding).toBeDefined();
131
+ });
132
+
133
+ it('calls route and unroute for offline simulation', async () => {
134
+ currentMockPage.evaluate.mockResolvedValue('Content');
135
+ const agent = createAgent();
136
+ await agent.run();
137
+ expect(currentMockPage.route).toHaveBeenCalledWith('**/*', expect.any(Function));
138
+ expect(currentMockPage.unroute).toHaveBeenCalledWith('**/*', expect.any(Function));
139
+ });
140
+
141
+ it('closes browser in finally', async () => {
142
+ mockBrowser.newPage.mockRejectedValue(new Error('Crash'));
143
+ const agent = createAgent();
144
+ await agent.run();
145
+ expect(mockBrowser.close).toHaveBeenCalled();
146
+ });
147
+
148
+ it('handles evaluate failure in recovery check', async () => {
149
+ currentMockPage.evaluate.mockRejectedValue(new Error('Eval failed'));
150
+ const agent = createAgent();
151
+ const result = await agent.run();
152
+ const finding = result.findings.find(f => f.id.includes('recovery-check-failed'));
153
+ expect(finding).toBeDefined();
154
+ });
155
+
156
+ it('no credentials continues without error', async () => {
157
+ const config = makeConfig({ auth: { loginUrl: '/login', credentials: {} } });
158
+ const agent = createAgent(config);
159
+ const result = await agent.run();
160
+ expect(result.status).toBeDefined();
161
+ });
162
+ });