qa360 2.2.20 → 2.3.1

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 (507) hide show
  1. package/README.md +155 -262
  2. package/{cli/dist → dist}/commands/ai.js +1 -1
  3. package/{cli/dist → dist}/commands/coverage.js +1 -1
  4. package/{cli/dist → dist}/commands/crawl.d.ts +12 -1
  5. package/{cli/dist → dist}/commands/crawl.js +70 -9
  6. package/{cli/dist → dist}/commands/doctor.js +2 -2
  7. package/{cli/dist → dist}/commands/explain.js +2 -2
  8. package/{cli/dist → dist}/commands/flakiness.js +1 -1
  9. package/{cli/dist → dist}/commands/generate.js +1 -1
  10. package/{cli/dist → dist}/commands/history.js +1 -1
  11. package/{cli/dist → dist}/commands/monitor.js +3 -3
  12. package/{cli/dist → dist}/commands/ollama.js +1 -1
  13. package/{cli/dist → dist}/commands/pack.js +2 -2
  14. package/{cli/dist → dist}/commands/regression.js +1 -1
  15. package/{cli/dist → dist}/commands/repair.js +1 -1
  16. package/{cli/dist → dist}/commands/retry.js +1 -1
  17. package/{cli/dist → dist}/commands/run.d.ts +1 -1
  18. package/{cli/dist → dist}/commands/run.js +1 -1
  19. package/{cli/dist → dist}/commands/secrets.js +1 -1
  20. package/{cli/dist → dist}/commands/serve.js +1 -1
  21. package/{cli/dist → dist}/commands/slo.js +1 -1
  22. package/{cli/dist → dist}/commands/verify.js +1 -1
  23. package/{cli/dist → dist}/core/adapters/playwright-native-api.d.ts +2 -0
  24. package/{cli/dist → dist}/core/adapters/playwright-native-api.js +20 -1
  25. package/{cli/dist → dist}/core/adapters/playwright-ui.d.ts +21 -0
  26. package/dist/core/adapters/playwright-ui.js +2050 -0
  27. package/{cli/dist → dist}/core/ai/ollama-provider.js +15 -3
  28. package/{cli/dist → dist}/core/artifacts/ui-artifacts.js +24 -4
  29. package/dist/core/auth/backup-codes-provider.d.ts +91 -0
  30. package/dist/core/auth/backup-codes-provider.js +215 -0
  31. package/{cli/dist → dist}/core/auth/basic-auth-provider.d.ts +6 -0
  32. package/{cli/dist → dist}/core/auth/basic-auth-provider.js +24 -6
  33. package/dist/core/auth/digest-auth-provider.d.ts +116 -0
  34. package/dist/core/auth/digest-auth-provider.js +244 -0
  35. package/dist/core/auth/hcaptcha-handler.d.ts +103 -0
  36. package/dist/core/auth/hcaptcha-handler.js +288 -0
  37. package/{cli/dist → dist}/core/auth/index.d.ts +81 -4
  38. package/{cli/dist → dist}/core/auth/index.js +15 -1
  39. package/dist/core/auth/oauth-handler.d.ts +408 -0
  40. package/dist/core/auth/oauth-handler.js +636 -0
  41. package/{cli/dist → dist}/core/auth/oauth2-provider.d.ts +9 -0
  42. package/dist/core/auth/oauth2-provider.js +227 -0
  43. package/dist/core/auth/otp-provider.d.ts +93 -0
  44. package/dist/core/auth/otp-provider.js +288 -0
  45. package/dist/core/auth/recaptcha-handler.d.ts +119 -0
  46. package/dist/core/auth/recaptcha-handler.js +301 -0
  47. package/dist/core/auth/remember-me-handler.d.ts +142 -0
  48. package/dist/core/auth/remember-me-handler.js +255 -0
  49. package/dist/core/auth/saml-handler.d.ts +173 -0
  50. package/dist/core/auth/saml-handler.js +364 -0
  51. package/dist/core/auth/webauthn-handler.d.ts +182 -0
  52. package/dist/core/auth/webauthn-handler.js +310 -0
  53. package/dist/core/crawler/advanced-interactions.d.ts +342 -0
  54. package/dist/core/crawler/advanced-interactions.js +1069 -0
  55. package/dist/core/crawler/blob-url-download-handler.d.ts +145 -0
  56. package/dist/core/crawler/blob-url-download-handler.js +392 -0
  57. package/dist/core/crawler/consent-handler.d.ts +49 -0
  58. package/dist/core/crawler/consent-handler.js +258 -0
  59. package/dist/core/crawler/cookie-manager.d.ts +166 -0
  60. package/dist/core/crawler/cookie-manager.js +353 -0
  61. package/dist/core/crawler/coop-coep-handler.d.ts +136 -0
  62. package/dist/core/crawler/coop-coep-handler.js +338 -0
  63. package/dist/core/crawler/csp-handler.d.ts +151 -0
  64. package/dist/core/crawler/csp-handler.js +415 -0
  65. package/dist/core/crawler/download-handler.d.ts +155 -0
  66. package/dist/core/crawler/download-handler.js +370 -0
  67. package/dist/core/crawler/email-testing-handler.d.ts +214 -0
  68. package/dist/core/crawler/email-testing-handler.js +398 -0
  69. package/dist/core/crawler/error-tracking-handler.d.ts +177 -0
  70. package/dist/core/crawler/error-tracking-handler.js +378 -0
  71. package/dist/core/crawler/form-handler.d.ts +100 -0
  72. package/dist/core/crawler/form-handler.js +465 -0
  73. package/dist/core/crawler/framework-wait-handler.d.ts +96 -0
  74. package/dist/core/crawler/framework-wait-handler.js +464 -0
  75. package/dist/core/crawler/geolocation-handler.d.ts +112 -0
  76. package/dist/core/crawler/geolocation-handler.js +276 -0
  77. package/dist/core/crawler/index.d.ts +78 -0
  78. package/{cli/dist → dist}/core/crawler/index.js +74 -1
  79. package/dist/core/crawler/intelligent-selector-generator.d.ts +164 -0
  80. package/dist/core/crawler/intelligent-selector-generator.js +612 -0
  81. package/{cli/dist → dist}/core/crawler/journey-generator.js +44 -1
  82. package/{cli/dist → dist}/core/crawler/page-analyzer.d.ts +16 -1
  83. package/{cli/dist → dist}/core/crawler/page-analyzer.js +469 -17
  84. package/dist/core/crawler/permissions-handler.d.ts +112 -0
  85. package/dist/core/crawler/permissions-handler.js +236 -0
  86. package/dist/core/crawler/permissions-policy-handler.d.ts +113 -0
  87. package/dist/core/crawler/permissions-policy-handler.js +402 -0
  88. package/dist/core/crawler/presets.d.ts +100 -0
  89. package/dist/core/crawler/presets.js +887 -0
  90. package/dist/core/crawler/repl-debug-handler.d.ts +105 -0
  91. package/dist/core/crawler/repl-debug-handler.js +552 -0
  92. package/dist/core/crawler/reporting-api-handler.d.ts +212 -0
  93. package/dist/core/crawler/reporting-api-handler.js +344 -0
  94. package/{cli/dist → dist}/core/crawler/selector-generator.d.ts +9 -0
  95. package/{cli/dist → dist}/core/crawler/selector-generator.js +99 -23
  96. package/dist/core/crawler/site-profiler.d.ts +89 -0
  97. package/dist/core/crawler/site-profiler.js +290 -0
  98. package/dist/core/crawler/sourcemaps-handler.d.ts +144 -0
  99. package/dist/core/crawler/sourcemaps-handler.js +420 -0
  100. package/dist/core/crawler/stacked-modals-handler.d.ts +118 -0
  101. package/dist/core/crawler/stacked-modals-handler.js +429 -0
  102. package/dist/core/crawler/trusted-types-handler.d.ts +149 -0
  103. package/dist/core/crawler/trusted-types-handler.js +413 -0
  104. package/{cli/dist → dist}/core/crawler/types.d.ts +68 -2
  105. package/dist/core/crawler/wait-strategies.d.ts +108 -0
  106. package/dist/core/crawler/wait-strategies.js +399 -0
  107. package/dist/core/fixtures/factories.d.ts +180 -0
  108. package/dist/core/fixtures/factories.js +279 -0
  109. package/dist/core/fixtures/index.d.ts +6 -0
  110. package/dist/core/fixtures/index.js +6 -0
  111. package/{cli/dist → dist}/core/generation/crawler-pack-generator.d.ts +13 -3
  112. package/dist/core/generation/crawler-pack-generator.js +232 -0
  113. package/{cli/dist → dist}/core/generation/index.d.ts +2 -0
  114. package/{cli/dist → dist}/core/generation/index.js +2 -0
  115. package/{cli/dist → dist}/core/index.d.ts +2 -0
  116. package/{cli/dist → dist}/core/index.js +4 -0
  117. package/dist/core/network/index.d.ts +7 -0
  118. package/dist/core/network/index.js +7 -0
  119. package/dist/core/network/network-manager.d.ts +237 -0
  120. package/dist/core/network/network-manager.js +343 -0
  121. package/dist/core/network/network-simulator.d.ts +158 -0
  122. package/dist/core/network/network-simulator.js +261 -0
  123. package/{cli/dist → dist}/core/pack/validator.js +2 -2
  124. package/{cli/dist → dist}/core/pack-v2/migrator.d.ts +5 -0
  125. package/{cli/dist → dist}/core/pack-v2/migrator.js +81 -6
  126. package/{cli/dist → dist}/core/pack-v2/validator.js +4 -3
  127. package/{cli/dist → dist}/core/pom/base-page.js +1 -1
  128. package/{cli/dist → dist}/core/pom/loader.js +1 -1
  129. package/dist/core/reporting/index.d.ts +9 -0
  130. package/dist/core/reporting/index.js +10 -0
  131. package/dist/core/reporting/junit-reporter.d.ts +114 -0
  132. package/dist/core/reporting/junit-reporter.js +306 -0
  133. package/{cli/dist → dist}/core/runner/e2e-helpers.d.ts +1 -1
  134. package/{cli/dist → dist}/core/runner/e2e-helpers.js +2 -2
  135. package/{cli/dist → dist}/core/runner/phase3-runner.d.ts +3 -0
  136. package/{cli/dist → dist}/core/runner/phase3-runner.js +45 -14
  137. package/dist/core/sharding/test-sharding.d.ts +137 -0
  138. package/dist/core/sharding/test-sharding.js +233 -0
  139. package/dist/core/storage/cookie-manager.d.ts +160 -0
  140. package/dist/core/storage/cookie-manager.js +268 -0
  141. package/dist/core/storage/index.d.ts +7 -0
  142. package/dist/core/storage/index.js +7 -0
  143. package/dist/core/storage/storage-helpers.d.ts +138 -0
  144. package/dist/core/storage/storage-helpers.js +315 -0
  145. package/dist/core/test-helpers/index.d.ts +6 -0
  146. package/dist/core/test-helpers/index.js +6 -0
  147. package/dist/core/test-helpers/state-reset.d.ts +119 -0
  148. package/dist/core/test-helpers/state-reset.js +234 -0
  149. package/{cli/dist → dist}/core/types/pack-v1.d.ts +15 -2
  150. package/{cli/dist → dist}/core/types/pack-v2.d.ts +1 -1
  151. package/dist/core/upload/chunked-uploader.d.ts +150 -0
  152. package/dist/core/upload/chunked-uploader.js +289 -0
  153. package/dist/core/upload/index.d.ts +11 -0
  154. package/dist/core/upload/index.js +8 -0
  155. package/dist/core/upload/mime-validator.d.ts +119 -0
  156. package/dist/core/upload/mime-validator.js +373 -0
  157. package/dist/core/upload/presigned-uploader.d.ts +118 -0
  158. package/dist/core/upload/presigned-uploader.js +274 -0
  159. package/dist/core/utils/device-emulation.d.ts +194 -0
  160. package/dist/core/utils/device-emulation.js +380 -0
  161. package/dist/core/utils/index.d.ts +8 -0
  162. package/dist/core/utils/index.js +8 -0
  163. package/dist/core/utils/retry.d.ts +145 -0
  164. package/dist/core/utils/retry.js +242 -0
  165. package/dist/core/utils/smart-wait.d.ts +133 -0
  166. package/dist/core/utils/smart-wait.js +417 -0
  167. package/dist/core/visual/index.d.ts +7 -0
  168. package/dist/core/visual/index.js +7 -0
  169. package/dist/core/visual/pixel-diff.d.ts +87 -0
  170. package/dist/core/visual/pixel-diff.js +213 -0
  171. package/dist/core/visual/screenshot-helper.d.ts +130 -0
  172. package/dist/core/visual/screenshot-helper.js +223 -0
  173. package/{cli/dist → dist}/utils/config.d.ts +1 -1
  174. package/examples/README.md +160 -0
  175. package/examples/accessibility.yml +48 -0
  176. package/examples/api-basic.yml +27 -0
  177. package/examples/complete.yml +146 -0
  178. package/examples/crawler.yml +38 -0
  179. package/examples/fullstack.yml +78 -0
  180. package/examples/security.yml +58 -0
  181. package/examples/ui-advanced.yml +49 -0
  182. package/examples/ui-basic.yml +24 -0
  183. package/package.json +33 -67
  184. package/CHANGELOG.md +0 -262
  185. package/CONTRIBUTING.md +0 -273
  186. package/QUICK_START.md +0 -191
  187. package/cli/CHANGELOG.md +0 -84
  188. package/cli/LICENSE +0 -24
  189. package/cli/README.md +0 -222
  190. package/cli/dist/core/adapters/playwright-ui.js +0 -864
  191. package/cli/dist/core/auth/oauth2-provider.js +0 -114
  192. package/cli/dist/core/coverage/analyzer.d.ts +0 -101
  193. package/cli/dist/core/coverage/analyzer.js +0 -415
  194. package/cli/dist/core/coverage/collector.d.ts +0 -74
  195. package/cli/dist/core/coverage/collector.js +0 -459
  196. package/cli/dist/core/coverage/config.d.ts +0 -37
  197. package/cli/dist/core/coverage/config.js +0 -156
  198. package/cli/dist/core/coverage/index.d.ts +0 -11
  199. package/cli/dist/core/coverage/index.js +0 -15
  200. package/cli/dist/core/coverage/types.d.ts +0 -267
  201. package/cli/dist/core/coverage/types.js +0 -6
  202. package/cli/dist/core/coverage/vault.d.ts +0 -95
  203. package/cli/dist/core/coverage/vault.js +0 -405
  204. package/cli/dist/core/crawler/index.d.ts +0 -57
  205. package/cli/dist/core/fixtures/index.d.ts +0 -8
  206. package/cli/dist/core/fixtures/index.js +0 -8
  207. package/cli/dist/core/generation/crawler-pack-generator.js +0 -231
  208. package/cli/dist/core/reporting/index.d.ts +0 -6
  209. package/cli/dist/core/reporting/index.js +0 -6
  210. package/cli/dist/core/visual/index.d.ts +0 -6
  211. package/cli/dist/core/visual/index.js +0 -6
  212. package/cli/package.json +0 -76
  213. package/core/LICENSE +0 -24
  214. package/core/README.md +0 -64
  215. package/core/package.json +0 -81
  216. package/core/schemas/pack.schema.json +0 -236
  217. /package/{cli/bin → bin}/qa360.js +0 -0
  218. /package/{cli/dist → dist}/cli-minimal.d.ts +0 -0
  219. /package/{cli/dist → dist}/cli-minimal.js +0 -0
  220. /package/{cli/dist → dist}/commands/ai.d.ts +0 -0
  221. /package/{cli/dist → dist}/commands/ask.d.ts +0 -0
  222. /package/{cli/dist → dist}/commands/ask.js +0 -0
  223. /package/{cli/dist → dist}/commands/coverage.d.ts +0 -0
  224. /package/{cli/dist → dist}/commands/doctor.d.ts +0 -0
  225. /package/{cli/dist → dist}/commands/examples.d.ts +0 -0
  226. /package/{cli/dist → dist}/commands/examples.js +0 -0
  227. /package/{cli/dist → dist}/commands/explain.d.ts +0 -0
  228. /package/{cli/dist → dist}/commands/flakiness.d.ts +0 -0
  229. /package/{cli/dist → dist}/commands/generate.d.ts +0 -0
  230. /package/{cli/dist → dist}/commands/history.d.ts +0 -0
  231. /package/{cli/dist → dist}/commands/init.d.ts +0 -0
  232. /package/{cli/dist → dist}/commands/init.js +0 -0
  233. /package/{cli/dist → dist}/commands/monitor.d.ts +0 -0
  234. /package/{cli/dist → dist}/commands/ollama.d.ts +0 -0
  235. /package/{cli/dist → dist}/commands/pack.d.ts +0 -0
  236. /package/{cli/dist → dist}/commands/regression.d.ts +0 -0
  237. /package/{cli/dist → dist}/commands/repair.d.ts +0 -0
  238. /package/{cli/dist → dist}/commands/report.d.ts +0 -0
  239. /package/{cli/dist → dist}/commands/report.js +0 -0
  240. /package/{cli/dist → dist}/commands/retry.d.ts +0 -0
  241. /package/{cli/dist → dist}/commands/scan.d.ts +0 -0
  242. /package/{cli/dist → dist}/commands/scan.js +0 -0
  243. /package/{cli/dist → dist}/commands/secrets.d.ts +0 -0
  244. /package/{cli/dist → dist}/commands/serve.d.ts +0 -0
  245. /package/{cli/dist → dist}/commands/slo.d.ts +0 -0
  246. /package/{cli/dist → dist}/commands/verify.d.ts +0 -0
  247. /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.d.ts +0 -0
  248. /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.js +0 -0
  249. /package/{cli/dist → dist}/core/adapters/jest-adapter.d.ts +0 -0
  250. /package/{cli/dist → dist}/core/adapters/jest-adapter.js +0 -0
  251. /package/{cli/dist → dist}/core/adapters/k6-perf.d.ts +0 -0
  252. /package/{cli/dist → dist}/core/adapters/k6-perf.js +0 -0
  253. /package/{cli/dist → dist}/core/adapters/osv-deps.d.ts +0 -0
  254. /package/{cli/dist → dist}/core/adapters/osv-deps.js +0 -0
  255. /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.d.ts +0 -0
  256. /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.js +0 -0
  257. /package/{cli/dist → dist}/core/adapters/pytest-adapter.d.ts +0 -0
  258. /package/{cli/dist → dist}/core/adapters/pytest-adapter.js +0 -0
  259. /package/{cli/dist → dist}/core/adapters/semgrep-sast.d.ts +0 -0
  260. /package/{cli/dist → dist}/core/adapters/semgrep-sast.js +0 -0
  261. /package/{cli/dist → dist}/core/adapters/unit-test-types.d.ts +0 -0
  262. /package/{cli/dist → dist}/core/adapters/unit-test-types.js +0 -0
  263. /package/{cli/dist → dist}/core/adapters/vitest-adapter.d.ts +0 -0
  264. /package/{cli/dist → dist}/core/adapters/vitest-adapter.js +0 -0
  265. /package/{cli/dist → dist}/core/adapters/zap-dast.d.ts +0 -0
  266. /package/{cli/dist → dist}/core/adapters/zap-dast.js +0 -0
  267. /package/{cli/dist → dist}/core/ai/anthropic-provider.d.ts +0 -0
  268. /package/{cli/dist → dist}/core/ai/anthropic-provider.js +0 -0
  269. /package/{cli/dist → dist}/core/ai/deepseek-provider.d.ts +0 -0
  270. /package/{cli/dist → dist}/core/ai/deepseek-provider.js +0 -0
  271. /package/{cli/dist → dist}/core/ai/index.d.ts +0 -0
  272. /package/{cli/dist → dist}/core/ai/index.js +0 -0
  273. /package/{cli/dist → dist}/core/ai/llm-client.d.ts +0 -0
  274. /package/{cli/dist → dist}/core/ai/llm-client.js +0 -0
  275. /package/{cli/dist → dist}/core/ai/mock-provider.d.ts +0 -0
  276. /package/{cli/dist → dist}/core/ai/mock-provider.js +0 -0
  277. /package/{cli/dist → dist}/core/ai/ollama-provider.d.ts +0 -0
  278. /package/{cli/dist → dist}/core/ai/openai-provider.d.ts +0 -0
  279. /package/{cli/dist → dist}/core/ai/openai-provider.js +0 -0
  280. /package/{cli/dist → dist}/core/ai/provider-factory.d.ts +0 -0
  281. /package/{cli/dist → dist}/core/ai/provider-factory.js +0 -0
  282. /package/{cli/dist → dist}/core/artifacts/index.d.ts +0 -0
  283. /package/{cli/dist → dist}/core/artifacts/index.js +0 -0
  284. /package/{cli/dist → dist}/core/artifacts/ui-artifacts.d.ts +0 -0
  285. /package/{cli/dist → dist}/core/assertions/engine.d.ts +0 -0
  286. /package/{cli/dist → dist}/core/assertions/engine.js +0 -0
  287. /package/{cli/dist → dist}/core/assertions/index.d.ts +0 -0
  288. /package/{cli/dist → dist}/core/assertions/index.js +0 -0
  289. /package/{cli/dist → dist}/core/assertions/types.d.ts +0 -0
  290. /package/{cli/dist → dist}/core/assertions/types.js +0 -0
  291. /package/{cli/dist → dist}/core/auth/api-key-provider.d.ts +0 -0
  292. /package/{cli/dist → dist}/core/auth/api-key-provider.js +0 -0
  293. /package/{cli/dist → dist}/core/auth/aws-iam-provider.d.ts +0 -0
  294. /package/{cli/dist → dist}/core/auth/aws-iam-provider.js +0 -0
  295. /package/{cli/dist → dist}/core/auth/azure-ad-provider.d.ts +0 -0
  296. /package/{cli/dist → dist}/core/auth/azure-ad-provider.js +0 -0
  297. /package/{cli/dist → dist}/core/auth/gcp-adc-provider.d.ts +0 -0
  298. /package/{cli/dist → dist}/core/auth/gcp-adc-provider.js +0 -0
  299. /package/{cli/dist → dist}/core/auth/jwt-provider.d.ts +0 -0
  300. /package/{cli/dist → dist}/core/auth/jwt-provider.js +0 -0
  301. /package/{cli/dist → dist}/core/auth/manager.d.ts +0 -0
  302. /package/{cli/dist → dist}/core/auth/manager.js +0 -0
  303. /package/{cli/dist → dist}/core/auth/totp-provider.d.ts +0 -0
  304. /package/{cli/dist → dist}/core/auth/totp-provider.js +0 -0
  305. /package/{cli/dist → dist}/core/auth/ui-login-provider.d.ts +0 -0
  306. /package/{cli/dist → dist}/core/auth/ui-login-provider.js +0 -0
  307. /package/{cli/dist → dist}/core/cache/index.d.ts +0 -0
  308. /package/{cli/dist → dist}/core/cache/index.js +0 -0
  309. /package/{cli/dist → dist}/core/cache/lru-cache.d.ts +0 -0
  310. /package/{cli/dist → dist}/core/cache/lru-cache.js +0 -0
  311. /package/{cli/dist/core → dist}/core/coverage/analyzer.d.ts +0 -0
  312. /package/{cli/dist/core → dist}/core/coverage/analyzer.js +0 -0
  313. /package/{cli/dist/core → dist}/core/coverage/collector.d.ts +0 -0
  314. /package/{cli/dist/core → dist}/core/coverage/collector.js +0 -0
  315. /package/{cli/dist/core → dist}/core/coverage/config.d.ts +0 -0
  316. /package/{cli/dist/core → dist}/core/coverage/config.js +0 -0
  317. /package/{cli/dist/core → dist}/core/coverage/index.d.ts +0 -0
  318. /package/{cli/dist/core → dist}/core/coverage/index.js +0 -0
  319. /package/{cli/dist/core → dist}/core/coverage/types.d.ts +0 -0
  320. /package/{cli/dist/core → dist}/core/coverage/types.js +0 -0
  321. /package/{cli/dist/core → dist}/core/coverage/vault.d.ts +0 -0
  322. /package/{cli/dist/core → dist}/core/coverage/vault.js +0 -0
  323. /package/{cli/dist → dist}/core/crawler/journey-generator.d.ts +0 -0
  324. /package/{cli/dist → dist}/core/crawler/types.js +0 -0
  325. /package/{cli/dist → dist}/core/dashboard/assets.d.ts +0 -0
  326. /package/{cli/dist → dist}/core/dashboard/assets.js +0 -0
  327. /package/{cli/dist → dist}/core/dashboard/index.d.ts +0 -0
  328. /package/{cli/dist → dist}/core/dashboard/index.js +0 -0
  329. /package/{cli/dist → dist}/core/dashboard/server.d.ts +0 -0
  330. /package/{cli/dist → dist}/core/dashboard/server.js +0 -0
  331. /package/{cli/dist → dist}/core/dashboard/types.d.ts +0 -0
  332. /package/{cli/dist → dist}/core/dashboard/types.js +0 -0
  333. /package/{cli/dist → dist}/core/discoverer/index.d.ts +0 -0
  334. /package/{cli/dist → dist}/core/discoverer/index.js +0 -0
  335. /package/{cli/dist → dist}/core/fixtures/loader.d.ts +0 -0
  336. /package/{cli/dist → dist}/core/fixtures/loader.js +0 -0
  337. /package/{cli/dist → dist}/core/fixtures/resolver.d.ts +0 -0
  338. /package/{cli/dist → dist}/core/fixtures/resolver.js +0 -0
  339. /package/{cli/dist → dist}/core/fixtures/types.d.ts +0 -0
  340. /package/{cli/dist → dist}/core/fixtures/types.js +0 -0
  341. /package/{cli/dist → dist}/core/flakiness/index.d.ts +0 -0
  342. /package/{cli/dist → dist}/core/flakiness/index.js +0 -0
  343. /package/{cli/dist → dist}/core/generation/code-formatter.d.ts +0 -0
  344. /package/{cli/dist → dist}/core/generation/code-formatter.js +0 -0
  345. /package/{cli/dist → dist}/core/generation/code-generator.d.ts +0 -0
  346. /package/{cli/dist → dist}/core/generation/code-generator.js +0 -0
  347. /package/{cli/dist → dist}/core/generation/generator.d.ts +0 -0
  348. /package/{cli/dist → dist}/core/generation/generator.js +0 -0
  349. /package/{cli/dist → dist}/core/generation/pack-generator.d.ts +0 -0
  350. /package/{cli/dist → dist}/core/generation/pack-generator.js +0 -0
  351. /package/{cli/dist → dist}/core/generation/prompt-builder.d.ts +0 -0
  352. /package/{cli/dist → dist}/core/generation/prompt-builder.js +0 -0
  353. /package/{cli/dist → dist}/core/generation/source-analyzer.d.ts +0 -0
  354. /package/{cli/dist → dist}/core/generation/source-analyzer.js +0 -0
  355. /package/{cli/dist → dist}/core/generation/test-optimizer.d.ts +0 -0
  356. /package/{cli/dist → dist}/core/generation/test-optimizer.js +0 -0
  357. /package/{cli/dist → dist}/core/generation/types.d.ts +0 -0
  358. /package/{cli/dist → dist}/core/generation/types.js +0 -0
  359. /package/{cli/dist → dist}/core/hooks/compose.d.ts +0 -0
  360. /package/{cli/dist → dist}/core/hooks/compose.js +0 -0
  361. /package/{cli/dist → dist}/core/hooks/runner.d.ts +0 -0
  362. /package/{cli/dist → dist}/core/hooks/runner.js +0 -0
  363. /package/{cli/dist → dist}/core/pack/migrator.d.ts +0 -0
  364. /package/{cli/dist → dist}/core/pack/migrator.js +0 -0
  365. /package/{cli/dist → dist}/core/pack/validator.d.ts +0 -0
  366. /package/{cli/dist → dist}/core/pack-v2/index.d.ts +0 -0
  367. /package/{cli/dist → dist}/core/pack-v2/index.js +0 -0
  368. /package/{cli/dist → dist}/core/pack-v2/loader.d.ts +0 -0
  369. /package/{cli/dist → dist}/core/pack-v2/loader.js +0 -0
  370. /package/{cli/dist → dist}/core/pack-v2/validator.d.ts +0 -0
  371. /package/{cli/dist → dist}/core/parallel/index.d.ts +0 -0
  372. /package/{cli/dist → dist}/core/parallel/index.js +0 -0
  373. /package/{cli/dist → dist}/core/parallel/parallel-runner.d.ts +0 -0
  374. /package/{cli/dist → dist}/core/parallel/parallel-runner.js +0 -0
  375. /package/{cli/dist → dist}/core/pom/base-page.d.ts +0 -0
  376. /package/{cli/dist → dist}/core/pom/index.d.ts +0 -0
  377. /package/{cli/dist → dist}/core/pom/index.js +0 -0
  378. /package/{cli/dist → dist}/core/pom/loader.d.ts +0 -0
  379. /package/{cli/dist → dist}/core/pom/types.d.ts +0 -0
  380. /package/{cli/dist → dist}/core/pom/types.js +0 -0
  381. /package/{cli/dist → dist}/core/proof/bundle.d.ts +0 -0
  382. /package/{cli/dist → dist}/core/proof/bundle.js +0 -0
  383. /package/{cli/dist → dist}/core/proof/canonicalize.d.ts +0 -0
  384. /package/{cli/dist → dist}/core/proof/canonicalize.js +0 -0
  385. /package/{cli/dist → dist}/core/proof/index.d.ts +0 -0
  386. /package/{cli/dist → dist}/core/proof/index.js +0 -0
  387. /package/{cli/dist → dist}/core/proof/schema.d.ts +0 -0
  388. /package/{cli/dist → dist}/core/proof/schema.js +0 -0
  389. /package/{cli/dist → dist}/core/proof/signer.d.ts +0 -0
  390. /package/{cli/dist → dist}/core/proof/signer.js +0 -0
  391. /package/{cli/dist → dist}/core/proof/verifier.d.ts +0 -0
  392. /package/{cli/dist → dist}/core/proof/verifier.js +0 -0
  393. /package/{cli/dist → dist}/core/regression/detector.d.ts +0 -0
  394. /package/{cli/dist → dist}/core/regression/detector.js +0 -0
  395. /package/{cli/dist → dist}/core/regression/index.d.ts +0 -0
  396. /package/{cli/dist → dist}/core/regression/index.js +0 -0
  397. /package/{cli/dist → dist}/core/regression/trend-analyzer.d.ts +0 -0
  398. /package/{cli/dist → dist}/core/regression/trend-analyzer.js +0 -0
  399. /package/{cli/dist → dist}/core/regression/types.d.ts +0 -0
  400. /package/{cli/dist → dist}/core/regression/types.js +0 -0
  401. /package/{cli/dist → dist}/core/regression/vault.d.ts +0 -0
  402. /package/{cli/dist → dist}/core/regression/vault.js +0 -0
  403. /package/{cli/dist → dist}/core/repair/engine/fixer.d.ts +0 -0
  404. /package/{cli/dist → dist}/core/repair/engine/fixer.js +0 -0
  405. /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.d.ts +0 -0
  406. /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.js +0 -0
  407. /package/{cli/dist → dist}/core/repair/index.d.ts +0 -0
  408. /package/{cli/dist → dist}/core/repair/index.js +0 -0
  409. /package/{cli/dist → dist}/core/repair/repairer.d.ts +0 -0
  410. /package/{cli/dist → dist}/core/repair/repairer.js +0 -0
  411. /package/{cli/dist → dist}/core/repair/types.d.ts +0 -0
  412. /package/{cli/dist → dist}/core/repair/types.js +0 -0
  413. /package/{cli/dist → dist}/core/repair/utils/error-analyzer.d.ts +0 -0
  414. /package/{cli/dist → dist}/core/repair/utils/error-analyzer.js +0 -0
  415. /package/{cli/dist → dist}/core/reporting/html-reporter.d.ts +0 -0
  416. /package/{cli/dist → dist}/core/reporting/html-reporter.js +0 -0
  417. /package/{cli/dist → dist}/core/retry/flakiness-integration.d.ts +0 -0
  418. /package/{cli/dist → dist}/core/retry/flakiness-integration.js +0 -0
  419. /package/{cli/dist → dist}/core/retry/index.d.ts +0 -0
  420. /package/{cli/dist → dist}/core/retry/index.js +0 -0
  421. /package/{cli/dist → dist}/core/retry/retry-engine.d.ts +0 -0
  422. /package/{cli/dist → dist}/core/retry/retry-engine.js +0 -0
  423. /package/{cli/dist → dist}/core/retry/types.d.ts +0 -0
  424. /package/{cli/dist → dist}/core/retry/types.js +0 -0
  425. /package/{cli/dist → dist}/core/retry/vault.d.ts +0 -0
  426. /package/{cli/dist → dist}/core/retry/vault.js +0 -0
  427. /package/{cli/dist → dist}/core/schemas/pack.schema.json +0 -0
  428. /package/{cli/dist → dist}/core/secrets/crypto.d.ts +0 -0
  429. /package/{cli/dist → dist}/core/secrets/crypto.js +0 -0
  430. /package/{cli/dist → dist}/core/secrets/manager.d.ts +0 -0
  431. /package/{cli/dist → dist}/core/secrets/manager.js +0 -0
  432. /package/{cli/dist → dist}/core/security/redaction-patterns-extended.d.ts +0 -0
  433. /package/{cli/dist → dist}/core/security/redaction-patterns-extended.js +0 -0
  434. /package/{cli/dist → dist}/core/security/redactor.d.ts +0 -0
  435. /package/{cli/dist → dist}/core/security/redactor.js +0 -0
  436. /package/{cli/dist → dist}/core/self-healing/assertion-healer.d.ts +0 -0
  437. /package/{cli/dist → dist}/core/self-healing/assertion-healer.js +0 -0
  438. /package/{cli/dist → dist}/core/self-healing/engine.d.ts +0 -0
  439. /package/{cli/dist → dist}/core/self-healing/engine.js +0 -0
  440. /package/{cli/dist → dist}/core/self-healing/index.d.ts +0 -0
  441. /package/{cli/dist → dist}/core/self-healing/index.js +0 -0
  442. /package/{cli/dist → dist}/core/self-healing/selector-healer.d.ts +0 -0
  443. /package/{cli/dist → dist}/core/self-healing/selector-healer.js +0 -0
  444. /package/{cli/dist → dist}/core/self-healing/types.d.ts +0 -0
  445. /package/{cli/dist → dist}/core/self-healing/types.js +0 -0
  446. /package/{cli/dist → dist}/core/serve/diagnostics-collector.d.ts +0 -0
  447. /package/{cli/dist → dist}/core/serve/diagnostics-collector.js +0 -0
  448. /package/{cli/dist → dist}/core/serve/health-checker.d.ts +0 -0
  449. /package/{cli/dist → dist}/core/serve/health-checker.js +0 -0
  450. /package/{cli/dist → dist}/core/serve/index.d.ts +0 -0
  451. /package/{cli/dist → dist}/core/serve/index.js +0 -0
  452. /package/{cli/dist → dist}/core/serve/metrics-collector.d.ts +0 -0
  453. /package/{cli/dist → dist}/core/serve/metrics-collector.js +0 -0
  454. /package/{cli/dist → dist}/core/serve/process-manager.d.ts +0 -0
  455. /package/{cli/dist → dist}/core/serve/process-manager.js +0 -0
  456. /package/{cli/dist → dist}/core/serve/server.d.ts +0 -0
  457. /package/{cli/dist → dist}/core/serve/server.js +0 -0
  458. /package/{cli/dist → dist}/core/slo/config.d.ts +0 -0
  459. /package/{cli/dist → dist}/core/slo/config.js +0 -0
  460. /package/{cli/dist → dist}/core/slo/index.d.ts +0 -0
  461. /package/{cli/dist → dist}/core/slo/index.js +0 -0
  462. /package/{cli/dist → dist}/core/slo/sli-calculator.d.ts +0 -0
  463. /package/{cli/dist → dist}/core/slo/sli-calculator.js +0 -0
  464. /package/{cli/dist → dist}/core/slo/slo-tracker.d.ts +0 -0
  465. /package/{cli/dist → dist}/core/slo/slo-tracker.js +0 -0
  466. /package/{cli/dist → dist}/core/slo/types.d.ts +0 -0
  467. /package/{cli/dist → dist}/core/slo/types.js +0 -0
  468. /package/{cli/dist → dist}/core/slo/vault.d.ts +0 -0
  469. /package/{cli/dist → dist}/core/slo/vault.js +0 -0
  470. /package/{cli/dist → dist}/core/tui/index.d.ts +0 -0
  471. /package/{cli/dist → dist}/core/tui/index.js +0 -0
  472. /package/{cli/dist → dist}/core/tui/monitor.d.ts +0 -0
  473. /package/{cli/dist → dist}/core/tui/monitor.js +0 -0
  474. /package/{cli/dist → dist}/core/tui/renderer.d.ts +0 -0
  475. /package/{cli/dist → dist}/core/tui/renderer.js +0 -0
  476. /package/{cli/dist → dist}/core/tui/types.d.ts +0 -0
  477. /package/{cli/dist → dist}/core/tui/types.js +0 -0
  478. /package/{cli/dist → dist}/core/types/pack-v1.js +0 -0
  479. /package/{cli/dist → dist}/core/types/pack-v2.js +0 -0
  480. /package/{cli/dist → dist}/core/types/trust-score.d.ts +0 -0
  481. /package/{cli/dist → dist}/core/types/trust-score.js +0 -0
  482. /package/{cli/dist → dist}/core/vault/cas.d.ts +0 -0
  483. /package/{cli/dist → dist}/core/vault/cas.js +0 -0
  484. /package/{cli/dist → dist}/core/vault/index.d.ts +0 -0
  485. /package/{cli/dist → dist}/core/vault/index.js +0 -0
  486. /package/{cli/dist → dist}/core/visual/visual-regression.d.ts +0 -0
  487. /package/{cli/dist → dist}/core/visual/visual-regression.js +0 -0
  488. /package/{cli/dist → dist}/core/watch/index.d.ts +0 -0
  489. /package/{cli/dist → dist}/core/watch/index.js +0 -0
  490. /package/{cli/dist → dist}/core/watch/watch-mode.d.ts +0 -0
  491. /package/{cli/dist → dist}/core/watch/watch-mode.js +0 -0
  492. /package/{cli/dist → dist}/generators/index.d.ts +0 -0
  493. /package/{cli/dist → dist}/generators/index.js +0 -0
  494. /package/{cli/dist → dist}/generators/json-reporter.d.ts +0 -0
  495. /package/{cli/dist → dist}/generators/json-reporter.js +0 -0
  496. /package/{cli/dist → dist}/generators/test-generator.d.ts +0 -0
  497. /package/{cli/dist → dist}/generators/test-generator.js +0 -0
  498. /package/{cli/dist → dist}/index.d.ts +0 -0
  499. /package/{cli/dist → dist}/index.js +0 -0
  500. /package/{cli/dist → dist}/scanners/dom-scanner.d.ts +0 -0
  501. /package/{cli/dist → dist}/scanners/dom-scanner.js +0 -0
  502. /package/{cli/dist → dist}/scanners/index.d.ts +0 -0
  503. /package/{cli/dist → dist}/scanners/index.js +0 -0
  504. /package/{cli/dist → dist}/schemas/pack.schema.json +0 -0
  505. /package/{cli/dist → dist}/types/scan.d.ts +0 -0
  506. /package/{cli/dist → dist}/types/scan.js +0 -0
  507. /package/{cli/dist → dist}/utils/config.js +0 -0
