@avi770/testteam 1.2.0 → 2.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 (300) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/README.md +53 -6
  3. package/agents/24-signup-onboarding-tester.ts +429 -0
  4. package/agents/25-crud-flow-tester.ts +302 -0
  5. package/agents/26-form-validator.ts +297 -0
  6. package/agents/27-search-filter-tester.ts +326 -0
  7. package/agents/28-navigation-routing-tester.ts +425 -0
  8. package/agents/29-responsive-interaction-tester.ts +350 -0
  9. package/agents/30-multi-user-scenario-tester.ts +319 -0
  10. package/agents/31-load-tester.ts +134 -0
  11. package/agents/32-memory-leak-detector.ts +194 -0
  12. package/agents/33-bundle-analyzer.ts +132 -0
  13. package/agents/34-xss-scanner.ts +191 -0
  14. package/agents/35-csrf-tester.ts +82 -0
  15. package/agents/36-auth-fuzzer.ts +194 -0
  16. package/agents/37-dependency-scanner.ts +176 -0
  17. package/agents/38-secrets-scanner.ts +137 -0
  18. package/agents/39-api-contract-tester.ts +199 -0
  19. package/agents/40-rate-limit-tester.ts +94 -0
  20. package/agents/41-api-pagination-tester.ts +97 -0
  21. package/agents/42-graphql-tester.ts +222 -0
  22. package/agents/43-data-consistency-checker.ts +205 -0
  23. package/agents/44-backup-recovery-tester.ts +152 -0
  24. package/agents/45-data-privacy-scanner.ts +125 -0
  25. package/agents/46-seo-auditor.ts +294 -0
  26. package/agents/47-social-preview-tester.ts +232 -0
  27. package/agents/48-lighthouse-auditor.ts +213 -0
  28. package/agents/49-i18n-tester.ts +198 -0
  29. package/agents/50-timezone-tester.ts +173 -0
  30. package/agents/51-error-recovery-tester.ts +155 -0
  31. package/agents/52-offline-mode-tester.ts +180 -0
  32. package/agents/53-graceful-degradation-tester.ts +156 -0
  33. package/agents/54-websocket-tester.ts +151 -0
  34. package/agents/55-realtime-sync-tester.ts +194 -0
  35. package/agents/56-file-upload-tester.ts +194 -0
  36. package/agents/57-export-tester.ts +174 -0
  37. package/agents/58-payment-flow-tester.ts +183 -0
  38. package/agents/59-ssl-tls-auditor.ts +141 -0
  39. package/agents/60-dns-cdn-tester.ts +117 -0
  40. package/agents/61-docker-health-checker.ts +111 -0
  41. package/agents/62-env-config-validator.ts +152 -0
  42. package/agents/63-log-quality-auditor.ts +136 -0
  43. package/agents/64-analytics-tracker-tester.ts +165 -0
  44. package/agents/65-gdpr-compliance-tester.ts +215 -0
  45. package/agents/66-soc2-control-validator.ts +210 -0
  46. package/agents/67-wcag-aaa-tester.ts +241 -0
  47. package/agents/68-dead-code-detector.ts +135 -0
  48. package/agents/69-type-safety-auditor.ts +164 -0
  49. package/agents/70-complexity-analyzer.ts +179 -0
  50. package/agents/__tests__/24-signup-onboarding-tester.test.ts +274 -0
  51. package/agents/__tests__/25-crud-flow-tester.test.ts +322 -0
  52. package/agents/__tests__/26-form-validator.test.ts +345 -0
  53. package/agents/__tests__/27-search-filter-tester.test.ts +311 -0
  54. package/agents/__tests__/28-navigation-routing-tester.test.ts +328 -0
  55. package/agents/__tests__/29-responsive-interaction-tester.test.ts +297 -0
  56. package/agents/__tests__/30-multi-user-scenario-tester.test.ts +328 -0
  57. package/agents/__tests__/31-load-tester.test.ts +189 -0
  58. package/agents/__tests__/32-memory-leak-detector.test.ts +251 -0
  59. package/agents/__tests__/33-bundle-analyzer.test.ts +237 -0
  60. package/agents/__tests__/34-xss-scanner.test.ts +258 -0
  61. package/agents/__tests__/35-csrf-tester.test.ts +200 -0
  62. package/agents/__tests__/36-auth-fuzzer.test.ts +214 -0
  63. package/agents/__tests__/37-dependency-scanner.test.ts +266 -0
  64. package/agents/__tests__/38-secrets-scanner.test.ts +224 -0
  65. package/agents/__tests__/39-api-contract-tester.test.ts +312 -0
  66. package/agents/__tests__/40-rate-limit-tester.test.ts +192 -0
  67. package/agents/__tests__/41-api-pagination-tester.test.ts +198 -0
  68. package/agents/__tests__/42-graphql-tester.test.ts +252 -0
  69. package/agents/__tests__/43-data-consistency-checker.test.ts +232 -0
  70. package/agents/__tests__/44-backup-recovery-tester.test.ts +222 -0
  71. package/agents/__tests__/45-data-privacy-scanner.test.ts +223 -0
  72. package/agents/__tests__/46-seo-auditor.test.ts +261 -0
  73. package/agents/__tests__/47-social-preview-tester.test.ts +245 -0
  74. package/agents/__tests__/48-lighthouse-auditor.test.ts +276 -0
  75. package/agents/__tests__/49-i18n-tester.test.ts +201 -0
  76. package/agents/__tests__/50-timezone-tester.test.ts +172 -0
  77. package/agents/__tests__/51-error-recovery-tester.test.ts +162 -0
  78. package/agents/__tests__/52-offline-mode-tester.test.ts +164 -0
  79. package/agents/__tests__/53-graceful-degradation-tester.test.ts +168 -0
  80. package/agents/__tests__/54-websocket-tester.test.ts +157 -0
  81. package/agents/__tests__/55-realtime-sync-tester.test.ts +181 -0
  82. package/agents/__tests__/56-file-upload-tester.test.ts +172 -0
  83. package/agents/__tests__/57-export-tester.test.ts +169 -0
  84. package/agents/__tests__/58-payment-flow-tester.test.ts +182 -0
  85. package/agents/__tests__/59-ssl-tls-auditor.test.ts +179 -0
  86. package/agents/__tests__/60-dns-cdn-tester.test.ts +176 -0
  87. package/agents/__tests__/61-docker-health-checker.test.ts +150 -0
  88. package/agents/__tests__/62-env-config-validator.test.ts +166 -0
  89. package/agents/__tests__/63-log-quality-auditor.test.ts +175 -0
  90. package/agents/__tests__/64-analytics-tracker-tester.test.ts +158 -0
  91. package/agents/__tests__/65-gdpr-compliance-tester.test.ts +174 -0
  92. package/agents/__tests__/66-soc2-control-validator.test.ts +183 -0
  93. package/agents/__tests__/67-wcag-aaa-tester.test.ts +190 -0
  94. package/agents/__tests__/68-dead-code-detector.test.ts +174 -0
  95. package/agents/__tests__/69-type-safety-auditor.test.ts +173 -0
  96. package/agents/__tests__/70-complexity-analyzer.test.ts +177 -0
  97. package/agents/__tests__/registry.test.ts +13 -13
  98. package/agents/registry.ts +146 -5
  99. package/core/__tests__/integration.test.ts +4 -4
  100. package/core/__tests__/orchestrator.test.ts +17 -16
  101. package/core/license.ts +208 -211
  102. package/core/orchestrator.ts +6 -4
  103. package/dist/agents/24-signup-onboarding-tester.d.ts +35 -0
  104. package/dist/agents/24-signup-onboarding-tester.d.ts.map +1 -0
  105. package/dist/agents/24-signup-onboarding-tester.js +357 -0
  106. package/dist/agents/24-signup-onboarding-tester.js.map +1 -0
  107. package/dist/agents/25-crud-flow-tester.d.ts +11 -0
  108. package/dist/agents/25-crud-flow-tester.d.ts.map +1 -0
  109. package/dist/agents/25-crud-flow-tester.js +253 -0
  110. package/dist/agents/25-crud-flow-tester.js.map +1 -0
  111. package/dist/agents/26-form-validator.d.ts +12 -0
  112. package/dist/agents/26-form-validator.d.ts.map +1 -0
  113. package/dist/agents/26-form-validator.js +257 -0
  114. package/dist/agents/26-form-validator.js.map +1 -0
  115. package/dist/agents/27-search-filter-tester.d.ts +20 -0
  116. package/dist/agents/27-search-filter-tester.d.ts.map +1 -0
  117. package/dist/agents/27-search-filter-tester.js +267 -0
  118. package/dist/agents/27-search-filter-tester.js.map +1 -0
  119. package/dist/agents/28-navigation-routing-tester.d.ts +32 -0
  120. package/dist/agents/28-navigation-routing-tester.d.ts.map +1 -0
  121. package/dist/agents/28-navigation-routing-tester.js +363 -0
  122. package/dist/agents/28-navigation-routing-tester.js.map +1 -0
  123. package/dist/agents/29-responsive-interaction-tester.d.ts +26 -0
  124. package/dist/agents/29-responsive-interaction-tester.d.ts.map +1 -0
  125. package/dist/agents/29-responsive-interaction-tester.js +272 -0
  126. package/dist/agents/29-responsive-interaction-tester.js.map +1 -0
  127. package/dist/agents/30-multi-user-scenario-tester.d.ts +24 -0
  128. package/dist/agents/30-multi-user-scenario-tester.d.ts.map +1 -0
  129. package/dist/agents/30-multi-user-scenario-tester.js +254 -0
  130. package/dist/agents/30-multi-user-scenario-tester.js.map +1 -0
  131. package/dist/agents/31-load-tester.d.ts +12 -0
  132. package/dist/agents/31-load-tester.d.ts.map +1 -0
  133. package/dist/agents/31-load-tester.js +110 -0
  134. package/dist/agents/31-load-tester.js.map +1 -0
  135. package/dist/agents/32-memory-leak-detector.d.ts +12 -0
  136. package/dist/agents/32-memory-leak-detector.d.ts.map +1 -0
  137. package/dist/agents/32-memory-leak-detector.js +167 -0
  138. package/dist/agents/32-memory-leak-detector.js.map +1 -0
  139. package/dist/agents/33-bundle-analyzer.d.ts +10 -0
  140. package/dist/agents/33-bundle-analyzer.d.ts.map +1 -0
  141. package/dist/agents/33-bundle-analyzer.js +111 -0
  142. package/dist/agents/33-bundle-analyzer.js.map +1 -0
  143. package/dist/agents/34-xss-scanner.d.ts +11 -0
  144. package/dist/agents/34-xss-scanner.d.ts.map +1 -0
  145. package/dist/agents/34-xss-scanner.js +164 -0
  146. package/dist/agents/34-xss-scanner.js.map +1 -0
  147. package/dist/agents/35-csrf-tester.d.ts +11 -0
  148. package/dist/agents/35-csrf-tester.d.ts.map +1 -0
  149. package/dist/agents/35-csrf-tester.js +70 -0
  150. package/dist/agents/35-csrf-tester.js.map +1 -0
  151. package/dist/agents/36-auth-fuzzer.d.ts +13 -0
  152. package/dist/agents/36-auth-fuzzer.d.ts.map +1 -0
  153. package/dist/agents/36-auth-fuzzer.js +163 -0
  154. package/dist/agents/36-auth-fuzzer.js.map +1 -0
  155. package/dist/agents/37-dependency-scanner.d.ts +11 -0
  156. package/dist/agents/37-dependency-scanner.d.ts.map +1 -0
  157. package/dist/agents/37-dependency-scanner.js +139 -0
  158. package/dist/agents/37-dependency-scanner.js.map +1 -0
  159. package/dist/agents/38-secrets-scanner.d.ts +11 -0
  160. package/dist/agents/38-secrets-scanner.d.ts.map +1 -0
  161. package/dist/agents/38-secrets-scanner.js +116 -0
  162. package/dist/agents/38-secrets-scanner.js.map +1 -0
  163. package/dist/agents/39-api-contract-tester.d.ts +12 -0
  164. package/dist/agents/39-api-contract-tester.d.ts.map +1 -0
  165. package/dist/agents/39-api-contract-tester.js +142 -0
  166. package/dist/agents/39-api-contract-tester.js.map +1 -0
  167. package/dist/agents/40-rate-limit-tester.d.ts +12 -0
  168. package/dist/agents/40-rate-limit-tester.d.ts.map +1 -0
  169. package/dist/agents/40-rate-limit-tester.js +79 -0
  170. package/dist/agents/40-rate-limit-tester.js.map +1 -0
  171. package/dist/agents/41-api-pagination-tester.d.ts +12 -0
  172. package/dist/agents/41-api-pagination-tester.d.ts.map +1 -0
  173. package/dist/agents/41-api-pagination-tester.js +79 -0
  174. package/dist/agents/41-api-pagination-tester.js.map +1 -0
  175. package/dist/agents/42-graphql-tester.d.ts +13 -0
  176. package/dist/agents/42-graphql-tester.d.ts.map +1 -0
  177. package/dist/agents/42-graphql-tester.js +187 -0
  178. package/dist/agents/42-graphql-tester.js.map +1 -0
  179. package/dist/agents/43-data-consistency-checker.d.ts +11 -0
  180. package/dist/agents/43-data-consistency-checker.d.ts.map +1 -0
  181. package/dist/agents/43-data-consistency-checker.js +176 -0
  182. package/dist/agents/43-data-consistency-checker.js.map +1 -0
  183. package/dist/agents/44-backup-recovery-tester.d.ts +11 -0
  184. package/dist/agents/44-backup-recovery-tester.d.ts.map +1 -0
  185. package/dist/agents/44-backup-recovery-tester.js +128 -0
  186. package/dist/agents/44-backup-recovery-tester.js.map +1 -0
  187. package/dist/agents/45-data-privacy-scanner.d.ts +11 -0
  188. package/dist/agents/45-data-privacy-scanner.d.ts.map +1 -0
  189. package/dist/agents/45-data-privacy-scanner.js +100 -0
  190. package/dist/agents/45-data-privacy-scanner.js.map +1 -0
  191. package/dist/agents/46-seo-auditor.d.ts +12 -0
  192. package/dist/agents/46-seo-auditor.d.ts.map +1 -0
  193. package/dist/agents/46-seo-auditor.js +275 -0
  194. package/dist/agents/46-seo-auditor.js.map +1 -0
  195. package/dist/agents/47-social-preview-tester.d.ts +11 -0
  196. package/dist/agents/47-social-preview-tester.d.ts.map +1 -0
  197. package/dist/agents/47-social-preview-tester.js +219 -0
  198. package/dist/agents/47-social-preview-tester.js.map +1 -0
  199. package/dist/agents/48-lighthouse-auditor.d.ts +11 -0
  200. package/dist/agents/48-lighthouse-auditor.d.ts.map +1 -0
  201. package/dist/agents/48-lighthouse-auditor.js +192 -0
  202. package/dist/agents/48-lighthouse-auditor.js.map +1 -0
  203. package/dist/agents/49-i18n-tester.d.ts +13 -0
  204. package/dist/agents/49-i18n-tester.d.ts.map +1 -0
  205. package/dist/agents/49-i18n-tester.js +172 -0
  206. package/dist/agents/49-i18n-tester.js.map +1 -0
  207. package/dist/agents/50-timezone-tester.d.ts +11 -0
  208. package/dist/agents/50-timezone-tester.d.ts.map +1 -0
  209. package/dist/agents/50-timezone-tester.js +152 -0
  210. package/dist/agents/50-timezone-tester.js.map +1 -0
  211. package/dist/agents/51-error-recovery-tester.d.ts +11 -0
  212. package/dist/agents/51-error-recovery-tester.d.ts.map +1 -0
  213. package/dist/agents/51-error-recovery-tester.js +134 -0
  214. package/dist/agents/51-error-recovery-tester.js.map +1 -0
  215. package/dist/agents/52-offline-mode-tester.d.ts +12 -0
  216. package/dist/agents/52-offline-mode-tester.d.ts.map +1 -0
  217. package/dist/agents/52-offline-mode-tester.js +161 -0
  218. package/dist/agents/52-offline-mode-tester.js.map +1 -0
  219. package/dist/agents/53-graceful-degradation-tester.d.ts +12 -0
  220. package/dist/agents/53-graceful-degradation-tester.d.ts.map +1 -0
  221. package/dist/agents/53-graceful-degradation-tester.js +130 -0
  222. package/dist/agents/53-graceful-degradation-tester.js.map +1 -0
  223. package/dist/agents/54-websocket-tester.d.ts +10 -0
  224. package/dist/agents/54-websocket-tester.d.ts.map +1 -0
  225. package/dist/agents/54-websocket-tester.js +132 -0
  226. package/dist/agents/54-websocket-tester.js.map +1 -0
  227. package/dist/agents/55-realtime-sync-tester.d.ts +11 -0
  228. package/dist/agents/55-realtime-sync-tester.d.ts.map +1 -0
  229. package/dist/agents/55-realtime-sync-tester.js +175 -0
  230. package/dist/agents/55-realtime-sync-tester.js.map +1 -0
  231. package/dist/agents/56-file-upload-tester.d.ts +12 -0
  232. package/dist/agents/56-file-upload-tester.d.ts.map +1 -0
  233. package/dist/agents/56-file-upload-tester.js +166 -0
  234. package/dist/agents/56-file-upload-tester.js.map +1 -0
  235. package/dist/agents/57-export-tester.d.ts +11 -0
  236. package/dist/agents/57-export-tester.d.ts.map +1 -0
  237. package/dist/agents/57-export-tester.js +155 -0
  238. package/dist/agents/57-export-tester.js.map +1 -0
  239. package/dist/agents/58-payment-flow-tester.d.ts +11 -0
  240. package/dist/agents/58-payment-flow-tester.d.ts.map +1 -0
  241. package/dist/agents/58-payment-flow-tester.js +159 -0
  242. package/dist/agents/58-payment-flow-tester.js.map +1 -0
  243. package/dist/agents/59-ssl-tls-auditor.d.ts +10 -0
  244. package/dist/agents/59-ssl-tls-auditor.d.ts.map +1 -0
  245. package/dist/agents/59-ssl-tls-auditor.js +132 -0
  246. package/dist/agents/59-ssl-tls-auditor.js.map +1 -0
  247. package/dist/agents/60-dns-cdn-tester.d.ts +10 -0
  248. package/dist/agents/60-dns-cdn-tester.d.ts.map +1 -0
  249. package/dist/agents/60-dns-cdn-tester.js +105 -0
  250. package/dist/agents/60-dns-cdn-tester.js.map +1 -0
  251. package/dist/agents/61-docker-health-checker.d.ts +10 -0
  252. package/dist/agents/61-docker-health-checker.d.ts.map +1 -0
  253. package/dist/agents/61-docker-health-checker.js +95 -0
  254. package/dist/agents/61-docker-health-checker.js.map +1 -0
  255. package/dist/agents/62-env-config-validator.d.ts +10 -0
  256. package/dist/agents/62-env-config-validator.d.ts.map +1 -0
  257. package/dist/agents/62-env-config-validator.js +132 -0
  258. package/dist/agents/62-env-config-validator.js.map +1 -0
  259. package/dist/agents/63-log-quality-auditor.d.ts +9 -0
  260. package/dist/agents/63-log-quality-auditor.d.ts.map +1 -0
  261. package/dist/agents/63-log-quality-auditor.js +121 -0
  262. package/dist/agents/63-log-quality-auditor.js.map +1 -0
  263. package/dist/agents/64-analytics-tracker-tester.d.ts +10 -0
  264. package/dist/agents/64-analytics-tracker-tester.d.ts.map +1 -0
  265. package/dist/agents/64-analytics-tracker-tester.js +146 -0
  266. package/dist/agents/64-analytics-tracker-tester.js.map +1 -0
  267. package/dist/agents/65-gdpr-compliance-tester.d.ts +13 -0
  268. package/dist/agents/65-gdpr-compliance-tester.d.ts.map +1 -0
  269. package/dist/agents/65-gdpr-compliance-tester.js +186 -0
  270. package/dist/agents/65-gdpr-compliance-tester.js.map +1 -0
  271. package/dist/agents/66-soc2-control-validator.d.ts +14 -0
  272. package/dist/agents/66-soc2-control-validator.d.ts.map +1 -0
  273. package/dist/agents/66-soc2-control-validator.js +178 -0
  274. package/dist/agents/66-soc2-control-validator.js.map +1 -0
  275. package/dist/agents/67-wcag-aaa-tester.d.ts +13 -0
  276. package/dist/agents/67-wcag-aaa-tester.d.ts.map +1 -0
  277. package/dist/agents/67-wcag-aaa-tester.js +207 -0
  278. package/dist/agents/67-wcag-aaa-tester.js.map +1 -0
  279. package/dist/agents/68-dead-code-detector.d.ts +9 -0
  280. package/dist/agents/68-dead-code-detector.d.ts.map +1 -0
  281. package/dist/agents/68-dead-code-detector.js +116 -0
  282. package/dist/agents/68-dead-code-detector.js.map +1 -0
  283. package/dist/agents/69-type-safety-auditor.d.ts +9 -0
  284. package/dist/agents/69-type-safety-auditor.d.ts.map +1 -0
  285. package/dist/agents/69-type-safety-auditor.js +148 -0
  286. package/dist/agents/69-type-safety-auditor.js.map +1 -0
  287. package/dist/agents/70-complexity-analyzer.d.ts +10 -0
  288. package/dist/agents/70-complexity-analyzer.d.ts.map +1 -0
  289. package/dist/agents/70-complexity-analyzer.js +154 -0
  290. package/dist/agents/70-complexity-analyzer.js.map +1 -0
  291. package/dist/agents/registry.d.ts +3 -3
  292. package/dist/agents/registry.d.ts.map +1 -1
  293. package/dist/agents/registry.js +146 -5
  294. package/dist/agents/registry.js.map +1 -1
  295. package/dist/core/license.js +2 -5
  296. package/dist/core/license.js.map +1 -1
  297. package/dist/core/orchestrator.d.ts.map +1 -1
  298. package/dist/core/orchestrator.js +6 -4
  299. package/dist/core/orchestrator.js.map +1 -1
  300. package/package.json +2 -2
