@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,62 @@
1
+ /**
2
+ * TestHubReporter: Reporter para enviar resultados para AutoCore Hub
3
+ *
4
+ * πŸš€ ENDPOINTS UTILIZADOS:
5
+ * - POST /api/execucoes/batch (dados estruturados)
6
+ * - POST /api/execucoes/artifacts (binΓ‘rios em Base64)
7
+ *
8
+ * πŸ“¦ FONTE DE DADOS:
9
+ * - .rbqa/ct-execution-data.json (gerado pelo StatementTracker)
10
+ */
11
+ export declare class TestHubReporter {
12
+ private client;
13
+ private systemsManager;
14
+ constructor();
15
+ /**
16
+ * πŸ“€ Envia todos os resultados da suΓ­te de testes em formato BATCH
17
+ * 🎯 USA DADOS DO ARQUIVO .rbqa/ct-execution-data.json como fonte de verdade
18
+ * πŸš€ ENVIA PARA: POST /api/execucoes/batch + POST /api/execucoes/artifacts
19
+ */
20
+ sendAllResults(): Promise<void>;
21
+ /**
22
+ * βœ… Marca o envio como sucesso para garantir que o processo nΓ£o termine antes
23
+ */
24
+ private markSendSuccess;
25
+ /**
26
+ * πŸ“¦ Compacta e envia artifacts (relatΓ³rios) para o AutoCore Hub
27
+ * πŸš€ ENDPOINT: POST /api/execucoes/artifacts
28
+ */
29
+ private sendArtifacts;
30
+ /**
31
+ * πŸ“– LΓͺ dados do arquivo .rbqa/ct-execution-data.json
32
+ */
33
+ private readCTExecutionData;
34
+ /**
35
+ * πŸ“‹ ObtΓ©m logs capturados do terminal
36
+ */
37
+ private getTerminalLogs;
38
+ /**
39
+ * 🌍 Detecta ambiente de execução (LOCAL ou AZURE)
40
+ */
41
+ private detectEnvironment;
42
+ /**
43
+ * ObtΓ©m matrΓ­cula do usuΓ‘rio (Azure: email, Local: USERNAME)
44
+ */
45
+ private getMatricula;
46
+ /**
47
+ * Testa conectividade com AutoCore Hub
48
+ */
49
+ testConnection(): Promise<boolean>;
50
+ /**
51
+ * πŸ†• ConstrΓ³i logs formatados de API a partir das executedActions
52
+ * Gera logs completos com REQUEST e RESPONSE (headers + body)
53
+ * Formato idΓͺntico ao terminal para facilitar debug no TestHub
54
+ */
55
+ private buildApiLogsFromActions;
56
+ /**
57
+ * 🎯 Mapeia tipos de ação internos para tipos aceitos pelo Hub
58
+ * Backend aceita: "API"|"Database"|"Validation"|"Click"|"Fill"|"Navigate"
59
+ */
60
+ private mapActionTypeForHub;
61
+ }
62
+ export default TestHubReporter;
@@ -0,0 +1,576 @@
1
+ /**
2
+ * TestHubReporter: Reporter para enviar resultados para AutoCore Hub
3
+ *
4
+ * πŸš€ ENDPOINTS UTILIZADOS:
5
+ * - POST /api/execucoes/batch (dados estruturados)
6
+ * - POST /api/execucoes/artifacts (binΓ‘rios em Base64)
7
+ *
8
+ * πŸ“¦ FONTE DE DADOS:
9
+ * - .rbqa/ct-execution-data.json (gerado pelo StatementTracker)
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { ArtifactsCompressor } from '../utils/ArtifactsCompressor.js';
14
+ import SystemsManager from './SystemsManager.js';
15
+ import TestHubClient from './TestHubClient.js';
16
+ import { Logger } from '../utils/Logger.js';
17
+ export class TestHubReporter {
18
+ client;
19
+ systemsManager;
20
+ constructor() {
21
+ this.client = TestHubClient.getInstance();
22
+ this.systemsManager = SystemsManager.getInstance();
23
+ }
24
+ /**
25
+ * πŸ“€ Envia todos os resultados da suΓ­te de testes em formato BATCH
26
+ * 🎯 USA DADOS DO ARQUIVO .rbqa/ct-execution-data.json como fonte de verdade
27
+ * πŸš€ ENVIA PARA: POST /api/execucoes/batch + POST /api/execucoes/artifacts
28
+ */
29
+ async sendAllResults() {
30
+ try {
31
+ // 🎯 LER DADOS DO ARQUIVO JSON (fonte de verdade)
32
+ const ctExecutionData = this.readCTExecutionData();
33
+ if (!ctExecutionData ||
34
+ !ctExecutionData.tests ||
35
+ ctExecutionData.tests.length === 0) {
36
+ Logger.warning('\n⚠️ Nenhum dado de execução disponível para enviar');
37
+ return;
38
+ }
39
+ const allCTs = ctExecutionData.tests.flatMap((test) => test.cts);
40
+ const globalPassedCTs = allCTs.filter((ct) => ct.status === 'passed').length;
41
+ const globalFailedCTs = allCTs.filter((ct) => ct.status === 'failed' || ct.status === 'running').length;
42
+ // 🎯 Detectar ambiente de execução (LOCAL ou AZURE)
43
+ const ambiente = this.detectEnvironment();
44
+ Logger.info(`🌍 AMBIENTE: ${ambiente}`);
45
+ // 🎯 Obter sistema selecionado
46
+ const selectedSystem = this.systemsManager.getSelectedSystem();
47
+ const globalSystemName = selectedSystem?.system.name || 'Unknown';
48
+ Logger.info(`🎯 SISTEMA GLOBAL: ${globalSystemName}`);
49
+ // πŸ“‹ Obter logs capturados do terminal
50
+ const terminalLogs = this.getTerminalLogs();
51
+ // Montar payload batch completo conforme API do AutoCore Hub
52
+ // NOTA: matrΓ­cula e email agora sΓ£o enviados via headers (x-automation-user-matricula e x-automation-user-email)
53
+ // πŸ”§ Calcular startTime e endTime do batch COM VALIDAÇÃO
54
+ // Normalizar startTime para milissegundos (number) para evitar concatenaΓ§Γ£o de string
55
+ const rawStart = ctExecutionData.startTime || ctExecutionData.timestamp || Date.now();
56
+ const batchStartMs = typeof rawStart === 'number' ? rawStart : new Date(rawStart).getTime();
57
+ const batchStartTime = Number.isNaN(batchStartMs) ? Date.now() : batchStartMs;
58
+ // Calcular endTime: usar endTime direto se existir, senΓ£o somar duraΓ§Γ£o ao start
59
+ const rawEnd = ctExecutionData.endTime;
60
+ let batchEndTime;
61
+ if (rawEnd) {
62
+ const parsedEnd = typeof rawEnd === 'number' ? rawEnd : new Date(rawEnd).getTime();
63
+ batchEndTime = Number.isNaN(parsedEnd) ? Date.now() : parsedEnd;
64
+ }
65
+ else {
66
+ batchEndTime = batchStartTime + (ctExecutionData.totalDuration || 0);
67
+ }
68
+ // πŸ›‘οΈ VALIDAÇÃO: Verificar se os timestamps sΓ£o vΓ‘lidos antes de converter para ISO
69
+ let batchStartTimeFormatted;
70
+ let batchEndTimeFormatted;
71
+ try {
72
+ const startDate = new Date(batchStartTime);
73
+ if (Number.isNaN(startDate.getTime())) {
74
+ Logger.warning(`⚠️ [TestHubReporter] batchStartTime invÑlido: ${batchStartTime} (tipo: ${typeof batchStartTime})`);
75
+ Logger.warning(` πŸ“‹ ctExecutionData.startTime: ${ctExecutionData.startTime}`);
76
+ Logger.warning(` πŸ“‹ ctExecutionData.timestamp: ${ctExecutionData.timestamp}`);
77
+ batchStartTimeFormatted = new Date().toISOString(); // Fallback para agora
78
+ }
79
+ else {
80
+ batchStartTimeFormatted = ctExecutionData.startTimeFormatted || startDate.toISOString();
81
+ }
82
+ }
83
+ catch (err) {
84
+ Logger.warning(`⚠️ [TestHubReporter] Erro ao formatar batchStartTime: ${err}`);
85
+ Logger.warning(` πŸ“‹ Valor: ${batchStartTime} (tipo: ${typeof batchStartTime})`);
86
+ batchStartTimeFormatted = new Date().toISOString();
87
+ }
88
+ try {
89
+ const endDate = new Date(batchEndTime);
90
+ if (Number.isNaN(endDate.getTime())) {
91
+ Logger.warning(`⚠️ [TestHubReporter] batchEndTime invÑlido: ${batchEndTime} (tipo: ${typeof batchEndTime})`);
92
+ Logger.warning(` πŸ“‹ ctExecutionData.endTime: ${ctExecutionData.endTime}`);
93
+ Logger.warning(` πŸ“‹ batchStartTime: ${batchStartTime}`);
94
+ Logger.warning(` πŸ“‹ ctExecutionData.totalDuration: ${ctExecutionData.totalDuration}`);
95
+ batchEndTimeFormatted = new Date().toISOString(); // Fallback para agora
96
+ }
97
+ else {
98
+ batchEndTimeFormatted = ctExecutionData.endTimeFormatted || endDate.toISOString();
99
+ }
100
+ }
101
+ catch (err) {
102
+ Logger.warning(`⚠️ [TestHubReporter] Erro ao formatar batchEndTime: ${err}`);
103
+ Logger.warning(` πŸ“‹ Valor: ${batchEndTime} (tipo: ${typeof batchEndTime})`);
104
+ batchEndTimeFormatted = new Date().toISOString();
105
+ }
106
+ const batchPayload = {
107
+ ambiente, // βœ… LOCAL ou AZURE
108
+ systemName: globalSystemName, // βœ… Sistema global da execuΓ§Γ£o
109
+ timestamp: ctExecutionData.timestamp,
110
+ startTime: batchStartTime, // βœ… NOVO: InΓ­cio da execuΓ§Γ£o
111
+ startTimeFormatted: batchStartTimeFormatted, // βœ… NOVO: InΓ­cio formatado
112
+ endTime: batchEndTime, // βœ… NOVO: Fim da execuΓ§Γ£o
113
+ endTimeFormatted: batchEndTimeFormatted, // βœ… NOVO: Fim formatado
114
+ totalCTs: allCTs.length,
115
+ passedCTs: globalPassedCTs, // βœ… CORRIGIDO: Recalculado
116
+ failedCTs: globalFailedCTs, // βœ… CORRIGIDO: Recalculado incluindo "running"
117
+ totalDuration: ctExecutionData.totalDuration,
118
+ totalDurationFormatted: ctExecutionData.totalDurationFormatted,
119
+ terminalLogs, // βœ… NOVO: Logs do terminal
120
+ tests: ctExecutionData.tests.map((testData, testIndex) => {
121
+ Logger.info(`\n πŸ“‹ Teste ${testIndex + 1}/${ctExecutionData.tests.length}: "${testData.testName}"`);
122
+ Logger.info(` ⏱️ Duração: ${testData.durationFormatted}`);
123
+ Logger.info(` πŸ§ͺ CTs: ${testData.cts.length} total`);
124
+ // 🎯 Calcular contadores de CTs para cada teste (CN)
125
+ // πŸ›‘οΈ CRÍTICO: Converter "running" para "failed" nos contadores
126
+ const testPassedCTs = testData.cts.filter((ct) => ct.status === 'passed').length;
127
+ const testFailedCTs = testData.cts.filter((ct) => ct.status === 'failed' || ct.status === 'running').length;
128
+ const testSkippedCTs = testData.cts.filter((ct) => ct.status === 'skipped').length;
129
+ Logger.info(` βœ… Passados: ${testPassedCTs}`);
130
+ Logger.info(` ❌ Falhados: ${testFailedCTs}`);
131
+ Logger.info(` ⏭️ Pulados: ${testSkippedCTs}`);
132
+ // Listar CTs
133
+ testData.cts.forEach((ct, ctIndex) => {
134
+ const statusIcon = ct.status === 'passed'
135
+ ? 'βœ…'
136
+ : ct.status === 'failed'
137
+ ? '❌'
138
+ : '⏭️';
139
+ Logger.info(` ${statusIcon} CT${ctIndex + 1}: "${ct.name}" (${ct.durationFormatted}) - Sistema: ${ct.systemName || 'Nenhum'}`);
140
+ if (ct.error) {
141
+ Logger.info(` ⚠️ Erro: ${ct.error.substring(0, 80)}...`);
142
+ }
143
+ });
144
+ // πŸ“‹ Obter logs especΓ­ficos deste teste
145
+ const testLogs = terminalLogs?.byTest?.[testData.testName] || [];
146
+ Logger.info(` πŸ“‹ Logs deste teste: ${testLogs.length} logs`);
147
+ // πŸ”§ Calcular startTime e endTime do teste com fallbacks
148
+ const testStartTime = testData.startTime || Date.now();
149
+ const testEndTime = testData.endTime || (testStartTime + (testData.duration || 0));
150
+ const testStartTimeFormatted = testData.startTimeFormatted || new Date(testStartTime).toISOString();
151
+ const testEndTimeFormatted = testData.endTimeFormatted || new Date(testEndTime).toISOString();
152
+ return {
153
+ testName: testData.testName,
154
+ systemName: globalSystemName, // βœ… Sistema global para o teste (CN)
155
+ startTime: testStartTime,
156
+ startTimeFormatted: testStartTimeFormatted,
157
+ endTime: testEndTime, // βœ… CORRIGIDO: Com fallback
158
+ endTimeFormatted: testEndTimeFormatted, // βœ… CORRIGIDO: Com fallback
159
+ totalCTs: testData.cts.length,
160
+ passedCTs: testPassedCTs, // βœ… CORRIGIDO: Calculado dinamicamente
161
+ failedCTs: testFailedCTs, // βœ… CORRIGIDO: Calculado dinamicamente
162
+ skippedCTs: testSkippedCTs, // βœ… NOVO: CTs pulados
163
+ duration: testData.duration || 0,
164
+ durationFormatted: testData.durationFormatted || '0ms',
165
+ logs: testLogs, // βœ… NOVO: Logs deste teste (texto completo)
166
+ cts: testData.cts.map((ct) => {
167
+ // πŸ›‘οΈ VALIDAÇÃO: Se CT estΓ‘ "running" ao enviar para Hub, marcar como "failed"
168
+ const finalStatus = ct.status === 'running' ? 'failed' : ct.status;
169
+ const finalEndTime = ct.endTime || Date.now();
170
+ const finalDuration = ct.duration || (finalEndTime - ct.startTime);
171
+ // πŸ†• AGREGAR executedActions do CT + de todos os Statements
172
+ // As actions podem estar diretamente no CT OU dentro dos statements
173
+ const ctDirectActions = ct.executedActions || [];
174
+ const statementsActions = (ct.statements || []).flatMap((stmt) => stmt.executedActions || []);
175
+ const allExecutedActions = [...ctDirectActions, ...statementsActions];
176
+ // πŸ› DEBUG: Log para verificar agregaΓ§Γ£o de actions
177
+ const apiActionsCount = allExecutedActions.filter((a) => a.type === 'API').length;
178
+ if (allExecutedActions.length > 0 || ct.statements?.length > 0) {
179
+ Logger.info(` πŸ“Š CT "${ct.name}": ${ctDirectActions.length} aΓ§Γ΅es diretas + ${statementsActions.length} aΓ§Γ΅es de statements = ${allExecutedActions.length} total (${apiActionsCount} API)`);
180
+ }
181
+ // πŸ†• GERAR LOGS COMPLETOS DE API A PARTIR DE executedActions AGREGADOS
182
+ const apiLogs = this.buildApiLogsFromActions(allExecutedActions);
183
+ // πŸ†• Combinar logs existentes + logs de API estruturados
184
+ const combinedLogs = [
185
+ ...(ct.logs || []),
186
+ ...apiLogs,
187
+ ];
188
+ // πŸ†• Simplificar executedActions para o Hub (remover dados grandes)
189
+ // 🎯 Mapear tipos para valores aceitos pelo backend
190
+ const simplifiedActions = allExecutedActions.map((action) => ({
191
+ type: this.mapActionTypeForHub(action.type),
192
+ description: action.description,
193
+ timestamp: action.timestamp,
194
+ duration: action.duration,
195
+ success: action.success,
196
+ // πŸ›‘οΈ Enviar apenas resumo, nΓ£o dados completos de headers/body
197
+ details: action.details ? {
198
+ method: action.details.method,
199
+ url: action.details.url,
200
+ statusCode: action.details.statusCode,
201
+ // NÃO enviar requestHeaders, requestBody, responseHeaders, responseBody
202
+ } : undefined,
203
+ }));
204
+ return {
205
+ name: ct.name,
206
+ systemName: ct.systemName, // βœ… CORRIGIDO: SΓ³ usar systemName se foi explicitamente definido por setSystem()
207
+ status: finalStatus,
208
+ startTime: ct.startTime,
209
+ startTimeFormatted: ct.startTimeFormatted,
210
+ endTime: finalEndTime,
211
+ endTimeFormatted: ct.endTimeFormatted || new Date(finalEndTime).toISOString(),
212
+ duration: finalDuration,
213
+ durationFormatted: ct.durationFormatted || `${finalDuration}ms`,
214
+ error: ct.error || (finalStatus === 'failed' && ct.status === 'running' ? 'CT nΓ£o finalizado corretamente' : undefined),
215
+ logs: combinedLogs, // πŸ†• LOGS DO CT (texto + logs de API estruturados)
216
+ executedActions: simplifiedActions, // πŸ†• AΓ§Γ΅es simplificadas (sem dados grandes)
217
+ };
218
+ }),
219
+ };
220
+ }),
221
+ };
222
+ Logger.info('\nπŸ“€ Enviando batch para AutoCore Hub...');
223
+ const executionIds = await this.client.sendBatchExecution(batchPayload);
224
+ if (executionIds && executionIds.length > 0) {
225
+ Logger.success('Batch enviado com sucesso!');
226
+ Logger.info(` πŸ†” IDs das execuΓ§Γ΅es: ${executionIds.join(', ')}`);
227
+ // βœ… CRÍTICO: Marcar envio como sucesso
228
+ this.markSendSuccess();
229
+ }
230
+ else {
231
+ Logger.warning('\n⚠️ Batch enviado mas nenhum ID retornado');
232
+ }
233
+ // βœ… CRÍTICO: Aguardar para garantir que a conexΓ£o HTTP foi finalizada
234
+ // No modo UI, o processo pode terminar antes do socket fechar
235
+ Logger.info('⏳ Aguardando finalização da conexão HTTP...');
236
+ await new Promise((resolve) => setTimeout(resolve, 2000));
237
+ // πŸ“¦ COMPACTAR E ENVIAR ARTIFACTS PARA /api/execucoes/artifacts
238
+ await this.sendArtifacts();
239
+ // βœ… CRÍTICO: Delay final para garantir que TUDO foi enviado
240
+ Logger.info('⏳ Garantindo que todos os dados foram transmitidos...');
241
+ await new Promise((resolve) => setTimeout(resolve, 3000));
242
+ Logger.success('TransmissΓ£o de dados finalizada!');
243
+ }
244
+ catch (error) {
245
+ Logger.error('\n' + '='.repeat(80));
246
+ Logger.error('❌ ERRO AO ENVIAR RESULTADOS PARA AUTOCORE HUB');
247
+ Logger.error('='.repeat(80));
248
+ Logger.error(`πŸ“› Mensagem: ${error.message}`);
249
+ // πŸ”§ LOG COMPLETO DA REQUISIÇÃO PARA DEBUG
250
+ if (error.requestUrl) {
251
+ Logger.error('');
252
+ Logger.error('πŸ“‘ DETALHES DA REQUISIÇÃO:');
253
+ Logger.error('-'.repeat(80));
254
+ Logger.error(`πŸ”— URL: ${error.requestUrl}`);
255
+ Logger.error(`πŸ“‹ MΓ©todo: POST`);
256
+ }
257
+ if (error.requestHeaders) {
258
+ Logger.error('');
259
+ Logger.error('πŸ“¨ HEADERS ENVIADOS:');
260
+ Logger.error('-'.repeat(80));
261
+ // Mascarar x-automation-key para seguranΓ§a
262
+ const safeHeaders = { ...error.requestHeaders };
263
+ if (safeHeaders['x-automation-key']) {
264
+ safeHeaders['x-automation-key'] = safeHeaders['x-automation-key'].substring(0, 8) + '...[MASKED]';
265
+ }
266
+ Logger.error(JSON.stringify(safeHeaders, null, 2));
267
+ }
268
+ if (error.requestBody) {
269
+ Logger.error('');
270
+ Logger.error('πŸ“¦ BODY ENVIADO (primeiros 5000 caracteres):');
271
+ Logger.error('-'.repeat(80));
272
+ const bodyPreview = error.requestBody.length > 5000
273
+ ? error.requestBody.substring(0, 5000) + '\n... [TRUNCADO - Total: ' + error.requestBody.length + ' caracteres]'
274
+ : error.requestBody;
275
+ try {
276
+ // Tenta formatar como JSON para melhor leitura
277
+ const parsed = JSON.parse(error.requestBody);
278
+ Logger.error(JSON.stringify(parsed, null, 2).substring(0, 5000));
279
+ }
280
+ catch {
281
+ Logger.error(bodyPreview);
282
+ }
283
+ }
284
+ if (error.responseText) {
285
+ Logger.error('');
286
+ Logger.error('πŸ“₯ RESPOSTA DO SERVIDOR:');
287
+ Logger.error('-'.repeat(80));
288
+ Logger.error(error.responseText);
289
+ }
290
+ if (error.status) {
291
+ Logger.error('');
292
+ Logger.error(`πŸ”΄ HTTP Status: ${error.status} ${error.statusText || ''}`);
293
+ }
294
+ Logger.error('');
295
+ Logger.error('πŸ“ STACK TRACE:');
296
+ Logger.error('-'.repeat(80));
297
+ Logger.error(error.stack);
298
+ Logger.error('='.repeat(80) + '\n');
299
+ }
300
+ }
301
+ /**
302
+ * βœ… Marca o envio como sucesso para garantir que o processo nΓ£o termine antes
303
+ */
304
+ markSendSuccess() {
305
+ try {
306
+ const successPath = path.join(process.cwd(), '.rbqa', 'hub-send-success.json');
307
+ const successData = {
308
+ timestamp: new Date().toISOString(),
309
+ success: true,
310
+ };
311
+ fs.writeFileSync(successPath, JSON.stringify(successData, null, 2));
312
+ }
313
+ catch {
314
+ // Ignorar erro ao salvar marcador
315
+ }
316
+ }
317
+ /**
318
+ * πŸ“¦ Compacta e envia artifacts (relatΓ³rios) para o AutoCore Hub
319
+ * πŸš€ ENDPOINT: POST /api/execucoes/artifacts
320
+ */
321
+ async sendArtifacts() {
322
+ try {
323
+ const compressor = new ArtifactsCompressor(process.cwd());
324
+ const artifacts = await compressor.compressAllArtifacts();
325
+ // Verificar se hΓ‘ artifacts para enviar
326
+ if (!artifacts.htmlReport &&
327
+ !artifacts.testResults &&
328
+ artifacts.traces?.length === 0 &&
329
+ artifacts.screenshots?.length === 0) {
330
+ Logger.warning('⚠️ Nenhum artifact encontrado para enviar');
331
+ return;
332
+ }
333
+ // Montar payload dos artifacts
334
+ // NOTA: matrΓ­cula e email agora sΓ£o enviados via headers (x-automation-user-matricula e x-automation-user-email)
335
+ const payload = {
336
+ timestamp: new Date().toISOString(),
337
+ artifacts: {
338
+ htmlReport: artifacts.htmlReport,
339
+ testResults: artifacts.testResults,
340
+ traces: artifacts.traces,
341
+ screenshots: artifacts.screenshots,
342
+ size: artifacts.size,
343
+ },
344
+ };
345
+ // πŸš€ ENVIAR PARA /api/execucoes/artifacts
346
+ Logger.info('πŸ“¦ Enviando artifacts para AutoCore Hub...');
347
+ await this.client.sendArtifacts(payload);
348
+ Logger.success('Artifacts enviados com sucesso!');
349
+ // βœ… CRÍTICO: Aguardar para garantir que o upload foi completado
350
+ await new Promise((resolve) => setTimeout(resolve, 1000));
351
+ }
352
+ catch (error) {
353
+ Logger.error(`❌ Erro ao enviar artifacts: ${error.message}`);
354
+ Logger.warning('⚠️ Continuando execução sem artifacts...');
355
+ }
356
+ }
357
+ /**
358
+ * πŸ“– LΓͺ dados do arquivo .rbqa/ct-execution-data.json
359
+ */
360
+ readCTExecutionData() {
361
+ try {
362
+ const jsonPath = path.join(process.cwd(), '.rbqa', 'ct-execution-data.json');
363
+ if (!fs.existsSync(jsonPath)) {
364
+ Logger.warning(`⚠️ Arquivo não encontrado: ${jsonPath}`);
365
+ return null;
366
+ }
367
+ const jsonContent = fs.readFileSync(jsonPath, 'utf-8');
368
+ const data = JSON.parse(jsonContent);
369
+ return data;
370
+ }
371
+ catch (error) {
372
+ Logger.error('❌ Erro ao ler ct-execution-data.json', error);
373
+ return null;
374
+ }
375
+ }
376
+ /**
377
+ * πŸ“‹ ObtΓ©m logs capturados do terminal
378
+ */
379
+ getTerminalLogs() {
380
+ try {
381
+ // Tentar obter logs do TerminalLogCapture
382
+ if (globalThis.TerminalLogCapture) {
383
+ const logCapture = globalThis.TerminalLogCapture;
384
+ const logsByTest = logCapture.getLogsByTest();
385
+ const stats = logCapture.getStats();
386
+ Logger.info(`πŸ“‹ Logs capturados: ${stats.totalLogs} total`);
387
+ Logger.info(`πŸ“Š Logs por nΓ­vel: ${stats.byLevel.log} log, ${stats.byLevel.info} info, ${stats.byLevel.warn} warn, ${stats.byLevel.error} error`);
388
+ // Converter Map para objeto simples
389
+ const logsObject = {};
390
+ for (const [testName, logs] of logsByTest.entries()) {
391
+ logsObject[testName] = logs;
392
+ }
393
+ return {
394
+ totalLogs: stats.totalLogs,
395
+ byLevel: stats.byLevel,
396
+ byTest: logsObject,
397
+ stats,
398
+ };
399
+ }
400
+ // Tentar ler do arquivo salvo
401
+ const logsPath = path.join(process.cwd(), 'test-results', 'terminal-logs.json');
402
+ if (fs.existsSync(logsPath)) {
403
+ const logsContent = fs.readFileSync(logsPath, 'utf-8');
404
+ const logsData = JSON.parse(logsContent);
405
+ Logger.info(`πŸ“‹ Logs lidos do arquivo: ${logsData.totalLogs} total`);
406
+ return logsData;
407
+ }
408
+ Logger.warning('⚠️ Nenhum log do terminal encontrado');
409
+ return null;
410
+ }
411
+ catch (error) {
412
+ Logger.error('❌ Erro ao obter logs do terminal', error);
413
+ return null;
414
+ }
415
+ }
416
+ /**
417
+ * 🌍 Detecta ambiente de execução (LOCAL ou AZURE)
418
+ */
419
+ detectEnvironment() {
420
+ // Verificar se estΓ‘ rodando no Azure Pipeline
421
+ const isAzurePipeline = !!(process.env.BUILD_REQUESTEDFOREMAIL ||
422
+ process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI ||
423
+ process.env.AGENT_NAME ||
424
+ process.env.BUILD_BUILDID);
425
+ if (isAzurePipeline) {
426
+ Logger.info('πŸ”΅ Ambiente detectado: AZURE Pipeline');
427
+ return 'AZURE';
428
+ }
429
+ Logger.info('πŸ’» Ambiente detectado: LOCAL');
430
+ return 'LOCAL';
431
+ }
432
+ /**
433
+ * ObtΓ©m matrΓ­cula do usuΓ‘rio (Azure: email, Local: USERNAME)
434
+ */
435
+ getMatricula() {
436
+ // Azure Pipeline - usar email se disponΓ­vel
437
+ const azureEmail = process.env.BUILD_REQUESTEDFOREMAIL;
438
+ if (azureEmail) {
439
+ Logger.info(`πŸ”΅ Azure Pipeline - Email: ${azureEmail}`);
440
+ // Extrair matrΓ­cula do email se possΓ­vel
441
+ const matriculaMatch = azureEmail.match(/A\d{7}/);
442
+ if (matriculaMatch) {
443
+ Logger.info(`🎯 Matrícula extraída: ${matriculaMatch[0]}`);
444
+ return matriculaMatch[0];
445
+ }
446
+ return azureEmail;
447
+ }
448
+ // Local - usar matrΓ­cula configurada ou USERNAME
449
+ return (process.env.AUTOCORE_USER_MATRICULA ||
450
+ process.env.USERNAME ||
451
+ process.env.USER ||
452
+ 'N/A');
453
+ }
454
+ /**
455
+ * Testa conectividade com AutoCore Hub
456
+ */
457
+ async testConnection() {
458
+ return await this.client.testConnection();
459
+ }
460
+ /**
461
+ * πŸ†• ConstrΓ³i logs formatados de API a partir das executedActions
462
+ * Gera logs completos com REQUEST e RESPONSE (headers + body)
463
+ * Formato idΓͺntico ao terminal para facilitar debug no TestHub
464
+ */
465
+ buildApiLogsFromActions(executedActions) {
466
+ if (!executedActions || executedActions.length === 0) {
467
+ return [];
468
+ }
469
+ const apiLogs = [];
470
+ for (const action of executedActions) {
471
+ // SΓ³ processar aΓ§Γ΅es de API que tenham detalhes completos
472
+ if (action.type !== 'API' || !action.details) {
473
+ continue;
474
+ }
475
+ const details = action.details;
476
+ const statusIcon = action.success ? 'βœ…' : '❌';
477
+ const statusText = action.success ? 'PASSED' : 'FAILED';
478
+ // Header do log
479
+ apiLogs.push('');
480
+ apiLogs.push('═'.repeat(70));
481
+ apiLogs.push(`${statusIcon} API CALL: ${action.description} [${statusText}]`);
482
+ apiLogs.push(`⏱️ DuraΓ§Γ£o: ${action.duration || 0}ms | πŸ• ${action.timestamp}`);
483
+ apiLogs.push('═'.repeat(70));
484
+ // REQUEST - Formato completo
485
+ if (details.method && details.url) {
486
+ apiLogs.push('');
487
+ apiLogs.push('╔══════════════════════ REQUEST ═══════════════════════╗');
488
+ apiLogs.push(`β•‘ ENDPOINT: ${details.url}`);
489
+ apiLogs.push(`β•‘ METHOD: ${details.method}`);
490
+ // Request Headers - formato [key : value]
491
+ if (details.requestHeaders && typeof details.requestHeaders === 'object' && Object.keys(details.requestHeaders).length > 0) {
492
+ const headersList = Object.entries(details.requestHeaders)
493
+ .map(([key, value]) => `[${key} : ${value}]`)
494
+ .join(' ');
495
+ apiLogs.push(`β•‘ HEADERS: ${headersList}`);
496
+ }
497
+ else {
498
+ apiLogs.push(`β•‘ HEADERS: [nenhum]`);
499
+ }
500
+ // Request Body
501
+ const reqBody = details.requestBody;
502
+ if (reqBody && typeof reqBody === 'string' && reqBody.trim()) {
503
+ apiLogs.push(`β•‘ BODY:`);
504
+ // Dividir body em linhas para formataΓ§Γ£o
505
+ const bodyLines = reqBody.split('\n');
506
+ for (const line of bodyLines) {
507
+ apiLogs.push(`β•‘ ${line}`);
508
+ }
509
+ }
510
+ else {
511
+ apiLogs.push(`β•‘ BODY: [vazio]`);
512
+ }
513
+ apiLogs.push('β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•');
514
+ }
515
+ // RESPONSE - Formato completo
516
+ if (details.statusCode !== undefined) {
517
+ apiLogs.push('');
518
+ apiLogs.push('╔══════════════════════ RESPONSE ══════════════════════╗');
519
+ const statusCodeIcon = details.statusCode >= 200 && details.statusCode < 300 ? 'βœ…' : '⚠️';
520
+ apiLogs.push(`β•‘ ${statusCodeIcon} STATUS CODE: ${details.statusCode}`);
521
+ // Response Headers - formato [key : value]
522
+ if (details.responseHeaders && typeof details.responseHeaders === 'object' && Object.keys(details.responseHeaders).length > 0) {
523
+ const headersList = Object.entries(details.responseHeaders)
524
+ .map(([key, value]) => `[${key} : ${value}]`)
525
+ .join(' ');
526
+ apiLogs.push(`β•‘ HEADERS: ${headersList}`);
527
+ }
528
+ else {
529
+ apiLogs.push(`β•‘ HEADERS: [nenhum]`);
530
+ }
531
+ // Response Body
532
+ const respBody = details.responseBody;
533
+ if (respBody && typeof respBody === 'string' && respBody.trim()) {
534
+ apiLogs.push(`β•‘ BODY:`);
535
+ // Dividir body em linhas para formataΓ§Γ£o
536
+ const bodyLines = respBody.split('\n');
537
+ for (const line of bodyLines) {
538
+ apiLogs.push(`β•‘ ${line}`);
539
+ }
540
+ }
541
+ else {
542
+ apiLogs.push(`β•‘ BODY: [vazio]`);
543
+ }
544
+ apiLogs.push('β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•');
545
+ }
546
+ apiLogs.push('');
547
+ }
548
+ // Log de debug para verificar quantas aΓ§Γ΅es de API foram processadas
549
+ const apiActionsCount = executedActions.filter(a => a.type === 'API').length;
550
+ if (apiActionsCount > 0) {
551
+ apiLogs.unshift(`πŸ“Š Total de chamadas API capturadas: ${apiActionsCount}`);
552
+ apiLogs.unshift('');
553
+ }
554
+ return apiLogs;
555
+ }
556
+ /**
557
+ * 🎯 Mapeia tipos de ação internos para tipos aceitos pelo Hub
558
+ * Backend aceita: "API"|"Database"|"Validation"|"Click"|"Fill"|"Navigate"
559
+ */
560
+ mapActionTypeForHub(type) {
561
+ const typeMapping = {
562
+ 'API': 'API',
563
+ 'DB': 'Database',
564
+ 'SSH': 'API', // SSH Γ© tratado como API no Hub
565
+ 'UI': 'Click', // AΓ§Γ΅es de UI genΓ©ricas mapeiam para Click
566
+ 'MOBILE': 'Click', // Mobile tambΓ©m mapeia para Click
567
+ 'OTHER': 'Validation', // Outros mapeiam para Validation
568
+ 'VALIDATION': 'Validation',
569
+ 'CLICK': 'Click',
570
+ 'FILL': 'Fill',
571
+ 'NAVIGATE': 'Navigate',
572
+ };
573
+ return typeMapping[type?.toUpperCase()] || 'Validation';
574
+ }
575
+ }
576
+ export default TestHubReporter;