@silasfmartins/testhub 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/.github/copilot-instructions.md +520 -0
  2. package/biome.json +37 -0
  3. package/dist/index.d.ts +45 -0
  4. package/dist/index.js +169 -0
  5. package/dist/scripts/consumer-postinstall.d.ts +15 -0
  6. package/dist/scripts/consumer-postinstall.js +785 -0
  7. package/dist/scripts/generate-docs.d.ts +16 -0
  8. package/dist/scripts/generate-docs.js +1363 -0
  9. package/dist/scripts/generate-index.d.ts +2 -0
  10. package/dist/scripts/generate-index.js +314 -0
  11. package/dist/scripts/init-api.d.ts +2 -0
  12. package/dist/scripts/init-api.js +525 -0
  13. package/dist/scripts/init-banco.d.ts +2 -0
  14. package/dist/scripts/init-banco.js +347 -0
  15. package/dist/scripts/init-frontend.d.ts +2 -0
  16. package/dist/scripts/init-frontend.js +627 -0
  17. package/dist/scripts/init-mobile.d.ts +2 -0
  18. package/dist/scripts/init-mobile.js +481 -0
  19. package/dist/scripts/init-scenarios.d.ts +2 -0
  20. package/dist/scripts/init-scenarios.js +846 -0
  21. package/dist/scripts/init-ssh.d.ts +2 -0
  22. package/dist/scripts/init-ssh.js +639 -0
  23. package/dist/scripts/package-versions.d.ts +57 -0
  24. package/dist/scripts/package-versions.js +768 -0
  25. package/dist/scripts/postinstall.d.ts +1 -0
  26. package/dist/scripts/postinstall.js +527 -0
  27. package/dist/scripts/robust-build.d.ts +7 -0
  28. package/dist/scripts/robust-build.js +88 -0
  29. package/dist/scripts/setup-local-packages.d.ts +31 -0
  30. package/dist/scripts/setup-local-packages.js +237 -0
  31. package/dist/scripts/smart-override.d.ts +2 -0
  32. package/dist/scripts/smart-override.js +1360 -0
  33. package/dist/scripts/sync-configs.d.ts +27 -0
  34. package/dist/scripts/sync-configs.js +248 -0
  35. package/dist/scripts/test-biome-parse.d.ts +5 -0
  36. package/dist/scripts/test-biome-parse.js +84 -0
  37. package/dist/scripts/ultracite-setup.d.ts +4 -0
  38. package/dist/scripts/ultracite-setup.js +310 -0
  39. package/dist/scripts/update-all-init-scripts.d.ts +2 -0
  40. package/dist/scripts/update-all-init-scripts.js +52 -0
  41. package/dist/scripts/update-biome-schema.d.ts +15 -0
  42. package/dist/scripts/update-biome-schema.js +124 -0
  43. package/dist/src/AutoCoreFacade.d.ts +145 -0
  44. package/dist/src/AutoCoreFacade.js +217 -0
  45. package/dist/src/api/ApiActions.d.ts +297 -0
  46. package/dist/src/api/ApiActions.js +1905 -0
  47. package/dist/src/api/Certificate.d.ts +60 -0
  48. package/dist/src/api/Certificate.js +79 -0
  49. package/dist/src/api/JsonResponse.d.ts +116 -0
  50. package/dist/src/api/JsonResponse.js +206 -0
  51. package/dist/src/appium/DeviceFarmViewer.d.ts +79 -0
  52. package/dist/src/appium/DeviceFarmViewer.js +1083 -0
  53. package/dist/src/appium/MobileActions.d.ts +347 -0
  54. package/dist/src/appium/MobileActions.js +1632 -0
  55. package/dist/src/appium/MobileConnection.d.ts +160 -0
  56. package/dist/src/appium/MobileConnection.js +772 -0
  57. package/dist/src/config/envLoader.d.ts +123 -0
  58. package/dist/src/config/envLoader.js +361 -0
  59. package/dist/src/config/jest-safe-setup.d.ts +19 -0
  60. package/dist/src/config/jest-safe-setup.js +369 -0
  61. package/dist/src/config/timeouts.d.ts +32 -0
  62. package/dist/src/config/timeouts.js +38 -0
  63. package/dist/src/desktop/DesktopActions.d.ts +46 -0
  64. package/dist/src/desktop/DesktopActions.js +398 -0
  65. package/dist/src/desktop/DesktopConnection.d.ts +32 -0
  66. package/dist/src/desktop/DesktopConnection.js +84 -0
  67. package/dist/src/domain/entities/TestExecution.d.ts +117 -0
  68. package/dist/src/domain/entities/TestExecution.js +150 -0
  69. package/dist/src/domain/entities/TestReport.d.ts +114 -0
  70. package/dist/src/domain/entities/TestReport.js +179 -0
  71. package/dist/src/domain/repositories/ITestRepository.d.ts +196 -0
  72. package/dist/src/domain/repositories/ITestRepository.js +14 -0
  73. package/dist/src/domain/schemas/ValidationSchemas.d.ts +159 -0
  74. package/dist/src/domain/schemas/ValidationSchemas.js +181 -0
  75. package/dist/src/functions/errors/BaseError.d.ts +78 -0
  76. package/dist/src/functions/errors/BaseError.js +245 -0
  77. package/dist/src/functions/errors/ConfigurationError.d.ts +16 -0
  78. package/dist/src/functions/errors/ConfigurationError.js +48 -0
  79. package/dist/src/functions/errors/ErrorCatalog.d.ts +148 -0
  80. package/dist/src/functions/errors/ErrorCatalog.js +157 -0
  81. package/dist/src/functions/errors/GlobalErrorHandler.d.ts +101 -0
  82. package/dist/src/functions/errors/GlobalErrorHandler.js +281 -0
  83. package/dist/src/functions/errors/IntegrationError.d.ts +17 -0
  84. package/dist/src/functions/errors/IntegrationError.js +51 -0
  85. package/dist/src/functions/errors/SecurityError.d.ts +14 -0
  86. package/dist/src/functions/errors/SecurityError.js +42 -0
  87. package/dist/src/functions/errors/SystemError.d.ts +12 -0
  88. package/dist/src/functions/errors/SystemError.js +36 -0
  89. package/dist/src/functions/errors/ValidationError.d.ts +14 -0
  90. package/dist/src/functions/errors/ValidationError.js +61 -0
  91. package/dist/src/functions/errors/index.d.ts +12 -0
  92. package/dist/src/functions/errors/index.js +13 -0
  93. package/dist/src/global-setup.d.ts +1 -0
  94. package/dist/src/global-setup.js +1037 -0
  95. package/dist/src/helpers/BancoActions.d.ts +188 -0
  96. package/dist/src/helpers/BancoActions.js +581 -0
  97. package/dist/src/helpers/EnviromentHelper.d.ts +17 -0
  98. package/dist/src/helpers/EnviromentHelper.js +66 -0
  99. package/dist/src/helpers/ParallelExecutionHelper.d.ts +183 -0
  100. package/dist/src/helpers/ParallelExecutionHelper.js +375 -0
  101. package/dist/src/helpers/SyncSignal.d.ts +15 -0
  102. package/dist/src/helpers/SyncSignal.js +44 -0
  103. package/dist/src/hubdocs/CategoryDetector.d.ts +83 -0
  104. package/dist/src/hubdocs/CategoryDetector.js +401 -0
  105. package/dist/src/hubdocs/DirectStatementInterceptor.d.ts +54 -0
  106. package/dist/src/hubdocs/DirectStatementInterceptor.js +243 -0
  107. package/dist/src/hubdocs/ExecutionTracker.d.ts +107 -0
  108. package/dist/src/hubdocs/ExecutionTracker.js +702 -0
  109. package/dist/src/hubdocs/HubDocs.d.ts +395 -0
  110. package/dist/src/hubdocs/HubDocs.js +3586 -0
  111. package/dist/src/hubdocs/StatementMethodFilter.d.ts +71 -0
  112. package/dist/src/hubdocs/StatementMethodFilter.js +618 -0
  113. package/dist/src/hubdocs/StatementTracker.d.ts +417 -0
  114. package/dist/src/hubdocs/StatementTracker.js +2419 -0
  115. package/dist/src/hubdocs/SwaggerGenerator.d.ts +59 -0
  116. package/dist/src/hubdocs/SwaggerGenerator.js +405 -0
  117. package/dist/src/hubdocs/index.d.ts +9 -0
  118. package/dist/src/hubdocs/index.js +9 -0
  119. package/dist/src/hubdocs/types.d.ts +114 -0
  120. package/dist/src/hubdocs/types.js +5 -0
  121. package/dist/src/infrastructure/DependencyContainer.d.ts +142 -0
  122. package/dist/src/infrastructure/DependencyContainer.js +250 -0
  123. package/dist/src/infrastructure/adapters/AppiumAdapter.d.ts +168 -0
  124. package/dist/src/infrastructure/adapters/AppiumAdapter.js +468 -0
  125. package/dist/src/infrastructure/adapters/OracleAdapter.d.ts +150 -0
  126. package/dist/src/infrastructure/adapters/OracleAdapter.js +388 -0
  127. package/dist/src/infrastructure/adapters/PlaywrightAdapter.d.ts +192 -0
  128. package/dist/src/infrastructure/adapters/PlaywrightAdapter.js +382 -0
  129. package/dist/src/infrastructure/adapters/SSHAdapter.d.ts +141 -0
  130. package/dist/src/infrastructure/adapters/SSHAdapter.js +428 -0
  131. package/dist/src/interfaces.d.ts +501 -0
  132. package/dist/src/interfaces.js +25 -0
  133. package/dist/src/internal/fakes/__fake-actions__.d.ts +17 -0
  134. package/dist/src/internal/fakes/__fake-actions__.js +21 -0
  135. package/dist/src/internal/fakes/__forbidden__.d.ts +10 -0
  136. package/dist/src/internal/fakes/__forbidden__.js +18 -0
  137. package/dist/src/internal/fakes/__honeypot__.d.ts +15 -0
  138. package/dist/src/internal/fakes/__honeypot__.js +24 -0
  139. package/dist/src/octane/OctaneReporter.d.ts +13 -0
  140. package/dist/src/octane/OctaneReporter.js +61 -0
  141. package/dist/src/playwright/CryptoActions.d.ts +20 -0
  142. package/dist/src/playwright/CryptoActions.js +75 -0
  143. package/dist/src/playwright/EnhancedWebActions.d.ts +7 -0
  144. package/dist/src/playwright/EnhancedWebActions.js +65 -0
  145. package/dist/src/playwright/WebActions.d.ts +1599 -0
  146. package/dist/src/playwright/WebActions.js +11788 -0
  147. package/dist/src/playwright/actions/ActionTimeline.d.ts +36 -0
  148. package/dist/src/playwright/actions/ActionTimeline.js +101 -0
  149. package/dist/src/playwright/actions/RecoveryQueue.d.ts +82 -0
  150. package/dist/src/playwright/actions/RecoveryQueue.js +130 -0
  151. package/dist/src/playwright/actions/SelectorCache.d.ts +53 -0
  152. package/dist/src/playwright/actions/SelectorCache.js +96 -0
  153. package/dist/src/playwright/actions/index.d.ts +13 -0
  154. package/dist/src/playwright/actions/index.js +14 -0
  155. package/dist/src/playwright/actions/types.d.ts +147 -0
  156. package/dist/src/playwright/actions/types.js +5 -0
  157. package/dist/src/playwright/fixtures.d.ts +112 -0
  158. package/dist/src/playwright/fixtures.js +718 -0
  159. package/dist/src/playwright/network-logs-reporter.d.ts +7 -0
  160. package/dist/src/playwright/network-logs-reporter.js +66 -0
  161. package/dist/src/playwright/registerRecoveryWrappers.d.ts +1 -0
  162. package/dist/src/playwright/registerRecoveryWrappers.js +54 -0
  163. package/dist/src/security/BuildSecurity.d.ts +12 -0
  164. package/dist/src/security/BuildSecurity.js +138 -0
  165. package/dist/src/security/EulaProtection.d.ts +70 -0
  166. package/dist/src/security/EulaProtection.js +155 -0
  167. package/dist/src/security/HoneypotManager.d.ts +46 -0
  168. package/dist/src/security/HoneypotManager.js +234 -0
  169. package/dist/src/security/KeysManager.d.ts +36 -0
  170. package/dist/src/security/KeysManager.js +158 -0
  171. package/dist/src/security/ProofOfWorkIntegration.d.ts +64 -0
  172. package/dist/src/security/ProofOfWorkIntegration.js +206 -0
  173. package/dist/src/security/SecurityValidation.d.ts +21 -0
  174. package/dist/src/security/SecurityValidation.js +163 -0
  175. package/dist/src/security/SourceMapProtection.d.ts +55 -0
  176. package/dist/src/security/SourceMapProtection.js +220 -0
  177. package/dist/src/security/protector.d.ts +1 -0
  178. package/dist/src/security/protector.js +97 -0
  179. package/dist/src/ssh/SSHActions.d.ts +262 -0
  180. package/dist/src/ssh/SSHActions.js +790 -0
  181. package/dist/src/ssh/SSHClient.d.ts +99 -0
  182. package/dist/src/ssh/SSHClient.js +409 -0
  183. package/dist/src/statements/BaseStatement.d.ts +38 -0
  184. package/dist/src/statements/BaseStatement.js +78 -0
  185. package/dist/src/testContext/AuthStateManager.d.ts +93 -0
  186. package/dist/src/testContext/AuthStateManager.js +256 -0
  187. package/dist/src/testContext/CoverageManager.d.ts +198 -0
  188. package/dist/src/testContext/CoverageManager.js +917 -0
  189. package/dist/src/testContext/TestAnnotations.d.ts +476 -0
  190. package/dist/src/testContext/TestAnnotations.js +2647 -0
  191. package/dist/src/testContext/TestContext.d.ts +138 -0
  192. package/dist/src/testContext/TestContext.js +369 -0
  193. package/dist/src/testContext/UnifiedHtmlGenerator.d.ts +7 -0
  194. package/dist/src/testContext/UnifiedHtmlGenerator.js +264 -0
  195. package/dist/src/testContext/UnifiedReportManager.d.ts +211 -0
  196. package/dist/src/testContext/UnifiedReportManager.js +1206 -0
  197. package/dist/src/testhub/DynamicConfigManager.d.ts +121 -0
  198. package/dist/src/testhub/DynamicConfigManager.js +320 -0
  199. package/dist/src/testhub/SystemsManager.d.ts +119 -0
  200. package/dist/src/testhub/SystemsManager.js +365 -0
  201. package/dist/src/testhub/TestHubClient.d.ts +335 -0
  202. package/dist/src/testhub/TestHubClient.js +1215 -0
  203. package/dist/src/testhub/TestHubReporter.d.ts +62 -0
  204. package/dist/src/testhub/TestHubReporter.js +576 -0
  205. package/dist/src/testhub/TestHubVars.d.ts +116 -0
  206. package/dist/src/testhub/TestHubVars.js +273 -0
  207. package/dist/src/utils/ActionInterceptor.d.ts +59 -0
  208. package/dist/src/utils/ActionInterceptor.js +741 -0
  209. package/dist/src/utils/ArtifactsCompressor.d.ts +43 -0
  210. package/dist/src/utils/ArtifactsCompressor.js +181 -0
  211. package/dist/src/utils/AutoLogsFinal.d.ts +47 -0
  212. package/dist/src/utils/AutoLogsFinal.js +148 -0
  213. package/dist/src/utils/CodeGenSession.d.ts +114 -0
  214. package/dist/src/utils/CodeGenSession.js +264 -0
  215. package/dist/src/utils/ConfigLogger.d.ts +133 -0
  216. package/dist/src/utils/ConfigLogger.js +611 -0
  217. package/dist/src/utils/CustomReporter.d.ts +22 -0
  218. package/dist/src/utils/CustomReporter.js +352 -0
  219. package/dist/src/utils/DataStore.d.ts +171 -0
  220. package/dist/src/utils/DataStore.js +484 -0
  221. package/dist/src/utils/DatabaseInterceptor.d.ts +19 -0
  222. package/dist/src/utils/DatabaseInterceptor.js +295 -0
  223. package/dist/src/utils/DateHelper.d.ts +16 -0
  224. package/dist/src/utils/DateHelper.js +120 -0
  225. package/dist/src/utils/DateValidator.d.ts +4 -0
  226. package/dist/src/utils/DateValidator.js +51 -0
  227. package/dist/src/utils/DocumentGenerator.d.ts +35 -0
  228. package/dist/src/utils/DocumentGenerator.js +129 -0
  229. package/dist/src/utils/EvidenceCapture.d.ts +90 -0
  230. package/dist/src/utils/EvidenceCapture.js +600 -0
  231. package/dist/src/utils/EvidenceReportGenerator.d.ts +70 -0
  232. package/dist/src/utils/EvidenceReportGenerator.js +799 -0
  233. package/dist/src/utils/FrameManagementUtil.d.ts +42 -0
  234. package/dist/src/utils/FrameManagementUtil.js +75 -0
  235. package/dist/src/utils/GlobalStatementsInterceptor.d.ts +1 -0
  236. package/dist/src/utils/GlobalStatementsInterceptor.js +1 -0
  237. package/dist/src/utils/HTMLTemplate.d.ts +1 -0
  238. package/dist/src/utils/HTMLTemplate.js +1034 -0
  239. package/dist/src/utils/InterceptacaoMagica.d.ts +23 -0
  240. package/dist/src/utils/InterceptacaoMagica.js +365 -0
  241. package/dist/src/utils/LogSanitizer.d.ts +35 -0
  242. package/dist/src/utils/LogSanitizer.js +110 -0
  243. package/dist/src/utils/Logger.d.ts +65 -0
  244. package/dist/src/utils/Logger.js +284 -0
  245. package/dist/src/utils/McpLocalClient.d.ts +141 -0
  246. package/dist/src/utils/McpLocalClient.js +871 -0
  247. package/dist/src/utils/PDFEvidenceGenerator.d.ts +20 -0
  248. package/dist/src/utils/PDFEvidenceGenerator.js +156 -0
  249. package/dist/src/utils/SpecFileAnalyzer.d.ts +35 -0
  250. package/dist/src/utils/SpecFileAnalyzer.js +209 -0
  251. package/dist/src/utils/StatementInterceptor.d.ts +18 -0
  252. package/dist/src/utils/StatementInterceptor.js +87 -0
  253. package/dist/src/utils/StatementLogger.d.ts +33 -0
  254. package/dist/src/utils/StatementLogger.js +113 -0
  255. package/dist/src/utils/StatementsInterceptor.d.ts +1 -0
  256. package/dist/src/utils/StatementsInterceptor.js +1 -0
  257. package/dist/src/utils/TeamsFlushHook.d.ts +17 -0
  258. package/dist/src/utils/TeamsFlushHook.js +168 -0
  259. package/dist/src/utils/TerminalLogCapture.d.ts +158 -0
  260. package/dist/src/utils/TerminalLogCapture.js +531 -0
  261. package/dist/src/utils/TestMethodLogger.d.ts +70 -0
  262. package/dist/src/utils/TestMethodLogger.js +95 -0
  263. package/dist/src/utils/UnifiedTeardown.d.ts +4 -0
  264. package/dist/src/utils/UnifiedTeardown.js +400 -0
  265. package/dist/src/utils/XPathCatalog.d.ts +152 -0
  266. package/dist/src/utils/XPathCatalog.js +350 -0
  267. package/dist/src/utils/generators.d.ts +90 -0
  268. package/dist/src/utils/generators.js +167 -0
  269. package/dist/src/utils/testRecovery/ResilientPlaywright.d.ts +152 -0
  270. package/dist/src/utils/testRecovery/ResilientPlaywright.js +715 -0
  271. package/dist/src/utils/testRecovery/TestRecoveryClient.d.ts +801 -0
  272. package/dist/src/utils/testRecovery/TestRecoveryClient.js +1415 -0
  273. package/dist/src/utils/testRecovery/autoFixCode.d.ts +65 -0
  274. package/dist/src/utils/testRecovery/autoFixCode.js +32 -0
  275. package/dist/vitest.config.d.ts +2 -0
  276. package/dist/vitest.config.js +59 -0
  277. package/dist/wdio.conf.d.ts +1 -0
  278. package/dist/wdio.conf.js +420 -0
  279. package/package.json +137 -0
  280. package/protect-loader.mjs +643 -0
  281. package/scripts/consumer-postinstall.ts +975 -0
  282. package/scripts/generate-index.ts +343 -0
  283. package/scripts/init-api.ts +613 -0
  284. package/scripts/init-banco.ts +437 -0
  285. package/scripts/init-frontend.ts +727 -0
  286. package/scripts/init-mobile.ts +558 -0
  287. package/scripts/init-scenarios.ts +925 -0
  288. package/scripts/init-ssh.ts +734 -0
  289. package/scripts/package-versions.ts +978 -0
  290. package/scripts/postinstall.ts +605 -0
  291. package/scripts/smart-override.ts +1675 -0
  292. package/scripts/sync-configs.ts +302 -0
  293. package/scripts/ultracite-setup.ts +370 -0
  294. package/src/types/globals.d.ts +48 -0
  295. package/tsconfig.json +29 -0
  296. package/types/autocore-sync-signal.d.ts +10 -0
