@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,600 @@
1
+ /**
2
+ * 📸 Sistema de Captura de Evidências
3
+ * @description Captura e organiza screenshots e logs para gerar relatórios com evidências
4
+ * @author TestHUB Team
5
+ * @version 1.0.0
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { TestContext } from '../testContext/TestContext.js';
10
+ import { Logger } from './Logger.js';
11
+ export class EvidenceCapture {
12
+ static evidenceByTest = new Map();
13
+ static currentEvidenceId = 0;
14
+ static playwrightReportDir = '';
15
+ static evidenceFile = '';
16
+ /**
17
+ * ✅ Inicializa o sistema de captura de evidências
18
+ */
19
+ static initialize() {
20
+ // Detectar diretório playwright-report
21
+ const possibleDirs = [
22
+ path.join(process.cwd(), 'playwright-report'),
23
+ path.join(process.cwd(), 'test-results'),
24
+ path.join(process.cwd(), 'reports'),
25
+ ];
26
+ for (const dir of possibleDirs) {
27
+ if (fs.existsSync(dir)) {
28
+ EvidenceCapture.playwrightReportDir = dir;
29
+ break;
30
+ }
31
+ }
32
+ // Se não encontrar, criar playwright-report
33
+ if (!EvidenceCapture.playwrightReportDir) {
34
+ EvidenceCapture.playwrightReportDir = path.join(process.cwd(), 'playwright-report');
35
+ if (!fs.existsSync(EvidenceCapture.playwrightReportDir)) {
36
+ fs.mkdirSync(EvidenceCapture.playwrightReportDir, { recursive: true });
37
+ }
38
+ }
39
+ // Criar subpasta para evidências
40
+ const evidenceDir = path.join(EvidenceCapture.playwrightReportDir, 'evidence');
41
+ if (!fs.existsSync(evidenceDir)) {
42
+ fs.mkdirSync(evidenceDir, { recursive: true });
43
+ }
44
+ // Definir arquivo de persistência
45
+ EvidenceCapture.evidenceFile = path.join(EvidenceCapture.playwrightReportDir, 'evidence-data.json');
46
+ // Carregar evidências existentes
47
+ EvidenceCapture.loadEvidence();
48
+ }
49
+ /**
50
+ * 🆕 Carregar evidências do arquivo de persistência
51
+ */
52
+ static loadEvidence() {
53
+ try {
54
+ if (fs.existsSync(EvidenceCapture.evidenceFile)) {
55
+ const data = fs.readFileSync(EvidenceCapture.evidenceFile, 'utf-8');
56
+ const parsed = JSON.parse(data);
57
+ // Restaurar Map
58
+ if (parsed.evidenceByTest) {
59
+ for (const [testName, testEvidence] of Object.entries(parsed.evidenceByTest)) {
60
+ // Converter datas de volta para objetos Date
61
+ const evidence = testEvidence;
62
+ evidence.startTime = new Date(evidence.startTime);
63
+ if (evidence.endTime) {
64
+ evidence.endTime = new Date(evidence.endTime);
65
+ }
66
+ if (evidence.items) {
67
+ evidence.items.forEach((item) => {
68
+ item.timestamp = new Date(item.timestamp);
69
+ });
70
+ }
71
+ EvidenceCapture.evidenceByTest.set(testName, evidence);
72
+ }
73
+ }
74
+ else {
75
+ Logger.info('⚠️ [EvidenceCapture] loadEvidence - No evidenceByTest in parsed data');
76
+ }
77
+ // Restaurar contador
78
+ if (parsed.currentEvidenceId) {
79
+ EvidenceCapture.currentEvidenceId = parsed.currentEvidenceId;
80
+ }
81
+ }
82
+ else {
83
+ }
84
+ }
85
+ catch (error) {
86
+ Logger.warning(`⚠️ [EvidenceCapture] Erro ao carregar evidências: ${error}`);
87
+ }
88
+ }
89
+ /**
90
+ * 🆕 Salvar evidências no arquivo de persistência
91
+ */
92
+ static saveEvidence() {
93
+ try {
94
+ const data = {
95
+ evidenceByTest: Object.fromEntries(EvidenceCapture.evidenceByTest),
96
+ currentEvidenceId: EvidenceCapture.currentEvidenceId,
97
+ lastSaved: new Date().toISOString(),
98
+ };
99
+ fs.writeFileSync(EvidenceCapture.evidenceFile, JSON.stringify(data, null, 2), 'utf-8');
100
+ }
101
+ catch (error) {
102
+ Logger.warning(`⚠️ [EvidenceCapture] Erro ao salvar evidências: ${error}`);
103
+ }
104
+ }
105
+ /**
106
+ * ✅ Inicia captura para um teste
107
+ */
108
+ static startTest(testName) {
109
+ if (!EvidenceCapture.evidenceByTest.has(testName)) {
110
+ EvidenceCapture.evidenceByTest.set(testName, {
111
+ testName,
112
+ startTime: new Date(),
113
+ items: [],
114
+ totalActions: 0,
115
+ successActions: 0,
116
+ failedActions: 0,
117
+ });
118
+ // Salvar imediatamente
119
+ EvidenceCapture.saveEvidence();
120
+ }
121
+ }
122
+ /**
123
+ * ✅ Finaliza captura para um teste
124
+ */
125
+ static endTest(testName) {
126
+ const evidence = EvidenceCapture.evidenceByTest.get(testName);
127
+ if (evidence) {
128
+ evidence.endTime = new Date();
129
+ // Salvar imediatamente
130
+ EvidenceCapture.saveEvidence();
131
+ }
132
+ }
133
+ /**
134
+ * ✅ Captura uma ação com screenshot
135
+ * @param testName Nome do teste
136
+ * @param action Ação executada
137
+ * @param description Descrição da ação
138
+ * @param metadata Metadados opcionais
139
+ * @param providedScreenshot Screenshot fornecido externamente (Buffer ou caminho)
140
+ */
141
+ static async captureAction(testName, action, description, metadata, providedScreenshot) {
142
+ try {
143
+ // Garantir que o teste está iniciado
144
+ EvidenceCapture.startTest(testName);
145
+ const evidenceId = `evidence-${++EvidenceCapture.currentEvidenceId}`;
146
+ const timestamp = new Date();
147
+ // Capturar screenshot se possível
148
+ let screenshot;
149
+ let screenshotPath;
150
+ try {
151
+ // 🆕 PRIORIZAR SCREENSHOT FORNECIDO (Mobile/Web)
152
+ if (providedScreenshot) {
153
+ if (Buffer.isBuffer(providedScreenshot)) {
154
+ screenshot = providedScreenshot;
155
+ }
156
+ else if (typeof providedScreenshot === 'string') {
157
+ // Se for caminho, usar o caminho diretamente
158
+ screenshotPath = providedScreenshot;
159
+ }
160
+ }
161
+ // Se não tiver screenshot fornecido, tentar capturar via TestContext
162
+ if (!(screenshot || screenshotPath)) {
163
+ const capturedScreenshot = await TestContext.captureScreenshot();
164
+ if (capturedScreenshot) {
165
+ screenshot = capturedScreenshot;
166
+ }
167
+ }
168
+ // Se tiver screenshot buffer, salvar arquivo
169
+ if (screenshot) {
170
+ const evidenceDir = path.join(EvidenceCapture.playwrightReportDir, 'evidence', testName.replace(/[^a-zA-Z0-9]/g, '_'));
171
+ if (!fs.existsSync(evidenceDir)) {
172
+ fs.mkdirSync(evidenceDir, { recursive: true });
173
+ }
174
+ const screenshotFile = path.join(evidenceDir, `${evidenceId}.png`);
175
+ fs.writeFileSync(screenshotFile, screenshot);
176
+ // Path relativo para o HTML
177
+ screenshotPath = `evidence/${testName.replace(/[^a-zA-Z0-9]/g, '_')}/${evidenceId}.png`;
178
+ }
179
+ }
180
+ catch (error) {
181
+ Logger.warning(`⚠️ Não foi possível capturar screenshot para ${action}: ${error}`);
182
+ }
183
+ const evidenceItem = {
184
+ id: evidenceId,
185
+ timestamp,
186
+ testName,
187
+ action,
188
+ description,
189
+ screenshot,
190
+ screenshotPath,
191
+ metadata,
192
+ };
193
+ const evidence = EvidenceCapture.evidenceByTest.get(testName);
194
+ evidence.items.push(evidenceItem);
195
+ evidence.totalActions++;
196
+ // Determinar se ação foi bem-sucedida baseado na descrição
197
+ if (description.includes('❌') ||
198
+ description.includes('erro') ||
199
+ description.includes('falhou')) {
200
+ evidence.failedActions++;
201
+ }
202
+ else {
203
+ evidence.successActions++;
204
+ }
205
+ // 🆕 SALVAR IMEDIATAMENTE APÓS ADICIONAR EVIDÊNCIA
206
+ EvidenceCapture.saveEvidence();
207
+ }
208
+ catch (error) {
209
+ Logger.error('❌ Erro ao capturar evidência:', error);
210
+ }
211
+ }
212
+ /**
213
+ * Compatibilidade: capturar página (wrapper para captureAction)
214
+ * @param description descrição da captura
215
+ * @param providedScreenshot buffer ou path opcional
216
+ */
217
+ static async capturePage(description, providedScreenshot) {
218
+ try {
219
+ const testInfo = TestContext.getSafeTestInfo();
220
+ const testName = (testInfo && testInfo.title) || 'unknown';
221
+ await EvidenceCapture.captureAction(testName, 'page', description, undefined, providedScreenshot);
222
+ }
223
+ catch (e) {
224
+ Logger.warning(`⚠️ EvidenceCapture.capturePage falhou: ${e}`);
225
+ }
226
+ }
227
+ /**
228
+ * ✅ Obtém evidências de um teste
229
+ */
230
+ static getTestEvidence(testName) {
231
+ return EvidenceCapture.evidenceByTest.get(testName);
232
+ }
233
+ /**
234
+ * ✅ Obtém todas as evidências (sempre carrega dados atualizados quando Map está vazio)
235
+ */
236
+ static getAllEvidence() {
237
+ // 🆕 RECARREGAR dados do arquivo APENAS se o Map estiver vazio
238
+ if (EvidenceCapture.evidenceByTest.size === 0) {
239
+ EvidenceCapture.loadEvidence();
240
+ }
241
+ return EvidenceCapture.evidenceByTest;
242
+ }
243
+ /**
244
+ * ✅ Gera relatório HTML com evidências
245
+ */
246
+ static async generateEvidenceReport() {
247
+ try {
248
+ const reportPath = path.join(EvidenceCapture.playwrightReportDir, 'evidence-report.html');
249
+ const html = EvidenceCapture.generateEvidenceHTML();
250
+ fs.writeFileSync(reportPath, html, 'utf-8');
251
+ Logger.success(`📄 Relatório de evidências gerado: ${reportPath}`);
252
+ }
253
+ catch (error) {
254
+ Logger.error('❌ Erro ao gerar relatório de evidências:', error);
255
+ }
256
+ }
257
+ /**
258
+ * ✅ Gera HTML do relatório de evidências
259
+ */
260
+ static generateEvidenceHTML() {
261
+ const allEvidence = Array.from(EvidenceCapture.evidenceByTest.values());
262
+ // Agrupar por tipo de teste e status
263
+ const groupedEvidence = allEvidence.reduce((groups, evidence) => {
264
+ // Detectar tipo de teste baseado no nome
265
+ let testType = 'Geral';
266
+ if (evidence.testName.toLowerCase().includes('api'))
267
+ testType = 'API';
268
+ else if (evidence.testName.toLowerCase().includes('frontend'))
269
+ testType = 'Frontend';
270
+ else if (evidence.testName.toLowerCase().includes('mobile'))
271
+ testType = 'Mobile';
272
+ else if (evidence.testName.toLowerCase().includes('ssh'))
273
+ testType = 'SSH';
274
+ else if (evidence.testName.toLowerCase().includes('banco'))
275
+ testType = 'Banco';
276
+ if (!groups[testType])
277
+ groups[testType] = [];
278
+ groups[testType].push(evidence);
279
+ return groups;
280
+ }, {});
281
+ const totalTests = allEvidence.length;
282
+ const totalActions = allEvidence.reduce((sum, e) => sum + e.totalActions, 0);
283
+ const successActions = allEvidence.reduce((sum, e) => sum + e.successActions, 0);
284
+ const failedActions = allEvidence.reduce((sum, e) => sum + e.failedActions, 0);
285
+ const successRate = totalActions > 0
286
+ ? ((successActions / totalActions) * 100).toFixed(1)
287
+ : '0.0';
288
+ return `<!DOCTYPE html>
289
+ <html lang="pt-BR">
290
+ <head>
291
+ <meta charset="UTF-8">
292
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
293
+ <title>📸 Relatório de Evidências - TestHUB</title>
294
+ <style>
295
+ * { margin: 0; padding: 0; box-sizing: border-box; }
296
+ body { font-family: 'Segoe UI', system-ui, sans-serif; background: #0f172a; color: #f1f5f9; line-height: 1.6; }
297
+ .light-mode { background-color: #f9fafb !important; color: #111827 !important; }
298
+ .container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
299
+ .header { text-align: center; margin-bottom: 3rem; padding: 2rem; background: linear-gradient(135deg, #1e293b, #334155); border-radius: 1rem; }
300
+ .header h1 { color: #22d3ee; font-size: 2.5rem; margin-bottom: 0.5rem; }
301
+ .header p { color: #94a3b8; font-size: 1.1rem; margin-bottom: 1rem; }
302
+ .header-buttons { margin-top: 1rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
303
+ .btn { background: #10b981; color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 0.5rem; cursor: pointer; font-size: 1rem; font-weight: 600; transition: all 0.3s ease; }
304
+ .btn:hover { background: #059669; transform: translateY(-2px); }
305
+ .btn-theme { background: #3b82f6; }
306
+ .btn-theme:hover { background: #2563eb; }
307
+
308
+ /* Agrupamento por tipo */
309
+ .type-group { margin-bottom: 3rem; background: #1e293b; border-radius: 1rem; padding: 1.5rem; }
310
+ .type-header { display: flex; items-center justify-between; margin-bottom: 2rem; padding-bottom: 1rem; border-bottom: 2px solid #374151; }
311
+ .type-title { font-size: 1.8rem; font-weight: 700; display: flex; items-center gap: 0.5rem; }
312
+ .type-stats { display: flex; gap: 1rem; font-size: 0.9rem; }
313
+ .stat-item { background: #374151; padding: 0.5rem 1rem; border-radius: 0.5rem; }
314
+ .stat-success { color: #10b981; }
315
+ .stat-failed { color: #ef4444; }
316
+ .stat-total { color: #06b6d4; }
317
+
318
+ .tests-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 2rem; }
319
+ .test-card { background: #111827; border-radius: 0.75rem; overflow: hidden; border: 1px solid #374151; }
320
+ .test-card-header { background: #1f2937; padding: 1rem; }
321
+ .test-title { color: #22d3ee; font-size: 1.2rem; font-weight: 600; margin-bottom: 0.5rem; }
322
+ .test-meta { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; font-size: 0.85rem; color: #9ca3af; }
323
+ .test-meta-item { background: #374151; padding: 0.5rem; border-radius: 0.25rem; text-align: center; }
324
+
325
+ .actions-container { padding: 1rem; }
326
+ .action-item { background: #1f2937; border-radius: 0.5rem; margin-bottom: 1rem; overflow: hidden; }
327
+ .action-header { display: flex; justify-content: between; align-items: center; padding: 0.75rem; background: #374151; }
328
+ .action-title { color: #22c55e; font-weight: 600; flex-1; }
329
+ .action-time { color: #94a3b8; font-size: 0.8rem; }
330
+ .action-status { font-size: 0.7rem; padding: 0.25rem 0.5rem; border-radius: 0.25rem; margin-left: 0.5rem; }
331
+ .status-success { background: #059669; color: white; }
332
+ .status-failed { background: #dc2626; color: white; }
333
+ .action-description { color: #e2e8f0; padding: 0.75rem; font-size: 0.9rem; }
334
+ .screenshot-container { padding: 0.75rem; text-align: center; }
335
+ .screenshot { max-width: 100%; max-height: 200px; border-radius: 0.5rem; box-shadow: 0 4px 6px rgba(0,0,0,0.3); cursor: pointer; transition: transform 0.2s; }
336
+ .screenshot:hover { transform: scale(1.05); }
337
+ .no-screenshot { color: #64748b; font-style: italic; padding: 1rem; text-align: center; background: #374151; border-radius: 0.25rem; }
338
+
339
+ .summary-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; margin: 3rem 0; }
340
+ .summary-card { background: linear-gradient(135deg, #1e293b, #334155); padding: 2rem; border-radius: 1rem; text-align: center; }
341
+ .summary-number { font-size: 2.5rem; font-weight: bold; margin-bottom: 0.5rem; }
342
+ .summary-label { color: #94a3b8; font-weight: 500; }
343
+ .summary-tests { color: #06b6d4; }
344
+ .summary-actions { color: #22d3ee; }
345
+ .summary-success { color: #10b981; }
346
+ .summary-failed { color: #ef4444; }
347
+
348
+ .collapsible { cursor: pointer; user-select: none; }
349
+ .collapsible:hover { background: #1f2937; }
350
+ .content { max-height: 300px; overflow-y: auto; }
351
+
352
+ @media (max-width: 768px) {
353
+ .header-buttons { flex-direction: column; align-items: center; }
354
+ .tests-grid { grid-template-columns: 1fr; }
355
+ .type-header { flex-direction: column; gap: 1rem; }
356
+ .type-stats { flex-wrap: wrap; justify-content: center; }
357
+ }
358
+ </style>
359
+ </head>
360
+ <body id="body-root">
361
+ <div class="container">
362
+ <div class="header">
363
+ <h1>📸 Relatório de Evidências TestHUB</h1>
364
+ <p>Documentação visual completa dos testes executados</p>
365
+ <div class="header-buttons">
366
+ <button onclick="toggleTheme()" class="btn btn-theme">🌙 Alternar Tema</button>
367
+ <button onclick="generatePDF()" class="btn">📄 Gerar PDF</button>
368
+ <button onclick="printPage()" class="btn">🖨️ Imprimir</button>
369
+ </div>
370
+ </div>
371
+
372
+ <!-- Estatísticas Resumidas -->
373
+ <div class="summary-stats">
374
+ <div class="summary-card">
375
+ <div class="summary-number summary-tests">${totalTests}</div>
376
+ <div class="summary-label">Testes com Evidências</div>
377
+ </div>
378
+ <div class="summary-card">
379
+ <div class="summary-number summary-actions">${totalActions}</div>
380
+ <div class="summary-label">Total de Ações</div>
381
+ </div>
382
+ <div class="summary-card">
383
+ <div class="summary-number summary-success">${successActions}</div>
384
+ <div class="summary-label">Ações Bem-sucedidas</div>
385
+ </div>
386
+ <div class="summary-card">
387
+ <div class="summary-number summary-failed">${failedActions}</div>
388
+ <div class="summary-label">Ações com Falha</div>
389
+ </div>
390
+ <div class="summary-card">
391
+ <div class="summary-number" style="color: ${Number.parseFloat(successRate) >= 80 ? '#10b981' : Number.parseFloat(successRate) >= 60 ? '#f59e0b' : '#ef4444'}">${successRate}%</div>
392
+ <div class="summary-label">Taxa de Sucesso</div>
393
+ </div>
394
+ </div>
395
+
396
+ <!-- Agrupamento por Tipo de Teste -->
397
+ ${Object.entries(groupedEvidence)
398
+ .map(([testType, evidences]) => `
399
+ <div class="type-group">
400
+ <div class="type-header">
401
+ <div class="type-title">
402
+ ${EvidenceCapture.getTypeIcon(testType)} ${testType}
403
+ <span style="font-size: 0.8rem; color: #9ca3af;">(${evidences.length} teste${evidences.length > 1 ? 's' : ''})</span>
404
+ </div>
405
+ <div class="type-stats">
406
+ <div class="stat-item stat-total">
407
+ 📊 ${evidences.reduce((sum, e) => sum + e.totalActions, 0)} ações
408
+ </div>
409
+ <div class="stat-item stat-success">
410
+ ✅ ${evidences.reduce((sum, e) => sum + e.successActions, 0)} sucessos
411
+ </div>
412
+ <div class="stat-item stat-failed">
413
+ ❌ ${evidences.reduce((sum, e) => sum + e.failedActions, 0)} falhas
414
+ </div>
415
+ </div>
416
+ </div>
417
+
418
+ <div class="tests-grid">
419
+ ${evidences
420
+ .map((evidence) => `
421
+ <div class="test-card">
422
+ <div class="test-card-header collapsible" onclick="toggleTestContent('${evidence.testName.replace(/[^a-zA-Z0-9]/g, '_')}')">
423
+ <div class="test-title">
424
+ 🧪 ${evidence.testName}
425
+ <span id="toggle-${evidence.testName.replace(/[^a-zA-Z0-9]/g, '_')}" style="float: right;">📋</span>
426
+ </div>
427
+ <div class="test-meta">
428
+ <div class="test-meta-item">
429
+ <strong>Início:</strong><br>${evidence.startTime.toLocaleString('pt-BR')}
430
+ </div>
431
+ <div class="test-meta-item">
432
+ <strong>Fim:</strong><br>${evidence.endTime?.toLocaleString('pt-BR') || 'Em execução'}
433
+ </div>
434
+ <div class="test-meta-item">
435
+ <strong>Total de Ações:</strong><br><span class="stat-total">${evidence.totalActions}</span>
436
+ </div>
437
+ <div class="test-meta-item">
438
+ <strong>Taxa de Sucesso:</strong><br>
439
+ <span style="color: ${((evidence.successActions / evidence.totalActions) * 100) >= 80 ? '#10b981' : '#f59e0b'}">
440
+ ${((evidence.successActions / evidence.totalActions) * 100).toFixed(1)}%
441
+ </span>
442
+ </div>
443
+ </div>
444
+ </div>
445
+
446
+ <div id="content-${evidence.testName.replace(/[^a-zA-Z0-9]/g, '_')}" class="actions-container content" style="display: none;">
447
+ ${evidence.items
448
+ .map((item, index) => `
449
+ <div class="action-item">
450
+ <div class="action-header">
451
+ <div class="action-title">
452
+ <span style="color: #9ca3af; font-size: 0.8rem; margin-right: 0.5rem;">#${index + 1}</span>
453
+ 🎯 ${item.action}
454
+ </div>
455
+ <div class="action-time">${item.timestamp.toLocaleTimeString('pt-BR')}</div>
456
+ <div class="action-status ${item.success ? 'status-success' : 'status-failed'}">
457
+ ${item.success ? '✅' : '❌'}
458
+ </div>
459
+ </div>
460
+ <div class="action-description">${item.description}</div>
461
+ <div class="screenshot-container">
462
+ ${item.screenshotPath
463
+ ? `<img src="${item.screenshotPath}" alt="Screenshot da ação ${item.action}" class="screenshot" onclick="openImageModal('${item.screenshotPath}')">`
464
+ : `<div class="no-screenshot">📷 Screenshot não disponível para esta ação</div>`}
465
+ </div>
466
+ </div>
467
+ `)
468
+ .join('')}
469
+ </div>
470
+ </div>
471
+ `)
472
+ .join('')}
473
+ </div>
474
+ </div>
475
+ `)
476
+ .join('')}
477
+ </div>
478
+
479
+ <!-- Modal para visualização de imagem -->
480
+ <div id="imageModal" style="display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9);" onclick="closeImageModal()">
481
+ <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: 90%; max-height: 90%;">
482
+ <img id="modalImage" style="max-width: 100%; max-height: 100%; border-radius: 0.5rem;">
483
+ </div>
484
+ <span style="position: absolute; top: 15px; right: 35px; color: #f1f5f9; font-size: 40px; font-weight: bold; cursor: pointer;" onclick="closeImageModal()">&times;</span>
485
+ </div>
486
+
487
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
488
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
489
+ <script>
490
+ function toggleTheme() {
491
+ document.getElementById('body-root').classList.toggle('light-mode')
492
+ }
493
+
494
+ function toggleTestContent(testId) {
495
+ const content = document.getElementById('content-' + testId)
496
+ const toggle = document.getElementById('toggle-' + testId)
497
+
498
+ if (content.style.display === 'none') {
499
+ content.style.display = 'block'
500
+ toggle.innerHTML = '📋 ▲'
501
+ } else {
502
+ content.style.display = 'none'
503
+ toggle.innerHTML = '📋'
504
+ }
505
+ }
506
+
507
+ function openImageModal(imageSrc) {
508
+ document.getElementById('modalImage').src = imageSrc
509
+ document.getElementById('imageModal').style.display = 'block'
510
+ }
511
+
512
+ function closeImageModal() {
513
+ document.getElementById('imageModal').style.display = 'none'
514
+ }
515
+
516
+ async function generatePDF() {
517
+ const element = document.body;
518
+
519
+ // Aplicar estilos para PDF
520
+ const originalBg = element.style.background;
521
+ const originalColor = element.style.color;
522
+ element.style.background = 'white';
523
+ element.style.color = 'black';
524
+
525
+ try {
526
+ // Usar html2canvas para capturar o conteúdo
527
+ const canvas = await html2canvas(element, {
528
+ scale: 1.5,
529
+ useCORS: false,
530
+ allowTaint: true,
531
+ backgroundColor: '#fff'
532
+ });
533
+
534
+ // Criar PDF com jsPDF
535
+ const { jsPDF } = jspdf;
536
+ const pdf = new jsPDF({
537
+ orientation: 'portrait',
538
+ unit: 'mm',
539
+ format: 'a4'
540
+ });
541
+
542
+ const imgData = canvas.toDataURL('image/jpeg', 0.98);
543
+ const imgWidth = 210;
544
+ const pageHeight = 297;
545
+ const imgHeight = (canvas.height * imgWidth) / canvas.width;
546
+ let heightLeft = imgHeight;
547
+ let position = 0;
548
+
549
+ pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
550
+ heightLeft -= pageHeight;
551
+
552
+ while (heightLeft > 0) {
553
+ position = heightLeft - imgHeight;
554
+ pdf.addPage();
555
+ pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
556
+ heightLeft -= pageHeight;
557
+ }
558
+
559
+ pdf.save('evidencias-testhub-' + new Date().toISOString().split('T')[0] + '.pdf');
560
+ } catch (error) {
561
+ console.error('Erro ao gerar PDF:', error);
562
+ alert('Erro ao gerar PDF: ' + error.message);
563
+ } finally {
564
+ // Restaurar estilos originais
565
+ element.style.background = originalBg;
566
+ element.style.color = originalColor;
567
+ }
568
+ }
569
+
570
+ function printPage() {
571
+ window.print();
572
+ }
573
+ </script>
574
+ </body>
575
+ </html>`;
576
+ }
577
+ /**
578
+ * ✅ Obter ícone do tipo de teste
579
+ */
580
+ static getTypeIcon(testType) {
581
+ const icons = {
582
+ API: '🌐',
583
+ Frontend: '💻',
584
+ Mobile: '📱',
585
+ SSH: '🔧',
586
+ Banco: '🗃️',
587
+ Geral: '📋',
588
+ };
589
+ return icons[testType] || '📋';
590
+ }
591
+ /**
592
+ * ✅ Limpa evidências antigas
593
+ */
594
+ static cleanup() {
595
+ EvidenceCapture.evidenceByTest.clear();
596
+ EvidenceCapture.currentEvidenceId = 0;
597
+ }
598
+ }
599
+ // ✅ Auto-inicialização
600
+ EvidenceCapture.initialize();
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 📸 Organizador de Evidências do AutoCore
3
+ * @description Coleta e organiza screenshots já gerados pelos projetos consumidores (Web/Mobile)
4
+ * @author TestHUB Team
5
+ * @version 1.0.0
6
+ *
7
+ * ⚠️ IMPORTANTE: Este projeto AutoCore NÃO gera evidências
8
+ * Ele apenas coleta e organiza evidências dos projetos consumidores:
9
+ * - Web: C:\Users\{user}\PlayWright\test-simplifique-e2e\test-results\web-screenshots\
10
+ * - Mobile: C:\Users\{user}\PlayWright\mobile\test-results\mobile-screenshots\
11
+ */
12
+ export interface EvidenceScreenshot {
13
+ fileName: string;
14
+ fullPath: string;
15
+ relativePath: string;
16
+ testName: string;
17
+ timestamp: Date;
18
+ size: number;
19
+ base64?: string;
20
+ }
21
+ export declare class EvidenceReportGenerator {
22
+ /**
23
+ * 🎯 Detectar o tipo do projeto atual baseado nas pastas de evidências
24
+ *
25
+ * ℹ️ AutoCore trabalha no projeto atual e verifica se há:
26
+ * - Web: test-results/web-screenshots/
27
+ * - Mobile: test-results/mobile-screenshots/
28
+ */
29
+ private static detectCurrentProjectType;
30
+ /**
31
+ * 🔍 Coleta screenshots em uma pasta específica do projeto consumidor
32
+ */
33
+ private static findScreenshotsInDirectory;
34
+ /**
35
+ * ✅ Gera relatório de evidências procurando screenshots nas pastas padrão
36
+ */
37
+ static generateEvidenceReport(): Promise<void>;
38
+ /**
39
+ * ✅ Procura screenshots em diretórios específicos
40
+ */
41
+ private static findScreenshots;
42
+ /**
43
+ * 🆕 Converte imagem para base64
44
+ */
45
+ private static convertImageToBase64;
46
+ /**
47
+ * ✅ Encontra arquivos recursivamente
48
+ */
49
+ private static findFilesRecursively;
50
+ /**
51
+ * ✅ Extrai nome do teste do caminho ou nome do arquivo
52
+ */
53
+ private static extractTestName;
54
+ /**
55
+ * ✅ Gera HTML do relatório com recursos avançados (igual HTMLTemplate)
56
+ */
57
+ private static generateHTML;
58
+ /**
59
+ * ✅ Agrupa screenshots por teste
60
+ */
61
+ private static groupScreenshotsByTest;
62
+ /**
63
+ * ✅ Formata tamanho de arquivo
64
+ */
65
+ private static formatFileSize;
66
+ /**
67
+ * ✅ Gera relatório vazio quando não há evidências nos projetos consumidores
68
+ */
69
+ private static generateEmptyReport;
70
+ }