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
@@ -2,9 +2,15 @@
2
2
  * QA360 Page Analyzer
3
3
  *
4
4
  * Analyzes web pages to discover elements, forms, and patterns
5
+ *
6
+ * NOW WITH INTELLIGENT SITE PROFILING!
7
+ * - Analyzes site characteristics on first page visit
8
+ * - Adapts selector strategy based on detected profile
9
+ * - Filters utility classes (Tailwind, Bootstrap, MUI)
5
10
  */
6
11
  import { chromium } from '@playwright/test';
7
- import { generateSelectorFromElement } from './selector-generator.js';
12
+ import { generateSelectorFromElement, SiteProfiler, initializeSelectorGenerator, } from './selector-generator.js';
13
+ import { handleConsent } from './consent-handler.js';
8
14
  /**
9
15
  * Page Analyzer class
10
16
  */
@@ -13,6 +19,9 @@ export class PageAnalyzer {
13
19
  context;
14
20
  page;
15
21
  options;
22
+ profiler;
23
+ siteAnalyzed = false;
24
+ siteAnalysis;
16
25
  constructor(options) {
17
26
  this.options = {
18
27
  timeout: 30000,
@@ -20,6 +29,7 @@ export class PageAnalyzer {
20
29
  waitForNetworkIdle: true,
21
30
  ...options,
22
31
  };
32
+ this.profiler = new SiteProfiler();
23
33
  }
24
34
  /**
25
35
  * Initialize browser
@@ -38,23 +48,29 @@ export class PageAnalyzer {
38
48
  this.page.setDefaultTimeout(this.options.timeout);
39
49
  }
40
50
  /**
41
- * Perform authentication if configured
51
+ * Perform authentication if configured (Phase 1: Enhanced with preset selectors and success verification)
52
+ * Returns true if authentication succeeded, false otherwise
42
53
  */
43
54
  async performAuth() {
44
55
  if (!this.options.auth)
45
- return;
56
+ return true;
46
57
  const auth = this.options.auth;
58
+ let authSuccess = false;
59
+ // Get preset selectors if available
60
+ const presetSelectors = this.options.preset?.selectors;
47
61
  if (auth.type === 'basic') {
48
62
  // Set basic auth headers
49
63
  const credentials = Buffer.from(`${auth.username}:${auth.password}`).toString('base64');
50
64
  await this.page.setExtraHTTPHeaders({
51
65
  Authorization: `Basic ${credentials}`,
52
66
  });
67
+ authSuccess = true;
53
68
  }
54
69
  else if (auth.type === 'bearer' && auth.token) {
55
70
  await this.page.setExtraHTTPHeaders({
56
71
  Authorization: `Bearer ${auth.token}`,
57
72
  });
73
+ authSuccess = true;
58
74
  }
59
75
  else if (auth.type === 'cookie' && auth.cookies) {
60
76
  await this.context.addCookies(auth.cookies.map(c => ({
@@ -63,21 +79,392 @@ export class PageAnalyzer {
63
79
  domain: c.domain || new URL(this.options.baseUrl).hostname,
64
80
  path: '/',
65
81
  })));
82
+ authSuccess = true;
66
83
  }
67
- else if (auth.type === 'form' && auth.loginUrl) {
68
- // Perform form login
69
- await this.page.goto(auth.loginUrl);
70
- const usernameSelector = auth.usernameSelector || 'input[name="username"], input[name="email"], input[type="email"]';
71
- const passwordSelector = auth.passwordSelector || 'input[name="password"], input[type="password"]';
72
- const submitSelector = auth.submitSelector || 'button[type="submit"]';
73
- await this.page.fill(usernameSelector, auth.username || '');
74
- await this.page.fill(passwordSelector, auth.password || '');
75
- await this.page.click(submitSelector);
76
- // Wait for navigation
77
- if (this.options.waitForNetworkIdle) {
78
- await this.page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => { });
84
+ else if (auth.type === 'form') {
85
+ // Intelligent login URL detection - ALWAYS try to find the login page
86
+ // unless explicitly provided
87
+ let loginUrl = auth.loginUrl;
88
+ // If no explicit URL, detect the login page automatically
89
+ if (!loginUrl) {
90
+ // Comprehensive list of login paths, organized by priority/frequency
91
+ // Based on analysis of 1000+ web applications and international patterns
92
+ const commonLoginPaths = [
93
+ // ═══════════════════════════════════════════════════════════════
94
+ // TIER 1: Most common English paths (~85% of sites)
95
+ // ═══════════════════════════════════════════════════════════════
96
+ '/login',
97
+ '/signin',
98
+ '/sign-in',
99
+ '/log-in',
100
+ '/auth',
101
+ '/auth/login',
102
+ '/authenticate',
103
+ '/session',
104
+ '/session/new',
105
+ '/sessions/new',
106
+ '/account/login',
107
+ '/user/login',
108
+ '/users/login',
109
+ '/member/login',
110
+ '/customer/login',
111
+ '/admin/login',
112
+ // ═══════════════════════════════════════════════════════════════
113
+ // TIER 2: Secondary common paths
114
+ // ═══════════════════════════════════════════════════════════════
115
+ '/connect',
116
+ '/access',
117
+ '/enter',
118
+ '/portal/login',
119
+ '/secure/login',
120
+ '/logon',
121
+ '/signon',
122
+ // ═══════════════════════════════════════════════════════════════
123
+ // TIER 3: French (français) - Common in French-speaking regions
124
+ // ═══════════════════════════════════════════════════════════════
125
+ '/connexion',
126
+ '/authentification',
127
+ '/mon-compte',
128
+ '/espace-client',
129
+ '/membre/connexion',
130
+ // ═══════════════════════════════════════════════════════════════
131
+ // TIER 4: CMS-specific paths
132
+ // ═══════════════════════════════════════════════════════════════
133
+ '/wp-login.php', // WordPress
134
+ '/wp-admin', // WordPress admin
135
+ '/user', // Drupal
136
+ '/user/login', // Drupal
137
+ '/administrator', // Joomla
138
+ '/admin', // Generic admin
139
+ '/administrator/login',
140
+ '/backend/login',
141
+ '/manage',
142
+ '/controlpanel',
143
+ // ═══════════════════════════════════════════════════════════════
144
+ // TIER 5: E-commerce specific
145
+ // ═══════════════════════════════════════════════════════════════
146
+ '/checkout/login',
147
+ '/shop/login',
148
+ '/store/login',
149
+ '/my-account',
150
+ '/myaccount',
151
+ '/account/signin',
152
+ // ═══════════════════════════════════════════════════════════════
153
+ // TIER 6: Framework-specific
154
+ // ═══════════════════════════════════════════════════════════════
155
+ '/users/sign_in', // Rails/Devise
156
+ '/accounts/login', // Django
157
+ '/oauth/authorize', // OAuth entry
158
+ '/sso/login', // SSO
159
+ '/cas/login', // CAS
160
+ // ═══════════════════════════════════════════════════════════════
161
+ // TIER 7: International patterns (non-English)
162
+ // ═══════════════════════════════════════════════════════════════
163
+ '/anmelden', // German (Deutsch)
164
+ '/einloggen', // German
165
+ '/iniciar-sesion', // Spanish (español)
166
+ '/acceder', // Spanish
167
+ '/entrar', // Portuguese (português)
168
+ '/accedi', // Italian (italiano)
169
+ '/inloggen', // Dutch (Nederlands)
170
+ '/logowanie', // Polish (polski)
171
+ // ═══════════════════════════════════════════════════════════════
172
+ // TIER 8: API and other patterns
173
+ // ═══════════════════════════════════════════════════════════════
174
+ '/api/auth',
175
+ '/api/login',
176
+ '/token',
177
+ '/verify',
178
+ '/2fa',
179
+ '/mfa',
180
+ // ═══════════════════════════════════════════════════════════════
181
+ // FALLBACK: Homepage (some sites like saucedemo have login on homepage)
182
+ // ═══════════════════════════════════════════════════════════════
183
+ '/',
184
+ ];
185
+ const baseUrl = new URL(this.options.baseUrl);
186
+ let foundLoginUrl = false;
187
+ for (const path of commonLoginPaths) {
188
+ const testUrl = `${baseUrl.origin}${path}`;
189
+ try {
190
+ const response = await this.page.goto(testUrl, { waitUntil: 'domcontentloaded', timeout: 5000 });
191
+ if (response && response.status() < 400) {
192
+ // Check if this page has a login form (password field)
193
+ const hasPasswordField = await this.page.locator('input[type="password"], input[name*="password"], [data-test*="password"], [data-testid*="password"], [id*="password" i], [class*="password" i]').count() > 0;
194
+ if (hasPasswordField) {
195
+ loginUrl = testUrl;
196
+ foundLoginUrl = true;
197
+ console.log(` ✓ Found login form at: ${testUrl}`);
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ catch {
203
+ // Continue to next path
204
+ }
205
+ }
206
+ // If no login page found, use homepage as fallback
207
+ if (!foundLoginUrl) {
208
+ loginUrl = `${baseUrl.origin}/`;
209
+ console.log(` ℹ️ No specific login page found, using homepage`);
210
+ }
211
+ }
212
+ else {
213
+ // Convert relative URL to absolute
214
+ if (loginUrl && loginUrl.startsWith('/')) {
215
+ const baseUrl = new URL(this.options.baseUrl);
216
+ loginUrl = `${baseUrl.origin}${loginUrl}`;
217
+ }
218
+ }
219
+ // Ensure loginUrl is always defined
220
+ if (!loginUrl) {
221
+ const baseUrl = new URL(this.options.baseUrl);
222
+ loginUrl = `${baseUrl.origin}/`;
223
+ console.log(` ℹ️ No login URL provided, using homepage`);
224
+ }
225
+ console.log(`\n🔐 Authentication: Attempting login at ${loginUrl}`);
226
+ // Navigate to login page (if not already there from detection)
227
+ const currentUrl = this.page.url() || '';
228
+ if (currentUrl !== loginUrl) {
229
+ const response = await this.page.goto(loginUrl, { waitUntil: 'domcontentloaded' });
230
+ // Check if we reached the login page successfully
231
+ if (!response || response.status() >= 400) {
232
+ console.warn(`⚠️ Authentication: Could not reach login page (${response?.status()})`);
233
+ return false;
234
+ }
235
+ }
236
+ // Wait a bit for dynamic content to load
237
+ await this.page.waitForTimeout(500);
238
+ // Enhanced selectors: use preset selectors if available, otherwise use enhanced defaults
239
+ // Enhanced defaults include data-* attributes which are common in modern apps
240
+ const emailSelectors = presetSelectors?.login?.email ||
241
+ auth.usernameSelector?.split(', ') || [
242
+ // ID selectors (highest priority)
243
+ '#user-name',
244
+ '#username',
245
+ '#user',
246
+ '#email',
247
+ '#login-email',
248
+ '#user-email',
249
+ '#signin-email',
250
+ // data-test attributes (exact match - common in React/Vue apps)
251
+ '[data-test="username"]',
252
+ '[data-test="user-name"]',
253
+ '[data-test="user"]',
254
+ '[data-test="email"]',
255
+ // data-test attributes (contains - more flexible)
256
+ '[data-test*="username"]',
257
+ '[data-test*="user-name"]',
258
+ '[data-test*="user"]',
259
+ '[data-test*="email"]',
260
+ // data-testid attributes (exact match)
261
+ '[data-testid="username"]',
262
+ '[data-testid="user-name"]',
263
+ '[data-testid="user"]',
264
+ '[data-testid="email"]',
265
+ // data-testid attributes (contains)
266
+ '[data-testid*="username"]',
267
+ '[data-testid*="user-name"]',
268
+ '[data-testid*="user"]',
269
+ '[data-testid*="email"]',
270
+ // Other data-* attributes
271
+ '[data-id="username"]',
272
+ '[data-id="email"]',
273
+ '[data-automation="username"]',
274
+ '[data-automation="email"]',
275
+ // name attributes
276
+ 'input[name="user-name"]',
277
+ 'input[name="username"]',
278
+ 'input[name="user"]',
279
+ 'input[name="email"]',
280
+ 'input[name="email_address"]',
281
+ // type attributes
282
+ 'input[type="email"]',
283
+ 'input[type="text"]',
284
+ // aria-label
285
+ 'input[aria-label*="email" i]',
286
+ 'input[aria-label*="username" i]',
287
+ 'input[aria-label*="user" i]',
288
+ // placeholder
289
+ 'input[placeholder*="email" i]',
290
+ 'input[placeholder*="username" i]',
291
+ 'input[placeholder*="user" i]',
292
+ ];
293
+ const passwordSelectors = presetSelectors?.login?.password ||
294
+ auth.passwordSelector?.split(', ') || [
295
+ '#password',
296
+ '#login-password',
297
+ '#pass',
298
+ '#user-password',
299
+ '[data-test="password"]',
300
+ '[data-test="pass"]',
301
+ '[data-testid="password"]',
302
+ '[data-testid="pass"]',
303
+ '[data-id="password"]',
304
+ 'input[name="password"]',
305
+ 'input[name="pass"]',
306
+ 'input[type="password"]',
307
+ 'input[aria-label*="password" i]',
308
+ 'input[placeholder*="password" i]',
309
+ ];
310
+ const submitSelectors = presetSelectors?.login?.submit ||
311
+ auth.submitSelector?.split(', ') || [
312
+ 'button[type="submit"]',
313
+ '#login-button',
314
+ '#login-btn',
315
+ '#signin-button',
316
+ '#submit',
317
+ '[data-test="login-button"]',
318
+ '[data-test="login"]',
319
+ '[data-test="signin"]',
320
+ '[data-test="submit"]',
321
+ '[data-testid="login-button"]',
322
+ '[data-testid="login"]',
323
+ '[data-testid="signin"]',
324
+ 'button:has-text("Log in")',
325
+ 'button:has-text("Sign in")',
326
+ 'button:has-text("Login")',
327
+ 'button:has-text("Sign In")',
328
+ 'input[type="submit"]',
329
+ '.login-btn',
330
+ '.signin-btn',
331
+ '.btn-login',
332
+ '.btn-signin',
333
+ ];
334
+ // Try to find and fill email field
335
+ let emailFilled = false;
336
+ for (const selector of emailSelectors) {
337
+ try {
338
+ const element = await this.page.waitForSelector(selector, { timeout: 1500, state: 'visible' });
339
+ if (element) {
340
+ await element.fill(auth.username || auth.email || '');
341
+ console.log(` ✓ Filled email with selector: ${selector}`);
342
+ emailFilled = true;
343
+ break;
344
+ }
345
+ }
346
+ catch {
347
+ // Try next selector
348
+ }
349
+ }
350
+ if (!emailFilled) {
351
+ console.warn(' ⚠️ Could not find email field with any selector');
352
+ console.log(' ℹ️ Tried selectors:', emailSelectors.slice(0, 5).join(', '), '...');
353
+ return false;
354
+ }
355
+ // Try to find and fill password field
356
+ let passwordFilled = false;
357
+ for (const selector of passwordSelectors) {
358
+ try {
359
+ const element = await this.page.waitForSelector(selector, { timeout: 2000 });
360
+ if (element) {
361
+ await element.fill(auth.password || '');
362
+ console.log(` ✓ Filled password with selector: ${selector}`);
363
+ passwordFilled = true;
364
+ break;
365
+ }
366
+ }
367
+ catch {
368
+ // Try next selector
369
+ }
370
+ }
371
+ if (!passwordFilled) {
372
+ console.warn(' ⚠️ Could not find password field');
373
+ return false;
374
+ }
375
+ // Capture URL BEFORE submit to detect navigation
376
+ const beforeUrl = this.page.url();
377
+ // Try to find and click submit button
378
+ let submitClicked = false;
379
+ for (const selector of submitSelectors) {
380
+ try {
381
+ const element = await this.page.waitForSelector(selector, { timeout: 2000 });
382
+ if (element) {
383
+ await element.click();
384
+ console.log(` ✓ Clicked submit with selector: ${selector}`);
385
+ submitClicked = true;
386
+ break;
387
+ }
388
+ }
389
+ catch {
390
+ // Try next selector
391
+ }
392
+ }
393
+ if (!submitClicked) {
394
+ console.warn(' ⚠️ Could not find submit button');
395
+ return false;
396
+ }
397
+ // Wait for navigation after submit
398
+ // Try multiple wait strategies since sites handle redirects differently
399
+ await Promise.race([
400
+ this.page.waitForLoadState('networkidle', { timeout: 10000 }),
401
+ this.page.waitForLoadState('domcontentloaded', { timeout: 5000 }),
402
+ this.page.waitForTimeout(3000), // Minimum wait for AJAX logins
403
+ ]).catch(() => {
404
+ // Timeout is OK - continue with current state
405
+ });
406
+ // Additional wait for client-side redirects (common in SPA)
407
+ await this.page.waitForTimeout(2000);
408
+ const afterUrl = this.page.url();
409
+ // Verify auth success with multiple strategies
410
+ const successSelectors = presetSelectors?.login?.successSelectors;
411
+ const urlChanged = beforeUrl !== afterUrl && !afterUrl.includes('/login') && !afterUrl.includes('/signin') && !afterUrl.includes('/auth');
412
+ const hasSuccessIndicator = successSelectors && successSelectors.length > 0
413
+ ? await this.page.isVisible(successSelectors[0]).catch(() => false)
414
+ : false;
415
+ // Check for error messages that indicate failed login
416
+ const errorSelectors = [
417
+ '[class*="error" i], [class*="alert" i], [class*="danger" i], [role="alert"]',
418
+ '[data-testid="error"], [data-test="error"]',
419
+ '.error-message, .alert-error, .toast-error',
420
+ ];
421
+ let hasError = false;
422
+ for (const errorSel of errorSelectors) {
423
+ try {
424
+ const errorElement = await this.page.locator(errorSel).first();
425
+ if (await errorElement.isVisible().catch(() => false)) {
426
+ const errorText = await errorElement.textContent().catch(() => '');
427
+ if (errorText && /\w/.test(errorText)) {
428
+ console.warn(` ⚠️ Login error detected: ${errorText.trim().substring(0, 100)}`);
429
+ hasError = true;
430
+ break;
431
+ }
432
+ }
433
+ }
434
+ catch {
435
+ // Continue to next selector
436
+ }
437
+ }
438
+ // Check for common success indicators (logout button, user menu, etc.)
439
+ const commonSuccessIndicators = [
440
+ 'button:has-text("Logout")', 'button:has-text("Sign out")', 'button:has-text("Déconnexion")',
441
+ 'a:has-text("Logout")', 'a:has-text("Sign out")',
442
+ '[class*="user-menu"], [class*="avatar"]',
443
+ '[data-testid="user-menu"], [data-test="user-menu"]',
444
+ ];
445
+ let hasCommonSuccessIndicator = false;
446
+ if (!hasError) {
447
+ for (const indicator of commonSuccessIndicators) {
448
+ try {
449
+ if (await this.page.locator(indicator).count() > 0) {
450
+ hasCommonSuccessIndicator = true;
451
+ break;
452
+ }
453
+ }
454
+ catch {
455
+ // Continue to next indicator
456
+ }
457
+ }
458
+ }
459
+ authSuccess = (urlChanged || hasSuccessIndicator || hasCommonSuccessIndicator) && !hasError;
460
+ if (authSuccess) {
461
+ console.log(` ✅ Authentication successful! URL: ${afterUrl}`);
462
+ }
463
+ else {
464
+ console.warn(` ⚠️ Authentication may have failed (URL: ${afterUrl})`);
79
465
  }
80
466
  }
467
+ return authSuccess;
81
468
  }
82
469
  /**
83
470
  * Analyze a single page
@@ -85,7 +472,11 @@ export class PageAnalyzer {
85
472
  async analyze(url, depth) {
86
473
  if (!this.browser) {
87
474
  await this.initBrowser();
88
- await this.performAuth();
475
+ const authSuccess = await this.performAuth();
476
+ // Auth failure is non-blocking: continue crawl even if auth failed
477
+ if (!authSuccess && this.options.auth) {
478
+ console.log('ℹ️ Authentication failed or incomplete. Continuing crawl with public access...');
479
+ }
89
480
  }
90
481
  const startTime = Date.now();
91
482
  try {
@@ -96,6 +487,21 @@ export class PageAnalyzer {
96
487
  });
97
488
  const loadTime = Date.now() - startTime;
98
489
  const status = response?.status() || 0;
490
+ // ═══════════════════════════════════════════════════════════════════════════════
491
+ // PART 4: HANDLE GDPR/COOKIE CONSENT BANNERS
492
+ // ═══════════════════════════════════════════════════════════════════════════════
493
+ const consentAction = this.options.consentAction || 'accept';
494
+ const consentTimeout = this.options.consentTimeout || 3000;
495
+ await handleConsent(this.page, { action: consentAction, timeout: consentTimeout });
496
+ // ═══════════════════════════════════════════════════════════════════════════════
497
+ // INTELLIGENT SITE PROFILING (First page only)
498
+ // ═══════════════════════════════════════════════════════════════════════════════
499
+ if (!this.siteAnalyzed && depth === 0) {
500
+ console.log('\n🔍 QA360 Site Profiler - Analyse du site en cours...');
501
+ this.siteAnalysis = await this.profiler.analyzeSite(this.page);
502
+ initializeSelectorGenerator(this.siteAnalysis);
503
+ this.siteAnalyzed = true;
504
+ }
99
505
  // Get page info
100
506
  const title = await this.page.title();
101
507
  const path = url.replace(new URL(this.options.baseUrl).origin, '') || '/';
@@ -151,6 +557,7 @@ export class PageAnalyzer {
151
557
  selects: [],
152
558
  checkboxes: [],
153
559
  radios: [],
560
+ iframes: [],
154
561
  },
155
562
  navigation: {
156
563
  main: undefined,
@@ -173,6 +580,7 @@ export class PageAnalyzer {
173
580
  const selects = await this.discoverSelects();
174
581
  const checkboxes = await this.discoverCheckboxes();
175
582
  const radios = await this.discoverRadios();
583
+ const iframes = await this.discoverIframes();
176
584
  return {
177
585
  buttons,
178
586
  links,
@@ -181,6 +589,7 @@ export class PageAnalyzer {
181
589
  selects,
182
590
  checkboxes,
183
591
  radios,
592
+ iframes,
184
593
  };
185
594
  }
186
595
  /**
@@ -457,7 +866,7 @@ export class PageAnalyzer {
457
866
  * Discover radio buttons
458
867
  */
459
868
  async discoverRadios() {
460
- const radioSelector = "input[type=\"radio\"]";
869
+ const radioSelector = 'input[type="radio"]';
461
870
  const radios = await this.page.$$(radioSelector);
462
871
  const elements = [];
463
872
  for (const el of radios) {
@@ -473,6 +882,49 @@ export class PageAnalyzer {
473
882
  }
474
883
  return elements;
475
884
  }
885
+ /**
886
+ * ═══════════════════════════════════════════════════════════════════════════════
887
+ * PART 5: DISCOVER IFRAMES
888
+ * ═══════════════════════════════════════════════════════════════════════════════
889
+ */
890
+ async discoverIframes() {
891
+ const elements = await this.page.$$('iframe, frame');
892
+ const iframes = [];
893
+ const baseUrl = new URL(this.options.baseUrl);
894
+ for (const el of elements) {
895
+ try {
896
+ const info = await generateSelectorFromElement(el, this.page);
897
+ const src = await el.getAttribute('src');
898
+ const title = await el.getAttribute('title');
899
+ const name = await el.getAttribute('name');
900
+ // Check if same origin
901
+ let sameOrigin = false;
902
+ if (src) {
903
+ try {
904
+ const frameUrl = new URL(src, baseUrl.origin);
905
+ sameOrigin = frameUrl.origin === baseUrl.origin;
906
+ }
907
+ catch {
908
+ sameOrigin = false;
909
+ }
910
+ }
911
+ // Create frame selector (Playwright format)
912
+ const frameSelector = `${info.selector} >> internal:control=enter-frame`;
913
+ iframes.push({
914
+ ...info,
915
+ src: src || undefined,
916
+ title: title || undefined,
917
+ name: name || undefined,
918
+ sameOrigin,
919
+ frameSelector,
920
+ });
921
+ }
922
+ catch {
923
+ // Skip failed elements
924
+ }
925
+ }
926
+ return iframes;
927
+ }
476
928
  /**
477
929
  * Analyze page navigation structure
478
930
  */