@@ -0,0 +1,186 @@
1
+ import { BaseAgent } from './base-agent';
2
+ import { resolveEnvironment } from '../helpers/env-resolver';
3
+ import { login } from '../helpers/navigation';
4
+ /** Keywords that indicate cookie consent banner. */
5
+ const CONSENT_KEYWORDS = ['cookie', 'consent', 'privacy', 'gdpr', 'accept all', 'accept cookies'];
6
+ /** Common privacy policy link selectors. */
7
+ const PRIVACY_LINK_SELECTORS = [
8
+ 'a:has-text("Privacy")',
9
+ 'a:has-text("Privacy Policy")',
10
+ 'a[href*="privacy"]',
11
+ 'a[href*="datenschutz"]',
12
+ ];
13
+ export class GdprComplianceTesterAgent extends BaseAgent {
14
+ agentId = 65;
15
+ agentName = 'GDPR Compliance Tester';
16
+ baseUrl = '';
17
+ async preFlight() {
18
+ const { env } = await resolveEnvironment(this.config, this.phase);
19
+ this.baseUrl = env.baseUrl;
20
+ }
21
+ async execute() {
22
+ const findings = [];
23
+ const rawLoginUrl = this.config.auth.loginUrl ?? '/login';
24
+ const loginUrl = rawLoginUrl.startsWith('http') ? rawLoginUrl : `${this.baseUrl}${rawLoginUrl}`;
25
+ const credentials = this.config.auth.credentials?.['admin'] ??
26
+ Object.values(this.config.auth.credentials ?? {})[0];
27
+ const { chromium } = await import('playwright');
28
+ let browser = null;
29
+ try {
30
+ browser = await chromium.launch({ headless: true });
31
+ // Test 1: Cookie consent banner (fresh context, no previous cookies)
32
+ const freshContext = await browser.newContext();
33
+ const freshPage = await freshContext.newPage();
34
+ try {
35
+ await freshPage.goto(this.baseUrl, { waitUntil: 'domcontentloaded', timeout: 10_000 });
36
+ await new Promise(resolve => setTimeout(resolve, 2_000));
37
+ const consentFindings = await this.checkCookieConsent(freshPage);
38
+ findings.push(...consentFindings);
39
+ }
40
+ catch {
41
+ findings.push({
42
+ id: `${this.agentId}-nav-failed`,
43
+ type: 'infra-issue',
44
+ severity: 'medium',
45
+ agentId: this.agentId,
46
+ module: 'gdpr-compliance-tester',
47
+ description: 'Failed to navigate to base URL for GDPR testing',
48
+ });
49
+ }
50
+ await freshPage.close().catch(() => undefined);
51
+ await freshContext.close().catch(() => undefined);
52
+ // Test 2: Privacy policy link
53
+ const page = await browser.newPage();
54
+ try {
55
+ await page.goto(this.baseUrl, { waitUntil: 'domcontentloaded', timeout: 10_000 });
56
+ const privacyFindings = await this.checkPrivacyPolicy(page);
57
+ findings.push(...privacyFindings);
58
+ }
59
+ catch {
60
+ // Already reported nav failure
61
+ }
62
+ // Test 3: Delete account option (requires login)
63
+ if (credentials) {
64
+ try {
65
+ await login(page, credentials, loginUrl);
66
+ const deleteAccountFindings = await this.checkDeleteAccount(page);
67
+ findings.push(...deleteAccountFindings);
68
+ }
69
+ catch {
70
+ findings.push({
71
+ id: `${this.agentId}-login-failed`,
72
+ type: 'infra-issue',
73
+ severity: 'low',
74
+ agentId: this.agentId,
75
+ module: 'gdpr-compliance-tester',
76
+ description: 'Login failed — cannot check delete account option',
77
+ });
78
+ }
79
+ }
80
+ await page.close().catch(() => undefined);
81
+ }
82
+ catch (playwrightError) {
83
+ findings.push({
84
+ id: `${this.agentId}-playwright-failure`,
85
+ type: 'infra-issue',
86
+ severity: 'medium',
87
+ agentId: this.agentId,
88
+ module: 'gdpr-compliance-tester',
89
+ description: `Playwright execution failed: ${playwrightError instanceof Error ? playwrightError.message.split('\n')[0] : String(playwrightError)}`,
90
+ });
91
+ }
92
+ finally {
93
+ if (browser)
94
+ await browser.close().catch(() => undefined);
95
+ }
96
+ return findings;
97
+ }
98
+ async checkCookieConsent(page) {
99
+ const findings = [];
100
+ try {
101
+ const bodyText = await page.evaluate(() => document.body.innerText.toLowerCase());
102
+ const hasConsentText = CONSENT_KEYWORDS.some(keyword => bodyText.includes(keyword));
103
+ if (!hasConsentText) {
104
+ findings.push({
105
+ id: `${this.agentId}-no-cookie-consent`,
106
+ type: 'code-bug-security',
107
+ severity: 'high',
108
+ agentId: this.agentId,
109
+ module: 'gdpr-compliance-tester',
110
+ description: 'No cookie consent banner detected on first visit',
111
+ suggestedFix: 'Implement a cookie consent banner that appears on first visit',
112
+ });
113
+ }
114
+ else {
115
+ // Check for accept button
116
+ const acceptBtn = await page.locator('button:has-text("Accept"), button:has-text("Agree"), button:has-text("OK"), button:has-text("Got it")').count();
117
+ if (acceptBtn === 0) {
118
+ findings.push({
119
+ id: `${this.agentId}-no-consent-button`,
120
+ type: 'code-bug-security',
121
+ severity: 'medium',
122
+ agentId: this.agentId,
123
+ module: 'gdpr-compliance-tester',
124
+ description: 'Cookie consent text found but no accept/agree button detected',
125
+ });
126
+ }
127
+ }
128
+ }
129
+ catch {
130
+ // Evaluation failed
131
+ }
132
+ return findings;
133
+ }
134
+ async checkPrivacyPolicy(page) {
135
+ const findings = [];
136
+ const selector = PRIVACY_LINK_SELECTORS.join(', ');
137
+ const privacyLinkCount = await page.locator(selector).count();
138
+ if (privacyLinkCount === 0) {
139
+ findings.push({
140
+ id: `${this.agentId}-no-privacy-policy`,
141
+ type: 'code-bug-security',
142
+ severity: 'medium',
143
+ agentId: this.agentId,
144
+ module: 'gdpr-compliance-tester',
145
+ description: 'No privacy policy link found on the page',
146
+ suggestedFix: 'Add a privacy policy link accessible from the main page',
147
+ });
148
+ }
149
+ return findings;
150
+ }
151
+ async checkDeleteAccount(page) {
152
+ const findings = [];
153
+ // Try settings/account pages
154
+ const settingsRoutes = ['/settings', '/account', '/profile', '/settings/account'];
155
+ for (const route of settingsRoutes) {
156
+ try {
157
+ await page.goto(`${this.baseUrl}${route}`, { waitUntil: 'domcontentloaded', timeout: 5_000 });
158
+ const deleteText = await page.evaluate(() => {
159
+ const body = document.body.innerText.toLowerCase();
160
+ return body.includes('delete account') || body.includes('remove account') || body.includes('close account');
161
+ });
162
+ if (deleteText) {
163
+ this.addEvidence({
164
+ type: 'log',
165
+ path: '',
166
+ description: `Delete account option found at ${route}`,
167
+ });
168
+ return findings;
169
+ }
170
+ }
171
+ catch {
172
+ // Route not found — try next
173
+ }
174
+ }
175
+ findings.push({
176
+ id: `${this.agentId}-no-delete-account`,
177
+ type: 'test-bug',
178
+ severity: 'medium',
179
+ agentId: this.agentId,
180
+ module: 'gdpr-compliance-tester',
181
+ description: 'No "Delete account" option found in settings — GDPR right to erasure may not be accessible',
182
+ });
183
+ return findings;
184
+ }
185
+ }
186
+ //# sourceMappingURL=65-gdpr-compliance-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"65-gdpr-compliance-tester.js","sourceRoot":"","sources":["../../agents/65-gdpr-compliance-tester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Finding } from '../core/types';
2
+ import { BaseAgent } from './base-agent';
3
+ export declare class Soc2ControlValidatorAgent extends BaseAgent {
4
+ readonly agentId = 66;
5
+ readonly agentName = "SOC2 Control Validator";
6
+ private baseUrl;
7
+ protected preFlight(): Promise<void>;
8
+ protected execute(): Promise<Finding[]>;
9
+ private checkAuditLogging;
10
+ private checkSessionTimeout;
11
+ private checkMfaUI;
12
+ private checkRoleBasedAccess;
13
+ }
14
+ //# sourceMappingURL=66-soc2-control-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"66-soc2-control-validator.d.ts","sourceRoot":"","sources":["../../agents/66-soc2-control-validator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAmBzC,qBAAa,yBAA0B,SAAQ,SAAS;IACtD,QAAQ,CAAC,OAAO,MAAM;IACtB,QAAQ,CAAC,SAAS,4BAA4B;IAC9C,OAAO,CAAC,OAAO,CAAM;cAEL,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;cAK1B,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAyB7C,OAAO,CAAC,iBAAiB;IA8CzB,OAAO,CAAC,mBAAmB;YA+Bb,UAAU;IA4CxB,OAAO,CAAC,oBAAoB;CA8B7B"}
@@ -0,0 +1,178 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { BaseAgent } from './base-agent';
4
+ import { resolveEnvironment } from '../helpers/env-resolver';
5
+ /** Glob-like manual scan for .ts files under src/. */
6
+ function findTsFiles(dir, results = []) {
7
+ if (!fs.existsSync(dir))
8
+ return results;
9
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
10
+ for (const entry of entries) {
11
+ const fullPath = path.join(dir, entry.name);
12
+ if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git') {
13
+ findTsFiles(fullPath, results);
14
+ }
15
+ else if (entry.isFile() && entry.name.endsWith('.ts')) {
16
+ results.push(fullPath);
17
+ }
18
+ }
19
+ return results;
20
+ }
21
+ export class Soc2ControlValidatorAgent extends BaseAgent {
22
+ agentId = 66;
23
+ agentName = 'SOC2 Control Validator';
24
+ baseUrl = '';
25
+ async preFlight() {
26
+ const { env } = await resolveEnvironment(this.config, this.phase);
27
+ this.baseUrl = env.baseUrl;
28
+ }
29
+ async execute() {
30
+ const findings = [];
31
+ const projectRoot = this.config.projectRoot ?? process.cwd();
32
+ const srcDir = path.join(projectRoot, 'src');
33
+ // Check 1: Audit logging evidence
34
+ const auditFindings = this.checkAuditLogging(srcDir);
35
+ findings.push(...auditFindings);
36
+ // Check 2: Session timeout
37
+ const sessionFindings = this.checkSessionTimeout(srcDir);
38
+ findings.push(...sessionFindings);
39
+ // Check 3: MFA UI
40
+ const mfaFindings = await this.checkMfaUI();
41
+ findings.push(...mfaFindings);
42
+ // Check 4: Role-based access
43
+ const rbacFindings = this.checkRoleBasedAccess(srcDir);
44
+ findings.push(...rbacFindings);
45
+ return findings;
46
+ }
47
+ checkAuditLogging(srcDir) {
48
+ const findings = [];
49
+ if (!fs.existsSync(srcDir)) {
50
+ findings.push({
51
+ id: `${this.agentId}-no-src`,
52
+ type: 'infra-issue',
53
+ severity: 'low',
54
+ agentId: this.agentId,
55
+ module: 'soc2-control-validator',
56
+ description: 'No src/ directory found — cannot check for audit logging',
57
+ });
58
+ return findings;
59
+ }
60
+ const tsFiles = findTsFiles(srcDir);
61
+ let hasAuditLogging = false;
62
+ for (const filePath of tsFiles) {
63
+ const content = fs.readFileSync(filePath, 'utf-8');
64
+ if (/audit/i.test(content) && (/log/i.test(content) || /trail/i.test(content) || /event/i.test(content))) {
65
+ hasAuditLogging = true;
66
+ this.addEvidence({
67
+ type: 'log',
68
+ path: filePath,
69
+ description: 'Audit logging evidence found',
70
+ });
71
+ break;
72
+ }
73
+ }
74
+ if (!hasAuditLogging) {
75
+ findings.push({
76
+ id: `${this.agentId}-no-audit-logging`,
77
+ type: 'code-bug-security',
78
+ severity: 'medium',
79
+ agentId: this.agentId,
80
+ module: 'soc2-control-validator',
81
+ description: 'No audit logging evidence found in source code',
82
+ suggestedFix: 'Implement audit logging for security-relevant events',
83
+ });
84
+ }
85
+ return findings;
86
+ }
87
+ checkSessionTimeout(srcDir) {
88
+ const findings = [];
89
+ if (!fs.existsSync(srcDir))
90
+ return findings;
91
+ const tsFiles = findTsFiles(srcDir);
92
+ let hasSessionTimeout = false;
93
+ for (const filePath of tsFiles) {
94
+ const content = fs.readFileSync(filePath, 'utf-8');
95
+ if (/sessionTimeout/i.test(content) || /session.*timeout/i.test(content) || /setTimeout.*session/i.test(content) || /idle.*timeout/i.test(content)) {
96
+ hasSessionTimeout = true;
97
+ break;
98
+ }
99
+ }
100
+ if (!hasSessionTimeout) {
101
+ findings.push({
102
+ id: `${this.agentId}-no-session-timeout`,
103
+ type: 'code-bug-security',
104
+ severity: 'medium',
105
+ agentId: this.agentId,
106
+ module: 'soc2-control-validator',
107
+ description: 'No session timeout configuration found in source code',
108
+ suggestedFix: 'Implement session timeout to auto-logout inactive users',
109
+ });
110
+ }
111
+ return findings;
112
+ }
113
+ async checkMfaUI() {
114
+ const findings = [];
115
+ try {
116
+ const { chromium } = await import('playwright');
117
+ let browser = null;
118
+ try {
119
+ browser = await chromium.launch({ headless: true });
120
+ const page = await browser.newPage();
121
+ await page.goto(this.baseUrl, { waitUntil: 'domcontentloaded', timeout: 10_000 });
122
+ const bodyText = await page.evaluate(() => document.body.innerText.toLowerCase());
123
+ const hasMfaUI = bodyText.includes('two-factor') ||
124
+ bodyText.includes('2fa') ||
125
+ bodyText.includes('mfa') ||
126
+ bodyText.includes('multi-factor') ||
127
+ bodyText.includes('authenticator');
128
+ if (!hasMfaUI) {
129
+ findings.push({
130
+ id: `${this.agentId}-no-mfa`,
131
+ type: 'code-bug-security',
132
+ severity: 'medium',
133
+ agentId: this.agentId,
134
+ module: 'soc2-control-validator',
135
+ description: 'No MFA/2FA UI elements detected',
136
+ suggestedFix: 'Implement multi-factor authentication for SOC2 compliance',
137
+ });
138
+ }
139
+ await page.close().catch(() => undefined);
140
+ }
141
+ finally {
142
+ if (browser)
143
+ await browser.close().catch(() => undefined);
144
+ }
145
+ }
146
+ catch {
147
+ // Playwright not available — skip MFA UI check
148
+ }
149
+ return findings;
150
+ }
151
+ checkRoleBasedAccess(srcDir) {
152
+ const findings = [];
153
+ if (!fs.existsSync(srcDir))
154
+ return findings;
155
+ const tsFiles = findTsFiles(srcDir);
156
+ let hasRbac = false;
157
+ for (const filePath of tsFiles) {
158
+ const content = fs.readFileSync(filePath, 'utf-8');
159
+ if (/role/i.test(content) && (/guard/i.test(content) || /permission/i.test(content) || /authorize/i.test(content) || /access/i.test(content))) {
160
+ hasRbac = true;
161
+ break;
162
+ }
163
+ }
164
+ if (!hasRbac) {
165
+ findings.push({
166
+ id: `${this.agentId}-no-rbac`,
167
+ type: 'code-bug-security',
168
+ severity: 'medium',
169
+ agentId: this.agentId,
170
+ module: 'soc2-control-validator',
171
+ description: 'No role-based access control evidence found in source code',
172
+ suggestedFix: 'Implement RBAC with role checks on protected resources',
173
+ });
174
+ }
175
+ return findings;
176
+ }
177
+ }
178
+ //# sourceMappingURL=66-soc2-control-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"66-soc2-control-validator.js","sourceRoot":"","sources":["../../agents/66-soc2-control-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Finding } from '../core/types';
2
+ import { BaseAgent } from './base-agent';
3
+ export declare class WcagAaaTesterAgent extends BaseAgent {
4
+ readonly agentId = 67;
5
+ readonly agentName = "WCAG AAA Tester";
6
+ private baseUrl;
7
+ protected preFlight(): Promise<void>;
8
+ protected execute(): Promise<Finding[]>;
9
+ private checkContrast;
10
+ private checkTextResize;
11
+ private checkKeyboardNavigation;
12
+ }
13
+ //# sourceMappingURL=67-wcag-aaa-tester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"67-wcag-aaa-tester.d.ts","sourceRoot":"","sources":["../../agents/67-wcag-aaa-tester.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,OAAO,MAAM;IACtB,QAAQ,CAAC,SAAS,qBAAqB;IACvC,OAAO,CAAC,OAAO,CAAM;cAEL,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;cAS1B,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAyE/B,aAAa;YA0Db,eAAe;YAkCf,uBAAuB;CAuDtC"}
@@ -0,0 +1,207 @@
1
+ import { BaseAgent } from './base-agent';
2
+ import { resolveEnvironment } from '../helpers/env-resolver';
3
+ import { login } from '../helpers/navigation';
4
+ export class WcagAaaTesterAgent extends BaseAgent {
5
+ agentId = 67;
6
+ agentName = 'WCAG AAA Tester';
7
+ baseUrl = '';
8
+ async preFlight() {
9
+ if (!this.config.modules || this.config.modules.length === 0) {
10
+ throw new Error('WcagAaaTesterAgent requires at least one module in config.modules');
11
+ }
12
+ const { env } = await resolveEnvironment(this.config, this.phase);
13
+ this.baseUrl = env.baseUrl;
14
+ }
15
+ async execute() {
16
+ const findings = [];
17
+ const rawLoginUrl = this.config.auth.loginUrl ?? '/login';
18
+ const loginUrl = rawLoginUrl.startsWith('http') ? rawLoginUrl : `${this.baseUrl}${rawLoginUrl}`;
19
+ const credentials = this.config.auth.credentials?.['admin'] ??
20
+ Object.values(this.config.auth.credentials ?? {})[0];
21
+ const { chromium } = await import('playwright');
22
+ let browser = null;
23
+ try {
24
+ browser = await chromium.launch({ headless: true });
25
+ const page = await browser.newPage();
26
+ if (credentials) {
27
+ try {
28
+ await login(page, credentials, loginUrl);
29
+ }
30
+ catch {
31
+ findings.push({
32
+ id: `${this.agentId}-login-failed`,
33
+ type: 'infra-issue',
34
+ severity: 'medium',
35
+ agentId: this.agentId,
36
+ module: 'wcag-aaa-tester',
37
+ description: 'Login failed — continuing anonymously',
38
+ });
39
+ }
40
+ }
41
+ for (const mod of this.config.modules) {
42
+ const fullUrl = mod.route.startsWith('http')
43
+ ? mod.route
44
+ : `${this.baseUrl}${mod.route}`;
45
+ try {
46
+ await page.goto(fullUrl, { waitUntil: 'domcontentloaded', timeout: 10_000 });
47
+ }
48
+ catch {
49
+ continue;
50
+ }
51
+ // Test 1: Text contrast ratio >= 7:1 (AAA)
52
+ const contrastFindings = await this.checkContrast(page, mod.id);
53
+ findings.push(...contrastFindings);
54
+ // Test 2: Text resizable to 200%
55
+ const resizeFindings = await this.checkTextResize(page, mod.id);
56
+ findings.push(...resizeFindings);
57
+ // Test 3: Keyboard navigation
58
+ const keyboardFindings = await this.checkKeyboardNavigation(page, mod.id);
59
+ findings.push(...keyboardFindings);
60
+ }
61
+ await page.close().catch(() => undefined);
62
+ }
63
+ catch (playwrightError) {
64
+ findings.push({
65
+ id: `${this.agentId}-playwright-failure`,
66
+ type: 'infra-issue',
67
+ severity: 'medium',
68
+ agentId: this.agentId,
69
+ module: 'wcag-aaa-tester',
70
+ description: `Playwright execution failed: ${playwrightError instanceof Error ? playwrightError.message.split('\n')[0] : String(playwrightError)}`,
71
+ });
72
+ }
73
+ finally {
74
+ if (browser)
75
+ await browser.close().catch(() => undefined);
76
+ }
77
+ return findings;
78
+ }
79
+ async checkContrast(page, moduleId) {
80
+ const findings = [];
81
+ try {
82
+ const lowContrastCount = await page.evaluate(() => {
83
+ function getLuminance(r, g, b) {
84
+ const sRGB = [r, g, b].map(c => {
85
+ const s = c / 255;
86
+ return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
87
+ });
88
+ return 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2];
89
+ }
90
+ function parseColor(color) {
91
+ const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
92
+ if (match)
93
+ return [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])];
94
+ return null;
95
+ }
96
+ const elements = document.querySelectorAll('p, span, a, h1, h2, h3, h4, h5, h6, li, td, th, label');
97
+ let lowContrast = 0;
98
+ for (const el of Array.from(elements).slice(0, 50)) {
99
+ const style = window.getComputedStyle(el);
100
+ const fg = parseColor(style.color);
101
+ const bg = parseColor(style.backgroundColor);
102
+ if (fg && bg) {
103
+ const fgLum = getLuminance(...fg);
104
+ const bgLum = getLuminance(...bg);
105
+ const ratio = (Math.max(fgLum, bgLum) + 0.05) / (Math.min(fgLum, bgLum) + 0.05);
106
+ if (ratio < 7) {
107
+ lowContrast++;
108
+ }
109
+ }
110
+ }
111
+ return lowContrast;
112
+ });
113
+ if (lowContrastCount > 0) {
114
+ findings.push({
115
+ id: `${this.agentId}-low-contrast-${moduleId}`,
116
+ type: 'test-bug',
117
+ severity: 'medium',
118
+ agentId: this.agentId,
119
+ module: moduleId,
120
+ description: `${lowContrastCount} element(s) have contrast ratio below 7:1 (WCAG AAA requirement)`,
121
+ });
122
+ }
123
+ }
124
+ catch {
125
+ // Contrast check failed — non-critical
126
+ }
127
+ return findings;
128
+ }
129
+ async checkTextResize(page, moduleId) {
130
+ const findings = [];
131
+ try {
132
+ const hasOverflow = await page.evaluate(() => {
133
+ document.documentElement.style.fontSize = '200%';
134
+ // Wait a tick for reflow
135
+ const body = document.body;
136
+ const hasHorizontalOverflow = body.scrollWidth > window.innerWidth;
137
+ // Reset
138
+ document.documentElement.style.fontSize = '';
139
+ return hasHorizontalOverflow;
140
+ });
141
+ if (hasOverflow) {
142
+ findings.push({
143
+ id: `${this.agentId}-text-resize-overflow-${moduleId}`,
144
+ type: 'test-bug',
145
+ severity: 'medium',
146
+ agentId: this.agentId,
147
+ module: moduleId,
148
+ description: `Content overflows horizontally when text is resized to 200% in ${moduleId}`,
149
+ });
150
+ }
151
+ }
152
+ catch {
153
+ // Resize check failed — non-critical
154
+ }
155
+ return findings;
156
+ }
157
+ async checkKeyboardNavigation(page, moduleId) {
158
+ const findings = [];
159
+ try {
160
+ // Tab through elements and check focus visibility
161
+ const focusableCount = await page.evaluate(() => {
162
+ const focusable = document.querySelectorAll('a, button, input, select, textarea, [tabindex]');
163
+ return focusable.length;
164
+ });
165
+ if (focusableCount === 0) {
166
+ findings.push({
167
+ id: `${this.agentId}-no-focusable-${moduleId}`,
168
+ type: 'test-bug',
169
+ severity: 'medium',
170
+ agentId: this.agentId,
171
+ module: moduleId,
172
+ description: `No focusable elements found in ${moduleId} — keyboard navigation may not work`,
173
+ });
174
+ return findings;
175
+ }
176
+ // Press Tab a few times and check if focus is visible
177
+ for (let i = 0; i < Math.min(5, focusableCount); i++) {
178
+ await page.keyboard.press('Tab');
179
+ }
180
+ const hasFocusIndicator = await page.evaluate(() => {
181
+ const focused = document.activeElement;
182
+ if (!focused || focused === document.body)
183
+ return false;
184
+ const style = window.getComputedStyle(focused);
185
+ const hasOutline = style.outlineStyle !== 'none' && style.outlineWidth !== '0px';
186
+ const hasBoxShadow = style.boxShadow !== 'none';
187
+ const hasBorder = style.borderColor !== style.backgroundColor;
188
+ return hasOutline || hasBoxShadow || hasBorder;
189
+ });
190
+ if (!hasFocusIndicator) {
191
+ findings.push({
192
+ id: `${this.agentId}-no-focus-indicator-${moduleId}`,
193
+ type: 'test-bug',
194
+ severity: 'medium',
195
+ agentId: this.agentId,
196
+ module: moduleId,
197
+ description: `Focus indicator not visible during keyboard navigation in ${moduleId}`,
198
+ });
199
+ }
200
+ }
201
+ catch {
202
+ // Keyboard nav check failed — non-critical
203
+ }
204
+ return findings;
205
+ }
206
+ }
207
+ //# sourceMappingURL=67-wcag-aaa-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"67-wcag-aaa-tester.js","sourceRoot":"","sources":["../../agents/67-wcag-aaa-tester.ts"],"names":[],"mappings":"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"}