@@ -0,0 +1,350 @@
1
+ /**
2
+ * XPath Catalog (v2.7.44 - items 17, 18, 19 & 21)
3
+ *
4
+ * Mantém catálogo de XPaths por página, atualizado via `extract_page_structure`,
5
+ * e oferece resolução inteligente para métodos de ação (click, fill, select…).
6
+ *
7
+ * Item 17 — `extractPageStructure` como base para catálogo
8
+ * Item 18 — `getCurrentXPathCatalog` + resolver interno
9
+ * Item 19 — Geração de `.autocore/xpaths.generated.ts` para IntelliSense
10
+ * Item 21 — `pushToBackend` para execuções Azure sem agente de IA
11
+ */
12
+ import * as fs from 'fs';
13
+ import * as path from 'path';
14
+ import { Logger } from './Logger.js';
15
+ let _extractor = null;
16
+ const DEFAULT_TTL_MS = 60_000;
17
+ /** Normaliza URL para chave de cache (remove query/hash) */
18
+ function normalizePageKey(url) {
19
+ try {
20
+ const u = new URL(url);
21
+ return `${u.origin}${u.pathname}`.replace(/\/+$/, '').toLowerCase();
22
+ }
23
+ catch {
24
+ return url.toLowerCase().replace(/[?#].*$/, '').replace(/\/+$/, '');
25
+ }
26
+ }
27
+ // Cache interno
28
+ const _cache = new Map();
29
+ // ---------------------------------------------------------------------------
30
+ // XPathCatalog
31
+ // ---------------------------------------------------------------------------
32
+ export class XPathCatalog {
33
+ /** Injeta extrator de estrutura de página (obrigatório antes de usar) */
34
+ static setExtractor(fn) {
35
+ _extractor = fn;
36
+ }
37
+ /**
38
+ * Obtém catálogo de XPaths para a página fornecida (ou a página atual).
39
+ *
40
+ * @param currentPageUrl URL da página atual (usada quando opts.page não informado)
41
+ * @param opts Opções de consulta
42
+ */
43
+ static async getCatalog(currentPageUrl, opts) {
44
+ const pageUrl = opts?.page || currentPageUrl;
45
+ const pageKey = normalizePageKey(pageUrl);
46
+ const strictPage = opts?.strictPage ?? true;
47
+ const maxItems = opts?.maxItems ?? 200;
48
+ // Verificar cache (se não forçar refresh)
49
+ if (!opts?.refresh) {
50
+ const cached = _cache.get(pageKey);
51
+ if (cached && Date.now() - cached.updatedAt < DEFAULT_TTL_MS) {
52
+ return XPathCatalog.applyFilter(cached.items, opts?.filter, maxItems);
53
+ }
54
+ }
55
+ // Extrair estrutura da página
56
+ const items = await XPathCatalog.refresh(pageUrl);
57
+ // Filtrar
58
+ let result = XPathCatalog.applyFilter(items, opts?.filter, maxItems);
59
+ // Cross-page fallback
60
+ if (result.length === 0 && !strictPage && opts?.filter) {
61
+ for (const [, entry] of _cache) {
62
+ const crossItems = XPathCatalog.applyFilter(entry.items, opts.filter, maxItems);
63
+ if (crossItems.length > 0) {
64
+ result = crossItems;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+ /**
72
+ * Recarrega a estrutura da página e atualiza o cache.
73
+ */
74
+ static async refresh(pageUrl) {
75
+ if (!_extractor) {
76
+ Logger.warning('[XPathCatalog] Extrator de página não configurado. Use XPathCatalog.setExtractor().');
77
+ return [];
78
+ }
79
+ const raw = await _extractor(pageUrl);
80
+ const items = XPathCatalog.flatten(raw);
81
+ const key = normalizePageKey(pageUrl);
82
+ _cache.set(key, { items, updatedAt: Date.now() });
83
+ return items;
84
+ }
85
+ /**
86
+ * Resolve um alvo (texto/xpath/id/name/placeholder) para o melhor XPath do catálogo.
87
+ * Retorna undefined se não encontrar match aceitável.
88
+ */
89
+ static resolveFromCatalog(target, pageUrl) {
90
+ const key = normalizePageKey(pageUrl);
91
+ const cached = _cache.get(key);
92
+ if (!cached)
93
+ return undefined;
94
+ // Se o alvo já é um XPath válido, verificar se existe no catálogo
95
+ if (target.startsWith('//') || target.startsWith('(//') || target.startsWith('xpath=')) {
96
+ return undefined; // Não resolver XPaths explícitos via catálogo
97
+ }
98
+ // Procurar match por texto/id/name/placeholder/ariaLabel
99
+ const scored = XPathCatalog.applyFilter(cached.items, target, 5);
100
+ if (scored.length > 0 && scored[0].score && scored[0].score >= 0.6) {
101
+ return scored[0].xpath;
102
+ }
103
+ return undefined;
104
+ }
105
+ /** Limpa cache de uma página específica ou todo o cache */
106
+ static clearCache(pageUrl) {
107
+ if (pageUrl) {
108
+ _cache.delete(normalizePageKey(pageUrl));
109
+ }
110
+ else {
111
+ _cache.clear();
112
+ }
113
+ }
114
+ // ---------- Item 21 — Azure DOM push ----------
115
+ /**
116
+ * Envia DOM/pageStructure capturado localmente para o backend processar.
117
+ *
118
+ * Usado em execuções Azure/CI onde o backend **não** tem acesso de rede
119
+ * à página alvo. O framework captura `pageHtml` e/ou `pageStructure`
120
+ * e envia para `POST /api/xpath-catalog/extract`.
121
+ *
122
+ * O backend enriquece com hints Redis e retorna catálogo + xpaths.
123
+ * O resultado alimenta o cache local por página.
124
+ *
125
+ * @param request Payload com URL, pageHtml/pageStructure e filtro opcional
126
+ * @param authToken JWT ou chave de automação (header Authorization)
127
+ * @returns Resposta do backend com catálogo enriquecido
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * const html = await page.content()
132
+ * const result = await XPathCatalog.pushToBackend({
133
+ * url: page.url(),
134
+ * pageHtml: html,
135
+ * filter: 'cliente',
136
+ * })
137
+ * if (result?.catalog) {
138
+ * // catálogo já está no cache; usar via getCatalog()
139
+ * }
140
+ * ```
141
+ */
142
+ static async pushToBackend(request, authToken) {
143
+ const backendUrl = (process.env.AUTOCORE_HUB_URL ||
144
+ process.env.AUTOCORE_HUB_IP ||
145
+ '').replace(/\/$/, '');
146
+ if (!backendUrl) {
147
+ Logger.warning('[XPathCatalog] AUTOCORE_HUB_URL não configurado; pushToBackend ignorado.');
148
+ return null;
149
+ }
150
+ const headers = {
151
+ 'Content-Type': 'application/json',
152
+ 'x-automation-key': process.env.AUTOCORE_AUTOMATION_KEY || 'd8f3c4a9be7f29d1c6e04fa1a39c2e7bd91f57c8a3de45eb91c4f7a2d0e3b8fa',
153
+ };
154
+ if (authToken) {
155
+ headers['Authorization'] = authToken.startsWith('Bearer ') ? authToken : `Bearer ${authToken}`;
156
+ }
157
+ const controller = new AbortController();
158
+ const timeoutId = setTimeout(() => controller.abort(), 30_000);
159
+ try {
160
+ const res = await fetch(`${backendUrl}/api/xpath-catalog/extract`, {
161
+ method: 'POST',
162
+ headers,
163
+ body: JSON.stringify(request),
164
+ signal: controller.signal,
165
+ });
166
+ if (!res.ok) {
167
+ const text = await res.text().catch(() => '');
168
+ Logger.warning(`[XPathCatalog] pushToBackend falhou: HTTP ${res.status} — ${text}`);
169
+ return { success: false, error: `HTTP ${res.status}` };
170
+ }
171
+ const data = (await res.json());
172
+ // Alimentar cache local com catálogo retornado
173
+ if (data.success && data.catalog?.length) {
174
+ const key = normalizePageKey(request.url);
175
+ _cache.set(key, { items: data.catalog, updatedAt: Date.now() });
176
+ Logger.info(`[XPathCatalog] pushToBackend: ${data.catalog.length} itens recebidos para ${request.url}`);
177
+ }
178
+ return data;
179
+ }
180
+ catch (err) {
181
+ const msg = err instanceof Error ? err.message : String(err);
182
+ Logger.warning(`[XPathCatalog] pushToBackend erro: ${msg}`);
183
+ return { success: false, error: msg };
184
+ }
185
+ finally {
186
+ clearTimeout(timeoutId);
187
+ }
188
+ }
189
+ // ---------- IntelliSense file generation (Item 19) ----------
190
+ /**
191
+ * Gera arquivo `.autocore/xpaths.generated.ts` com constantes tipadas por tela.
192
+ *
193
+ * @param outputDir Diretório de saída (default: `.autocore` na raiz do projeto)
194
+ */
195
+ static generateIntelliSenseFile(outputDir) {
196
+ const dir = outputDir || path.resolve(process.cwd(), '.autocore');
197
+ const filePath = path.join(dir, 'xpaths.generated.ts');
198
+ if (_cache.size === 0) {
199
+ Logger.info('[XPathCatalog] Nenhum catálogo em cache; IntelliSense não gerado.');
200
+ return;
201
+ }
202
+ const lines = [
203
+ '// Auto-generated by @silasfmartins/testhub XPathCatalog',
204
+ '// Do not edit manually — regenerated a cada extract_page_structure',
205
+ '',
206
+ ];
207
+ for (const [pageKey, entry] of _cache) {
208
+ const blockName = XPathCatalog.pageKeyToConstName(pageKey);
209
+ lines.push(`export const ${blockName} = {`);
210
+ const seen = new Set();
211
+ for (const item of entry.items) {
212
+ if (!item.xpath)
213
+ continue;
214
+ const propName = XPathCatalog.itemToPropName(item);
215
+ if (seen.has(propName))
216
+ continue;
217
+ seen.add(propName);
218
+ const safeXPath = item.xpath.replace(/'/g, "\\'");
219
+ lines.push(` ${propName}: '${safeXPath}',`);
220
+ }
221
+ lines.push('} as const');
222
+ lines.push('');
223
+ }
224
+ try {
225
+ if (!fs.existsSync(dir))
226
+ fs.mkdirSync(dir, { recursive: true });
227
+ fs.writeFileSync(filePath, lines.join('\n'), 'utf-8');
228
+ Logger.info(`[XPathCatalog] IntelliSense gerado: ${filePath}`);
229
+ }
230
+ catch (err) {
231
+ Logger.warning(`[XPathCatalog] Falha ao gerar IntelliSense: ${err}`);
232
+ }
233
+ }
234
+ // ---------- Utilitários internos ----------
235
+ /** Converte estrutura bruta em lista flat de XPathCatalogItem */
236
+ static flatten(raw) {
237
+ const items = [];
238
+ const push = (arr) => {
239
+ if (!arr)
240
+ return;
241
+ for (const el of arr) {
242
+ if (el.xpath)
243
+ items.push(el);
244
+ }
245
+ };
246
+ push(raw.inputs);
247
+ push(raw.buttons);
248
+ push(raw.links);
249
+ push(raw.headings);
250
+ push(raw.elements);
251
+ return items;
252
+ }
253
+ /** Aplica filtro textual e ordena por relevância */
254
+ static applyFilter(items, filter, max) {
255
+ if (!filter || filter.trim() === '') {
256
+ return items.slice(0, max);
257
+ }
258
+ const tokens = filter.toLowerCase().split(/\s+/);
259
+ const scored = [];
260
+ for (const item of items) {
261
+ const haystack = [
262
+ item.text,
263
+ item.id,
264
+ item.name,
265
+ item.placeholder,
266
+ item.ariaLabel,
267
+ item.title,
268
+ item.role,
269
+ item.dataTestId,
270
+ item.className,
271
+ item.tag,
272
+ ]
273
+ .filter(Boolean)
274
+ .join(' ')
275
+ .toLowerCase();
276
+ let matched = 0;
277
+ for (const t of tokens) {
278
+ if (haystack.includes(t))
279
+ matched++;
280
+ }
281
+ if (matched > 0) {
282
+ const score = matched / tokens.length;
283
+ scored.push({ ...item, score });
284
+ }
285
+ }
286
+ // Ordenar: maior score primeiro; em empate, inputs > buttons > links
287
+ scored.sort((a, b) => {
288
+ const sa = a.score ?? 0;
289
+ const sb = b.score ?? 0;
290
+ if (sb !== sa)
291
+ return sb - sa;
292
+ return tagPriority(a.tag) - tagPriority(b.tag);
293
+ });
294
+ return scored.slice(0, max);
295
+ }
296
+ /** Converte pageKey em nome de constante TypeScript */
297
+ static pageKeyToConstName(pageKey) {
298
+ // Ex: "https://app.example.com/catalogo/ofertas" → "XPATH_CATALOGO_OFERTAS"
299
+ const segments = pageKey
300
+ .replace(/^https?:\/\/[^/]+/, '')
301
+ .replace(/^\//, '')
302
+ .split('/')
303
+ .filter(Boolean);
304
+ if (segments.length === 0)
305
+ return 'XPATH_HOME';
306
+ return ('XPATH_' +
307
+ segments
308
+ .map((s) => s
309
+ .replace(/[^a-zA-Z0-9_]/g, '_')
310
+ .replace(/_+/g, '_')
311
+ .toUpperCase())
312
+ .join('_'));
313
+ }
314
+ /** Converte item em nome de propriedade para IntelliSense */
315
+ static itemToPropName(item) {
316
+ const tag = (item.tag || 'EL').toUpperCase();
317
+ const label = item.id ||
318
+ item.dataTestId ||
319
+ item.name ||
320
+ item.ariaLabel ||
321
+ item.placeholder ||
322
+ item.title ||
323
+ item.text ||
324
+ '';
325
+ const clean = label
326
+ .substring(0, 40)
327
+ .replace(/[^a-zA-Z0-9]/g, '_')
328
+ .replace(/_+/g, '_')
329
+ .replace(/^_|_$/g, '')
330
+ .toUpperCase();
331
+ return clean ? `${tag}_${clean}` : `${tag}_${Math.random().toString(36).slice(2, 6).toUpperCase()}`;
332
+ }
333
+ }
334
+ // ---------------------------------------------------------------------------
335
+ // Helpers
336
+ // ---------------------------------------------------------------------------
337
+ function tagPriority(tag) {
338
+ switch (tag?.toLowerCase()) {
339
+ case 'input':
340
+ case 'textarea':
341
+ case 'select':
342
+ return 0;
343
+ case 'button':
344
+ return 1;
345
+ case 'a':
346
+ return 2;
347
+ default:
348
+ return 3;
349
+ }
350
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Geradores de dados para testes seguindo padrões DDD
3
+ * @module Utils/Generators
4
+ *
5
+ * 🎯 OBJETIVO: Generators de dados de teste padronizados
6
+ * - ✅ Geradores compatíveis com schemas de validação
7
+ * - ✅ Dados determinísticos para testes reproduzíveis
8
+ * - ✅ Integração com Domain Entities (TestExecution, TestReport)
9
+ * - ✅ Suporte a dados complexos para APIs e formulários
10
+ *
11
+ * 🏗️ ARQUITETURA DDD:
12
+ * - Domain Layer: Value Objects (CPF, CNPJ, Email)
13
+ * - Application Layer: Casos de uso específicos (generateApiTestData)
14
+ * - Infrastructure Layer: Implementações específicas de geradores
15
+ *
16
+ * EXEMPLO USO SIMPLES:
17
+ * ```typescript
18
+ * const id = generateRandomAlphanumeric(10)
19
+ * const email = generateEmail()
20
+ * ```
21
+ *
22
+ * EXEMPLO USO AVANÇADO:
23
+ * ```typescript
24
+ * const testData = generateCompleteFormData({
25
+ * includeOptional: true,
26
+ * locale: 'pt-BR'
27
+ * })
28
+ * ```
29
+ */
30
+ /**
31
+ * Gera UUID alfanumérico de tamanho específico
32
+ * @param length Comprimento desejado
33
+ * @returns String alfanumérica baseada em UUID
34
+ */
35
+ export declare function generateRandomAlphanumericUUID(length: number): string;
36
+ /**
37
+ * Gera ID externo complexo para simulação de sistemas legados
38
+ * @returns ID no formato system1-system2-0xhexadecimal
39
+ */
40
+ export declare function generateComplexExternalId(): string;
41
+ /**
42
+ * Gera string alfanumérica aleatória
43
+ * @param length Comprimento desejado
44
+ * @returns String alfanumérica
45
+ */
46
+ export declare function generateRandomAlphanumeric(length: number): string;
47
+ /**
48
+ * Gera string numérica aleatória
49
+ * @param length Comprimento desejado
50
+ * @returns String numérica
51
+ */
52
+ export declare function generateRandomNumeric(length: number): string;
53
+ /**
54
+ * 🆕 DDD: Gera email válido para testes
55
+ * @param domain Domínio opcional (padrão: 'test.com')
56
+ * @returns Email válido para testes
57
+ */
58
+ export declare function generateEmail(domain?: string): string;
59
+ /**
60
+ * 🆕 DDD: Gera CPF válido para testes (apenas dígitos)
61
+ * @returns CPF válido no formato 11111111111
62
+ */
63
+ export declare function generateCPF(): string;
64
+ /**
65
+ * 🆕 DDD: Gera telefone brasileiro válido
66
+ * @param withAreaCode Se deve incluir código de área
67
+ * @returns Telefone no formato 11999999999 ou 999999999
68
+ */
69
+ export declare function generatePhoneBR(withAreaCode?: boolean): string;
70
+ /**
71
+ * 🆕 DDD: Gera dados completos para formulários
72
+ * @param options Opções de geração
73
+ * @returns Objeto com dados completos para teste
74
+ */
75
+ export declare function generateCompleteFormData(options?: {
76
+ includeOptional?: boolean;
77
+ locale?: 'pt-BR' | 'en-US';
78
+ }): {
79
+ name: string;
80
+ email: string;
81
+ phone: string;
82
+ document: string;
83
+ address?: {
84
+ street: string;
85
+ number: string;
86
+ city: string;
87
+ zipCode: string;
88
+ };
89
+ };
90
+ export declare function generateServiceNowTaskId(): string;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * @fileoverview Geradores de dados para testes seguindo padrões DDD
3
+ * @module Utils/Generators
4
+ *
5
+ * 🎯 OBJETIVO: Generators de dados de teste padronizados
6
+ * - ✅ Geradores compatíveis com schemas de validação
7
+ * - ✅ Dados determinísticos para testes reproduzíveis
8
+ * - ✅ Integração com Domain Entities (TestExecution, TestReport)
9
+ * - ✅ Suporte a dados complexos para APIs e formulários
10
+ *
11
+ * 🏗️ ARQUITETURA DDD:
12
+ * - Domain Layer: Value Objects (CPF, CNPJ, Email)
13
+ * - Application Layer: Casos de uso específicos (generateApiTestData)
14
+ * - Infrastructure Layer: Implementações específicas de geradores
15
+ *
16
+ * EXEMPLO USO SIMPLES:
17
+ * ```typescript
18
+ * const id = generateRandomAlphanumeric(10)
19
+ * const email = generateEmail()
20
+ * ```
21
+ *
22
+ * EXEMPLO USO AVANÇADO:
23
+ * ```typescript
24
+ * const testData = generateCompleteFormData({
25
+ * includeOptional: true,
26
+ * locale: 'pt-BR'
27
+ * })
28
+ * ```
29
+ */
30
+ import { randomUUID } from 'node:crypto';
31
+ /**
32
+ * Gera UUID alfanumérico de tamanho específico
33
+ * @param length Comprimento desejado
34
+ * @returns String alfanumérica baseada em UUID
35
+ */
36
+ export function generateRandomAlphanumericUUID(length) {
37
+ // Gera um UUID e remove os hífens para ter mais caracteres disponíveis
38
+ const uuid = randomUUID().replace(/-/g, '');
39
+ // Se o comprimento solicitado for maior que o UUID disponível,
40
+ // repete o processo até ter caracteres suficientes
41
+ let result = uuid;
42
+ while (result.length < length) {
43
+ result += randomUUID().replace(/-/g, '');
44
+ }
45
+ // Retorna apenas a quantidade de caracteres solicitada
46
+ return result.substring(0, length);
47
+ }
48
+ /**
49
+ * Gera ID externo complexo para simulação de sistemas legados
50
+ * @returns ID no formato system1-system2-0xhexadecimal
51
+ */
52
+ export function generateComplexExternalId() {
53
+ const hex = 'abcdef0123456789';
54
+ const randomHex = (length) => Array.from({ length }, () => hex[Math.floor(Math.random() * hex.length)]).join('');
55
+ const part1 = randomHex(32);
56
+ const part2 = randomHex(32);
57
+ const part3 = '0x' +
58
+ randomHex(30) +
59
+ String.fromCharCode(97 + Math.floor(Math.random() * 26)); // adiciona uma letra no final
60
+ return `${part1}-${part2}${part3}`;
61
+ }
62
+ /**
63
+ * Gera string alfanumérica aleatória
64
+ * @param length Comprimento desejado
65
+ * @returns String alfanumérica
66
+ */
67
+ export function generateRandomAlphanumeric(length) {
68
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
69
+ let result = '';
70
+ for (let i = 0; i < length; i++) {
71
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * Gera string numérica aleatória
77
+ * @param length Comprimento desejado
78
+ * @returns String numérica
79
+ */
80
+ export function generateRandomNumeric(length) {
81
+ const digits = '0123456789';
82
+ let result = '';
83
+ for (let i = 0; i < length; i++) {
84
+ result += digits.charAt(Math.floor(Math.random() * digits.length));
85
+ }
86
+ return result;
87
+ }
88
+ /**
89
+ * 🆕 DDD: Gera email válido para testes
90
+ * @param domain Domínio opcional (padrão: 'test.com')
91
+ * @returns Email válido para testes
92
+ */
93
+ export function generateEmail(domain = 'test.com') {
94
+ const username = generateRandomAlphanumeric(8).toLowerCase();
95
+ return `${username}@${domain}`;
96
+ }
97
+ /**
98
+ * 🆕 DDD: Gera CPF válido para testes (apenas dígitos)
99
+ * @returns CPF válido no formato 11111111111
100
+ */
101
+ export function generateCPF() {
102
+ // Gera os 9 primeiros dígitos
103
+ const nineDegits = Array.from({ length: 9 }, () => Math.floor(Math.random() * 10));
104
+ // Calcula o primeiro dígito verificador
105
+ let sum = 0;
106
+ for (let i = 0; i < 9; i++) {
107
+ sum += nineDegits[i] * (10 - i);
108
+ }
109
+ const firstDigit = (sum * 10) % 11;
110
+ const firstVerifier = firstDigit < 10 ? firstDigit : 0;
111
+ // Calcula o segundo dígito verificador
112
+ sum = 0;
113
+ for (let i = 0; i < 9; i++) {
114
+ sum += nineDegits[i] * (11 - i);
115
+ }
116
+ sum += firstVerifier * 2;
117
+ const secondDigit = (sum * 10) % 11;
118
+ const secondVerifier = secondDigit < 10 ? secondDigit : 0;
119
+ return [...nineDegits, firstVerifier, secondVerifier].join('');
120
+ }
121
+ /**
122
+ * 🆕 DDD: Gera telefone brasileiro válido
123
+ * @param withAreaCode Se deve incluir código de área
124
+ * @returns Telefone no formato 11999999999 ou 999999999
125
+ */
126
+ export function generatePhoneBR(withAreaCode = true) {
127
+ const areaCode = withAreaCode ? generateRandomNumeric(2) : '';
128
+ const firstDigit = '9'; // Celular sempre inicia com 9
129
+ const restDigits = generateRandomNumeric(8);
130
+ return `${areaCode}${firstDigit}${restDigits}`;
131
+ }
132
+ /**
133
+ * 🆕 DDD: Gera dados completos para formulários
134
+ * @param options Opções de geração
135
+ * @returns Objeto com dados completos para teste
136
+ */
137
+ export function generateCompleteFormData(options) {
138
+ const locale = options?.locale || 'pt-BR';
139
+ const includeOptional = options?.includeOptional;
140
+ const data = {
141
+ name: `Test User ${generateRandomAlphanumeric(4)}`,
142
+ email: generateEmail(),
143
+ phone: locale === 'pt-BR' ? generatePhoneBR() : generateRandomNumeric(10),
144
+ document: locale === 'pt-BR' ? generateCPF() : generateRandomNumeric(9),
145
+ };
146
+ if (includeOptional) {
147
+ return {
148
+ ...data,
149
+ address: {
150
+ street: `Test Street ${generateRandomAlphanumeric(3)}`,
151
+ number: generateRandomNumeric(3),
152
+ city: 'Test City',
153
+ zipCode: locale === 'pt-BR'
154
+ ? generateRandomNumeric(8)
155
+ : generateRandomNumeric(5),
156
+ },
157
+ };
158
+ }
159
+ return data;
160
+ }
161
+ export function generateServiceNowTaskId() {
162
+ const hex = 'abcdef0123456789';
163
+ const randomHex = (length) => Array.from({ length }, () => hex[Math.floor(Math.random() * hex.length)]).join('');
164
+ const part1 = randomHex(32);
165
+ const part2 = randomHex(31);
166
+ return `${part1}x${part2}`;
167
+ }