@@ -0,0 +1,612 @@
1
+ /**
2
+ * QA360 Intelligent Selector Generator
3
+ *
4
+ * Generates optimal CSS selectors by adapting to the detected site profile.
5
+ * Follows Testing Library best practices with configurable strategies.
6
+ *
7
+ * Philosophy: "The more your tests resemble the way your software is used,
8
+ * the more confidence they can give you." - Kent C. Dodds
9
+ */
10
+ /**
11
+ * Selector strategies by site profile
12
+ *
13
+ * Each profile has a different priority order (tiers) for selector generation.
14
+ * Higher tier = higher priority = checked first.
15
+ */
16
+ const SELECTOR_STRATEGIES = {
17
+ // ═══════════════════════════════════════════════════════════════════════════════
18
+ // PROFIL_MODERN: Site with data-testid (React Testing Library, Cypress)
19
+ // Examples: Modern React/Vue apps, SaaS, tech startups
20
+ // ═══════════════════════════════════════════════════════════════════════════════
21
+ PROFIL_MODERN: [
22
+ { tier: 1, name: 'testId', fn: 'getByTestId', weight: 100 },
23
+ { tier: 2, name: 'role+name', fn: 'getByRole', weight: 90 },
24
+ { tier: 3, name: 'label', fn: 'getByLabelText', weight: 85 },
25
+ { tier: 4, name: 'placeholder', fn: 'getByPlaceholder', weight: 70 },
26
+ { tier: 5, name: 'text', fn: 'getByText', weight: 65 },
27
+ { tier: 6, name: 'altText', fn: 'getByAltText', weight: 60 },
28
+ { tier: 7, name: 'title', fn: 'getByTitle', weight: 50 },
29
+ { tier: 8, name: 'id', fn: 'getById', weight: 40 },
30
+ { tier: 9, name: 'css', fn: 'getByCss', weight: 20 },
31
+ ],
32
+ // ═══════════════════════════════════════════════════════════════════════════════
33
+ // PROFIL_ACCESSIBLE: Accessible site without testids
34
+ // Examples: Government sites, banks, enterprise sites
35
+ // Follows Testing Library (role first)
36
+ // ═══════════════════════════════════════════════════════════════════════════════
37
+ PROFIL_ACCESSIBLE: [
38
+ { tier: 1, name: 'role+name', fn: 'getByRole', weight: 100 },
39
+ { tier: 2, name: 'label', fn: 'getByLabelText', weight: 95 },
40
+ { tier: 3, name: 'placeholder', fn: 'getByPlaceholder', weight: 85 },
41
+ { tier: 4, name: 'text', fn: 'getByText', weight: 80 },
42
+ { tier: 5, name: 'altText', fn: 'getByAltText', weight: 75 },
43
+ { tier: 6, name: 'title', fn: 'getByTitle', weight: 60 },
44
+ { tier: 7, name: 'testId', fn: 'getByTestId', weight: 50 },
45
+ { tier: 8, name: 'id', fn: 'getById', weight: 40 },
46
+ { tier: 9, name: 'css', fn: 'getByCss', weight: 20 },
47
+ ],
48
+ // ═══════════════════════════════════════════════════════════════════════════════
49
+ // PROFIL_LEGACY: Legacy site with few attributes
50
+ // Examples: ASP.NET, old PHP, classic WordPress
51
+ // ═══════════════════════════════════════════════════════════════════════════════
52
+ PROFIL_LEGACY: [
53
+ { tier: 1, name: 'id', fn: 'getById', weight: 100 },
54
+ { tier: 2, name: 'name', fn: 'getByName', weight: 95 },
55
+ { tier: 3, name: 'text', fn: 'getByText', weight: 85 },
56
+ { tier: 4, name: 'value', fn: 'getByValue', weight: 75 },
57
+ { tier: 5, name: 'placeholder', fn: 'getByPlaceholder', weight: 70 },
58
+ { tier: 6, name: 'role+name', fn: 'getByRole', weight: 60 },
59
+ { tier: 7, name: 'css', fn: 'getByCss', weight: 50 },
60
+ { tier: 8, name: 'position', fn: 'getByPosition', weight: 30 },
61
+ ],
62
+ // ═══════════════════════════════════════════════════════════════════════════════
63
+ // PROFIL_MINIMAL: Minimalist or hybrid sites
64
+ // Examples: Landing pages, static sites, blogs
65
+ // ═══════════════════════════════════════════════════════════════════════════════
66
+ PROFIL_MINIMAL: [
67
+ { tier: 1, name: 'text', fn: 'getByText', weight: 100 },
68
+ { tier: 2, name: 'role+name', fn: 'getByRole', weight: 90 },
69
+ { tier: 3, name: 'placeholder', fn: 'getByPlaceholder', weight: 80 },
70
+ { tier: 4, name: 'altText', fn: 'getByAltText', weight: 75 },
71
+ { tier: 5, name: 'id', fn: 'getById', weight: 65 },
72
+ { tier: 6, name: 'testId', fn: 'getByTestId', weight: 60 },
73
+ { tier: 7, name: 'css', fn: 'getByCss', weight: 40 },
74
+ ],
75
+ };
76
+ // ═══════════════════════════════════════════════════════════════════════════════
77
+ // GENERATED ID PATTERNS (to filter out)
78
+ // ═══════════════════════════════════════════════════════════════════════════════
79
+ /**
80
+ * Patterns for auto-generated IDs (NOT stable)
81
+ */
82
+ const GENERATED_ID_PATTERNS = [
83
+ // === Existing ===
84
+ /^\w+_\d+$/, // react_123
85
+ /^(ember|ember)\d+$/, // ember1234
86
+ /^yui_[^_]+_\d+$/, // yui_gen_123
87
+ /^\w+-\w+-\w+$/, // random-hash
88
+ /^[a-f0-9]{8,}$/, // hex hashes
89
+ // === NEW - JavaScript Frameworks ===
90
+ /^_ngcontent-\w+-\d+$/, // Angular
91
+ /^_nghost-\w+-\d+$/, // Angular
92
+ /^_ngcontent\d+$/, // Angular
93
+ /^cdk-\w+-\d+$/, // Angular CDK
94
+ /^mat-\w+-\d+$/, // Angular Material
95
+ /^data-v-[a-f0-9]+$/, // Vue scoped
96
+ /^svelte-[a-z0-9]+$/i, // Svelte
97
+ /^s-[a-z0-9]+$/i, // Svelte short
98
+ // === NEW - UI Libraries ===
99
+ /^mui-\d+$/, // Material UI
100
+ /^:r[a-z0-9]+:$/, // MUI v5
101
+ /^css-[a-z0-9]+-\w+$/, // Emotion/styled-components
102
+ /^radix-\w+-\d+$/, // Radix UI
103
+ /^chakra-\w+-\d+$/, // Chakra UI
104
+ // === NEW - Legacy/Enterprise ===
105
+ /^ctl\d+_/, // ASP.NET
106
+ /^__\w+$/, // ASP.NET ViewState
107
+ /^MainContent_/, // ASP.NET
108
+ /^j_id[_:]?\d+$/, // JSF (Java)
109
+ /^form[_:]\w+$/, // JSF
110
+ /^gwt-uid-\d+$/, // GWT
111
+ /^ext-(gen|comp|element)-?\d+$/, // ExtJS
112
+ // === NEW - CMS ===
113
+ /^w-node-[a-f0-9-]+$/, // Webflow
114
+ /^post-\d+$/, // WordPress
115
+ /^comment-\d+$/, // WordPress
116
+ /^menu-item-\d+$/, // WordPress
117
+ /^edit-\w+-\d+-\w+$/, // Drupal
118
+ /^node-\d+$/, // Drupal
119
+ // === NEW - Generic ===
120
+ /^[a-f0-9]{8}-[a-f0-9]{4}-/, // UUID prefix
121
+ /^\w+-[a-f0-9]{6,}$/, // name-hash
122
+ /^_?[a-zA-Z]+_[a-z0-9]{5,}$/, // CSS Modules
123
+ /^[a-f0-9]{32}$/, // MD5 hash
124
+ /^[a-f0-9]{40}$/, // SHA1 hash
125
+ ];
126
+ /**
127
+ * Semantic ID patterns (TO KEEP)
128
+ * These IDs describe the PURPOSE, not the implementation
129
+ */
130
+ const SEMANTIC_ID_PATTERNS = [
131
+ // Actions
132
+ /^(login|signin|signup|register|logout|signout|submit|cancel|save|delete|edit|create|add|remove)[-_]?(btn|button|form|modal|dialog)?$/i,
133
+ /^(search|filter|sort|pagination)[-_]?(input|box|field|bar)?$/i,
134
+ // Form fields
135
+ /^(email|password|username|firstname|lastname|fullname|phone|address|city|zip|postal|country|state|region)[-_]?(input|field)?$/i,
136
+ /^(subject|message|comment|content|body|description)[-_]?(input|field|textarea)?$/i,
137
+ // Page zones
138
+ /^(header|footer|sidebar|nav|navigation|main|content|menu|hero|banner|wrapper|container)[-_]?\w*$/i,
139
+ // E-commerce
140
+ /^(cart|checkout|payment|shipping|billing|product|price|quantity|order|invoice)[-_]?\w*$/i,
141
+ // Modals/Dialogs
142
+ /^(modal|dialog|popup|overlay|drawer|lightbox)[-_]?(close|open|content|title|body)?$/i,
143
+ // Common patterns
144
+ /^\w{3,}-?\w{3,}/, // At least 3 chars - 3 chars (meaningful)
145
+ ];
146
+ /**
147
+ * Check if ID is auto-generated (NOT stable)
148
+ */
149
+ export function isGeneratedId(id) {
150
+ if (!id || id.length < 2)
151
+ return true;
152
+ return GENERATED_ID_PATTERNS.some(pattern => pattern.test(id));
153
+ }
154
+ /**
155
+ * Check if ID is semantic (describes the PURPOSE)
156
+ */
157
+ export function isSemanticId(id) {
158
+ if (!id || id.length < 2)
159
+ return false;
160
+ return SEMANTIC_ID_PATTERNS.some(p => p.test(id));
161
+ }
162
+ // ═══════════════════════════════════════════════════════════════════════════════
163
+ // UTILITY CLASS PATTERNS (to filter out)
164
+ // ═══════════════════════════════════════════════════════════════════════════════
165
+ /**
166
+ * Patterns for utility classes (Tailwind, Bootstrap, Foundation, generic frameworks)
167
+ *
168
+ * These patterns identify CSS classes that are:
169
+ * - Framework utilities (styling-only, not semantic)
170
+ * - Auto-generated by build tools
171
+ * - Too generic to be reliable selectors
172
+ */
173
+ const UTILITY_CLASS_PATTERNS = [
174
+ // === GENERIC FRAMEWORK PREFIXES (Universal detection) ===
175
+ // Single letter prefixes + hyphen (common in many frameworks)
176
+ /^[a-z]-[a-z][a-z0-9-]*$/, // x-nav-link, b-button, t-link
177
+ /^x-[a-z][a-z0-9-]*$/, // Foundation-style: x-nav-link, x-card
178
+ // Common framework suffixes (modifiers, not semantic)
179
+ /[a-z]--(primary|secondary|success|danger|warning|info|light|dark|sm|md|lg|xl|logo|icon)$/,
180
+ // === TAILWIND CSS ===
181
+ /^-?(m|p)(x|y|t|r|b|l|s|e)?-(\d+|px|auto|\[.+\])$/,
182
+ /^(w|h|min-w|max-w|min-h|max-h)-/,
183
+ /^(flex|inline-flex|block|inline-block|grid|hidden|contents|table|table-row|table-cell)$/,
184
+ /^(items|justify|content|place|self)-(start|end|center|between|around|evenly|stretch|baseline)$/,
185
+ /^(gap|space)-(x|y)-?\d+$/,
186
+ /^(text|font|leading|tracking)-(xs|sm|base|lg|xl|\d+|left|center|right|bold|medium|normal|light)$/,
187
+ /^(bg|text|border|ring|shadow|outline)-(transparent|current|inherit|black|white|\w+-\d+)$/,
188
+ /^(border|rounded)(-none|-sm|-md|-lg|-xl|-2xl|-3xl|-full)?$/,
189
+ /^(opacity|z)-(\d+|auto)$/,
190
+ /^(overflow|whitespace|truncate|break)-/,
191
+ /^(cursor|pointer-events|user-select|resize)-/,
192
+ /^(transition|duration|ease|delay|animate)-/,
193
+ /^(hover|focus|active|disabled|visited|group-hover|peer-\w+|dark|md|lg|xl|sm|2xl|3xl):/,
194
+ /^\[.+\]$/, // Arbitrary values
195
+ /^!/, // Important modifier
196
+ // === BOOTSTRAP ===
197
+ /^(col|offset|order)-(xs|sm|md|lg|xl|xxl)?-?\d*$/,
198
+ /^(d|align|justify)-(none|flex|block|inline|center|start|end)$/,
199
+ /^(m|p)(t|b|s|e|x|y)?-\d+$/,
200
+ /^(text|bg|border|btn)-(primary|secondary|success|danger|warning|info|light|dark)$/,
201
+ // === FOUNDATION (Zurb) ===
202
+ /^x-[a-z]+(-[a-z]+)*$/, // x-nav-link, x-column, x-row
203
+ // === BULMA ===
204
+ /^is-(active|info|success|warning|danger|link|loading|white|black|light|dark)$/,
205
+ /^has-(text|icon|addons)(-\w+)?$/, // has-text, has-icon-*, etc.
206
+ // === MATERIAL UI ===
207
+ /^Mui[A-Z]\w*(-\w+)*$/,
208
+ /^css-[a-z0-9]+$/,
209
+ /^jss\d+$/,
210
+ // === ANT DESIGN ===
211
+ /^ant-[a-z]+(-[a-z]+)*$/,
212
+ // === CHAKRA UI ===
213
+ /^css-[a-z0-9-]+$/,
214
+ // === GENERIC UTILITY CLASSES (Too common to be reliable) ===
215
+ // Single-word very common classes
216
+ /^(btn|button|link|nav|card|header|footer|sidebar|content|body|main|wrapper|container)$/,
217
+ /^(row|col|column|section|article|aside|div|span|text|title|heading)$/,
218
+ /^(left|right|top|bottom|center|middle|icon|logo|image|img)$/,
219
+ /^(small|medium|large|big|tiny|mini|micro|xs|sm|md|lg|xl)$/,
220
+ // Very short classes (less than 4 chars) - likely utilities
221
+ /^[a-z]{1,3}$/,
222
+ // === GENERIC STATE ===
223
+ /^(show|hide|active|inactive|selected|disabled|enabled|loading)$/,
224
+ /^(visible|invisible|hidden|collapsed|expanded|open|closed)$/,
225
+ /^(first|last|odd|even|current)$/,
226
+ // === CSS MODULES (hashed) ===
227
+ /^_[a-zA-Z]+_[a-z0-9]{5,}$/,
228
+ /^[a-zA-Z]+_[a-z0-9]{8,}$/,
229
+ ];
230
+ /**
231
+ * Check if class is a utility class (should be filtered out)
232
+ */
233
+ export function isUtilityClass(cls) {
234
+ if (!cls)
235
+ return true;
236
+ return UTILITY_CLASS_PATTERNS.some(pattern => pattern.test(cls));
237
+ }
238
+ // ═══════════════════════════════════════════════════════════════════════════════
239
+ // INTELLIGENT SELECTOR GENERATOR
240
+ // ═══════════════════════════════════════════════════════════════════════════════
241
+ /**
242
+ * Intelligent Selector Generator
243
+ *
244
+ * Adapts selector generation strategy based on detected site profile.
245
+ */
246
+ export class IntelligentSelectorGenerator {
247
+ siteProfile = null;
248
+ siteAnalysis = null;
249
+ strategy = null;
250
+ /**
251
+ * Initialize the generator with site analysis
252
+ */
253
+ initialize(analysis) {
254
+ this.siteAnalysis = analysis;
255
+ this.siteProfile = this.determineProfile(analysis);
256
+ this.strategy = SELECTOR_STRATEGIES[this.siteProfile];
257
+ this.logProfile();
258
+ }
259
+ /**
260
+ * Get the current site profile
261
+ */
262
+ getProfile() {
263
+ return this.siteProfile;
264
+ }
265
+ /**
266
+ * Get the current strategy
267
+ */
268
+ getStrategy() {
269
+ return this.strategy;
270
+ }
271
+ /**
272
+ * Determine site profile from analysis
273
+ */
274
+ determineProfile(analysis) {
275
+ const testIdRatio = analysis.totalElements > 0
276
+ ? analysis.hasTestIds / analysis.totalElements
277
+ : 0;
278
+ // PROFIL_MODERN: >30% data-testid
279
+ if (testIdRatio > 0.3) {
280
+ return 'PROFIL_MODERN';
281
+ }
282
+ const a11yRatio = analysis.totalElements > 0
283
+ ? analysis.hasAriaLabels / analysis.totalElements
284
+ : 0;
285
+ // PROFIL_ACCESSIBLE: Good ARIA but few testids
286
+ if (a11yRatio > 0.6 && testIdRatio < 0.1) {
287
+ return 'PROFIL_ACCESSIBLE';
288
+ }
289
+ // PROFIL_LEGACY: Poor accessibility and no testids
290
+ if (analysis.accessibilityScore < 30 && testIdRatio < 0.05) {
291
+ return 'PROFIL_LEGACY';
292
+ }
293
+ // PROFIL_MINIMAL: Other cases
294
+ return 'PROFIL_MINIMAL';
295
+ }
296
+ /**
297
+ * Log the detected profile to console
298
+ */
299
+ logProfile() {
300
+ if (!this.siteProfile || !this.siteAnalysis || !this.strategy)
301
+ return;
302
+ console.log('\n' + '═'.repeat(70));
303
+ console.log('🎯 QA360 SITE PROFILER - Stratégie Adaptative');
304
+ console.log('═'.repeat(70));
305
+ console.log(` Profil détecté: ${this.siteProfile}`);
306
+ console.log(` Framework JS: ${this.siteAnalysis.framework || 'non détecté'}`);
307
+ console.log(` Framework CSS: ${this.siteAnalysis.cssFramework || 'non détecté'}`);
308
+ console.log(` Score Testabilité: ${this.siteAnalysis.testabilityScore}%`);
309
+ console.log(` Score Accessibilité: ${this.siteAnalysis.accessibilityScore}%`);
310
+ console.log(` data-testid: ${this.siteAnalysis.hasTestIds} éléments`);
311
+ console.log(` ARIA labels: ${this.siteAnalysis.hasAriaLabels} éléments`);
312
+ console.log('');
313
+ console.log(` ➡️ TIER 1 (priorité): ${this.strategy[0].name} (${this.strategy[0].weight} points)`);
314
+ console.log('═'.repeat(70) + '\n');
315
+ }
316
+ /**
317
+ * Generate optimal selector for an element
318
+ */
319
+ generateSelector(element) {
320
+ // Use default strategy if not initialized
321
+ if (!this.strategy) {
322
+ this.strategy = SELECTOR_STRATEGIES.PROFIL_ACCESSIBLE;
323
+ }
324
+ // Try each tier in order
325
+ for (const tier of this.strategy) {
326
+ const selector = this.trySelector(element, tier.name);
327
+ if (selector) {
328
+ return {
329
+ selector,
330
+ tier: tier.tier,
331
+ type: tier.name,
332
+ weight: tier.weight,
333
+ };
334
+ }
335
+ }
336
+ // Fallback: tag only
337
+ return {
338
+ selector: element.tagName || '*',
339
+ tier: 99,
340
+ type: 'fallback',
341
+ weight: 0,
342
+ };
343
+ }
344
+ /**
345
+ * Try to generate a selector for a specific type
346
+ */
347
+ trySelector(element, type) {
348
+ const { tagName, id, className, attributes = {}, textContent, role, name, value } = element;
349
+ switch (type) {
350
+ case 'testId':
351
+ return this.getTestIdSelector(attributes);
352
+ case 'role+name':
353
+ return this.getRoleNameSelector(role, attributes, name);
354
+ case 'label':
355
+ return this.getLabelSelector(attributes);
356
+ case 'placeholder':
357
+ return this.getPlaceholderSelector(tagName, attributes);
358
+ case 'text':
359
+ return this.getTextSelector(tagName, role, textContent);
360
+ case 'altText':
361
+ return this.getAltTextSelector(tagName, attributes);
362
+ case 'title':
363
+ return this.getTitleSelector(attributes);
364
+ case 'id':
365
+ return this.getIdSelector(id);
366
+ case 'name':
367
+ return this.getNameSelector(tagName, name);
368
+ case 'value':
369
+ return this.getValueSelector(tagName, attributes, value);
370
+ case 'css':
371
+ return this.getCssSelector(tagName, className);
372
+ case 'position':
373
+ return null; // Last resort, avoid
374
+ default:
375
+ return null;
376
+ }
377
+ }
378
+ // ═══════════════════════════════════════════════════════════════════════════════
379
+ // SELECTOR GENERATION METHODS
380
+ // ═══════════════════════════════════════════════════════════════════════════════
381
+ /**
382
+ * TIER 1/7 - Get test ID selector
383
+ */
384
+ getTestIdSelector(attributes) {
385
+ const testIdAttrs = [
386
+ 'data-testid', 'data-cy', 'data-test', 'data-test-id',
387
+ 'data-qa', 'data-automation', 'data-e2e', 'data-selenium'
388
+ ];
389
+ for (const attr of testIdAttrs) {
390
+ if (attributes[attr]) {
391
+ return `[${attr}="${escapeCss(attributes[attr])}"]`;
392
+ }
393
+ }
394
+ return null;
395
+ }
396
+ /**
397
+ * TIER 2/6 - Get role + name selector (ARIA)
398
+ */
399
+ getRoleNameSelector(role, attributes, name) {
400
+ // role + aria-label (BEST semantic selector)
401
+ if (role && attributes['aria-label']) {
402
+ return `[role="${role}"][aria-label="${escapeCss(attributes['aria-label'])}"]`;
403
+ }
404
+ // role + name attribute (for forms)
405
+ if (role && name) {
406
+ return `[role="${role}"][name="${escapeCss(name)}"]`;
407
+ }
408
+ return null;
409
+ }
410
+ /**
411
+ * TIER 3 - Get label selector
412
+ */
413
+ getLabelSelector(attributes) {
414
+ if (attributes['aria-label']) {
415
+ return `[aria-label="${escapeCss(attributes['aria-label'])}"]`;
416
+ }
417
+ if (attributes['aria-labelledby']) {
418
+ return `[aria-labelledby="${escapeCss(attributes['aria-labelledby'])}"]`;
419
+ }
420
+ return null;
421
+ }
422
+ /**
423
+ * TIER 4 - Get placeholder selector
424
+ */
425
+ getPlaceholderSelector(tagName, attributes) {
426
+ if (!attributes.placeholder || !isFormElement(tagName)) {
427
+ return null;
428
+ }
429
+ const type = attributes.type || 'text';
430
+ return `${tagName}[type="${type}"][placeholder="${escapeCss(attributes.placeholder)}"]`;
431
+ }
432
+ /**
433
+ * TIER 5/1 - Get text selector
434
+ */
435
+ getTextSelector(tagName, role, textContent) {
436
+ if (!textContent?.trim() || !isStableTextElement(tagName)) {
437
+ return null;
438
+ }
439
+ const text = textContent.trim();
440
+ // Only if text is short and meaningful
441
+ if (text.length < 2 || text.length > 50) {
442
+ return null;
443
+ }
444
+ // Prefer role + text pattern for interactive elements
445
+ if (role) {
446
+ return `[role="${role}"]:has-text("${escapeCss(text)}")`;
447
+ }
448
+ return `${tagName}:has-text("${escapeCss(text)}")`;
449
+ }
450
+ /**
451
+ * TIER 6/4 - Get alt text selector (images)
452
+ */
453
+ getAltTextSelector(tagName, attributes) {
454
+ if (tagName === 'img' && attributes.alt) {
455
+ return `img[alt="${escapeCss(attributes.alt)}"]`;
456
+ }
457
+ return null;
458
+ }
459
+ /**
460
+ * TIER 7 - Get title selector
461
+ */
462
+ getTitleSelector(attributes) {
463
+ if (attributes.title) {
464
+ return `[title="${escapeCss(attributes.title)}"]`;
465
+ }
466
+ return null;
467
+ }
468
+ /**
469
+ * TIER 8/1 - Get ID selector (semantic only)
470
+ */
471
+ getIdSelector(id) {
472
+ if (id && !isGeneratedId(id)) {
473
+ return `#${escapeCss(id)}`;
474
+ }
475
+ return null;
476
+ }
477
+ /**
478
+ * TIER 2 - Get name selector (for forms)
479
+ */
480
+ getNameSelector(tagName, name) {
481
+ if (name && isFormElement(tagName)) {
482
+ return `${tagName}[name="${escapeCss(name)}"]`;
483
+ }
484
+ return null;
485
+ }
486
+ /**
487
+ * TIER 4 - Get value selector (submit buttons, etc.)
488
+ */
489
+ getValueSelector(tagName, attributes, value) {
490
+ if (attributes.type === 'submit' && isFormElement(tagName)) {
491
+ return `${tagName}[type="submit"]`;
492
+ }
493
+ return null;
494
+ }
495
+ /**
496
+ * TIER 9/7 - Get CSS selector (MAX 2 semantic classes)
497
+ */
498
+ getCssSelector(tagName, className) {
499
+ if (!className)
500
+ return null;
501
+ const semanticClasses = extractSemanticClasses(className);
502
+ if (semanticClasses.length > 0) {
503
+ const selected = semanticClasses.slice(0, 2); // MAX 2 classes
504
+ const classesStr = selected.map(c => `.${escapeCss(c)}`).join('');
505
+ return tagName ? `${tagName}${classesStr}` : classesStr;
506
+ }
507
+ return null;
508
+ }
509
+ }
510
+ // ═══════════════════════════════════════════════════════════════════════════════
511
+ // HELPER FUNCTIONS
512
+ // ═══════════════════════════════════════════════════════════════════════════════
513
+ /**
514
+ * Escape special CSS characters
515
+ */
516
+ function escapeCss(str) {
517
+ if (!str)
518
+ return '';
519
+ return str
520
+ .replace(/\\/g, '\\\\')
521
+ .replace(/"/g, '\\"')
522
+ .replace(/'/g, "\\'")
523
+ .replace(/\n/g, '\\n');
524
+ }
525
+ /**
526
+ * Check if element has stable/significant text content
527
+ */
528
+ function isStableTextElement(tagName) {
529
+ if (!tagName)
530
+ return false;
531
+ const stable = ['button', 'a', 'label', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'th', 'legend', 'summary'];
532
+ return stable.includes(tagName.toLowerCase());
533
+ }
534
+ /**
535
+ * Check if element is a form element
536
+ */
537
+ function isFormElement(tagName) {
538
+ if (!tagName)
539
+ return false;
540
+ const formElements = ['input', 'select', 'textarea', 'button'];
541
+ return formElements.includes(tagName.toLowerCase());
542
+ }
543
+ /**
544
+ * Extract semantic classes (filter out utility classes)
545
+ */
546
+ function extractSemanticClasses(className) {
547
+ const classes = className.split(/\s+/).filter(Boolean);
548
+ return classes.filter(cls => {
549
+ // Reject utility classes
550
+ if (isUtilityClass(cls))
551
+ return false;
552
+ // Keep names that are:
553
+ // - 3-30 characters long
554
+ // - Start with letter, contain only alphanumeric, hyphens, underscores
555
+ return cls.length >= 3 && cls.length <= 30 && /^[a-z][a-z0-9-_]*$/i.test(cls);
556
+ });
557
+ }
558
+ // ═══════════════════════════════════════════════════════════════════════════════
559
+ // GLOBAL INSTANCE AND CONVENIENCE FUNCTIONS
560
+ // ═══════════════════════════════════════════════════════════════════════════════
561
+ /**
562
+ * Global generator instance
563
+ */
564
+ let globalGenerator = null;
565
+ /**
566
+ * Initialize the global generator with site analysis
567
+ */
568
+ export function initializeSelectorGenerator(analysis) {
569
+ globalGenerator = new IntelligentSelectorGenerator();
570
+ globalGenerator.initialize(analysis);
571
+ }
572
+ /**
573
+ * Generate optimal selector for an element (uses global instance)
574
+ */
575
+ export function generateSelector(element) {
576
+ if (!globalGenerator) {
577
+ // Create default instance if not initialized
578
+ globalGenerator = new IntelligentSelectorGenerator();
579
+ // Use PROFIL_ACCESSIBLE as default strategy
580
+ globalGenerator.strategy = SELECTOR_STRATEGIES.PROFIL_ACCESSIBLE;
581
+ }
582
+ const result = globalGenerator.generateSelector(element);
583
+ return result.selector;
584
+ }
585
+ /**
586
+ * Generate selector with metadata (tier, type, weight)
587
+ */
588
+ export function generateSelectorWithMetadata(element) {
589
+ if (!globalGenerator) {
590
+ globalGenerator = new IntelligentSelectorGenerator();
591
+ globalGenerator.strategy = SELECTOR_STRATEGIES.PROFIL_ACCESSIBLE;
592
+ }
593
+ return globalGenerator.generateSelector(element);
594
+ }
595
+ /**
596
+ * Get the current site profile
597
+ */
598
+ export function getSiteProfile() {
599
+ return globalGenerator?.getProfile() || null;
600
+ }
601
+ /**
602
+ * Get the current strategy
603
+ */
604
+ export function getSelectorStrategy() {
605
+ return globalGenerator?.getStrategy() || null;
606
+ }
607
+ // ═══════════════════════════════════════════════════════════════════════════════
608
+ // EXPORT UTILITIES
609
+ // ═══════════════════════════════════════════════════════════════════════════════
610
+ // Note: isGeneratedId, isSemanticId, isUtilityClass are already exported at definition
611
+ // Export strategies for testing/customization
612
+ export { SELECTOR_STRATEGIES };