@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.
- package/.github/copilot-instructions.md +520 -0
- package/biome.json +37 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +169 -0
- package/dist/scripts/consumer-postinstall.d.ts +15 -0
- package/dist/scripts/consumer-postinstall.js +785 -0
- package/dist/scripts/generate-docs.d.ts +16 -0
- package/dist/scripts/generate-docs.js +1363 -0
- package/dist/scripts/generate-index.d.ts +2 -0
- package/dist/scripts/generate-index.js +314 -0
- package/dist/scripts/init-api.d.ts +2 -0
- package/dist/scripts/init-api.js +525 -0
- package/dist/scripts/init-banco.d.ts +2 -0
- package/dist/scripts/init-banco.js +347 -0
- package/dist/scripts/init-frontend.d.ts +2 -0
- package/dist/scripts/init-frontend.js +627 -0
- package/dist/scripts/init-mobile.d.ts +2 -0
- package/dist/scripts/init-mobile.js +481 -0
- package/dist/scripts/init-scenarios.d.ts +2 -0
- package/dist/scripts/init-scenarios.js +846 -0
- package/dist/scripts/init-ssh.d.ts +2 -0
- package/dist/scripts/init-ssh.js +639 -0
- package/dist/scripts/package-versions.d.ts +57 -0
- package/dist/scripts/package-versions.js +768 -0
- package/dist/scripts/postinstall.d.ts +1 -0
- package/dist/scripts/postinstall.js +527 -0
- package/dist/scripts/robust-build.d.ts +7 -0
- package/dist/scripts/robust-build.js +88 -0
- package/dist/scripts/setup-local-packages.d.ts +31 -0
- package/dist/scripts/setup-local-packages.js +237 -0
- package/dist/scripts/smart-override.d.ts +2 -0
- package/dist/scripts/smart-override.js +1360 -0
- package/dist/scripts/sync-configs.d.ts +27 -0
- package/dist/scripts/sync-configs.js +248 -0
- package/dist/scripts/test-biome-parse.d.ts +5 -0
- package/dist/scripts/test-biome-parse.js +84 -0
- package/dist/scripts/ultracite-setup.d.ts +4 -0
- package/dist/scripts/ultracite-setup.js +310 -0
- package/dist/scripts/update-all-init-scripts.d.ts +2 -0
- package/dist/scripts/update-all-init-scripts.js +52 -0
- package/dist/scripts/update-biome-schema.d.ts +15 -0
- package/dist/scripts/update-biome-schema.js +124 -0
- package/dist/src/AutoCoreFacade.d.ts +145 -0
- package/dist/src/AutoCoreFacade.js +217 -0
- package/dist/src/api/ApiActions.d.ts +297 -0
- package/dist/src/api/ApiActions.js +1905 -0
- package/dist/src/api/Certificate.d.ts +60 -0
- package/dist/src/api/Certificate.js +79 -0
- package/dist/src/api/JsonResponse.d.ts +116 -0
- package/dist/src/api/JsonResponse.js +206 -0
- package/dist/src/appium/DeviceFarmViewer.d.ts +79 -0
- package/dist/src/appium/DeviceFarmViewer.js +1083 -0
- package/dist/src/appium/MobileActions.d.ts +347 -0
- package/dist/src/appium/MobileActions.js +1632 -0
- package/dist/src/appium/MobileConnection.d.ts +160 -0
- package/dist/src/appium/MobileConnection.js +772 -0
- package/dist/src/config/envLoader.d.ts +123 -0
- package/dist/src/config/envLoader.js +361 -0
- package/dist/src/config/jest-safe-setup.d.ts +19 -0
- package/dist/src/config/jest-safe-setup.js +369 -0
- package/dist/src/config/timeouts.d.ts +32 -0
- package/dist/src/config/timeouts.js +38 -0
- package/dist/src/desktop/DesktopActions.d.ts +46 -0
- package/dist/src/desktop/DesktopActions.js +398 -0
- package/dist/src/desktop/DesktopConnection.d.ts +32 -0
- package/dist/src/desktop/DesktopConnection.js +84 -0
- package/dist/src/domain/entities/TestExecution.d.ts +117 -0
- package/dist/src/domain/entities/TestExecution.js +150 -0
- package/dist/src/domain/entities/TestReport.d.ts +114 -0
- package/dist/src/domain/entities/TestReport.js +179 -0
- package/dist/src/domain/repositories/ITestRepository.d.ts +196 -0
- package/dist/src/domain/repositories/ITestRepository.js +14 -0
- package/dist/src/domain/schemas/ValidationSchemas.d.ts +159 -0
- package/dist/src/domain/schemas/ValidationSchemas.js +181 -0
- package/dist/src/functions/errors/BaseError.d.ts +78 -0
- package/dist/src/functions/errors/BaseError.js +245 -0
- package/dist/src/functions/errors/ConfigurationError.d.ts +16 -0
- package/dist/src/functions/errors/ConfigurationError.js +48 -0
- package/dist/src/functions/errors/ErrorCatalog.d.ts +148 -0
- package/dist/src/functions/errors/ErrorCatalog.js +157 -0
- package/dist/src/functions/errors/GlobalErrorHandler.d.ts +101 -0
- package/dist/src/functions/errors/GlobalErrorHandler.js +281 -0
- package/dist/src/functions/errors/IntegrationError.d.ts +17 -0
- package/dist/src/functions/errors/IntegrationError.js +51 -0
- package/dist/src/functions/errors/SecurityError.d.ts +14 -0
- package/dist/src/functions/errors/SecurityError.js +42 -0
- package/dist/src/functions/errors/SystemError.d.ts +12 -0
- package/dist/src/functions/errors/SystemError.js +36 -0
- package/dist/src/functions/errors/ValidationError.d.ts +14 -0
- package/dist/src/functions/errors/ValidationError.js +61 -0
- package/dist/src/functions/errors/index.d.ts +12 -0
- package/dist/src/functions/errors/index.js +13 -0
- package/dist/src/global-setup.d.ts +1 -0
- package/dist/src/global-setup.js +1037 -0
- package/dist/src/helpers/BancoActions.d.ts +188 -0
- package/dist/src/helpers/BancoActions.js +581 -0
- package/dist/src/helpers/EnviromentHelper.d.ts +17 -0
- package/dist/src/helpers/EnviromentHelper.js +66 -0
- package/dist/src/helpers/ParallelExecutionHelper.d.ts +183 -0
- package/dist/src/helpers/ParallelExecutionHelper.js +375 -0
- package/dist/src/helpers/SyncSignal.d.ts +15 -0
- package/dist/src/helpers/SyncSignal.js +44 -0
- package/dist/src/hubdocs/CategoryDetector.d.ts +83 -0
- package/dist/src/hubdocs/CategoryDetector.js +401 -0
- package/dist/src/hubdocs/DirectStatementInterceptor.d.ts +54 -0
- package/dist/src/hubdocs/DirectStatementInterceptor.js +243 -0
- package/dist/src/hubdocs/ExecutionTracker.d.ts +107 -0
- package/dist/src/hubdocs/ExecutionTracker.js +702 -0
- package/dist/src/hubdocs/HubDocs.d.ts +395 -0
- package/dist/src/hubdocs/HubDocs.js +3586 -0
- package/dist/src/hubdocs/StatementMethodFilter.d.ts +71 -0
- package/dist/src/hubdocs/StatementMethodFilter.js +618 -0
- package/dist/src/hubdocs/StatementTracker.d.ts +417 -0
- package/dist/src/hubdocs/StatementTracker.js +2419 -0
- package/dist/src/hubdocs/SwaggerGenerator.d.ts +59 -0
- package/dist/src/hubdocs/SwaggerGenerator.js +405 -0
- package/dist/src/hubdocs/index.d.ts +9 -0
- package/dist/src/hubdocs/index.js +9 -0
- package/dist/src/hubdocs/types.d.ts +114 -0
- package/dist/src/hubdocs/types.js +5 -0
- package/dist/src/infrastructure/DependencyContainer.d.ts +142 -0
- package/dist/src/infrastructure/DependencyContainer.js +250 -0
- package/dist/src/infrastructure/adapters/AppiumAdapter.d.ts +168 -0
- package/dist/src/infrastructure/adapters/AppiumAdapter.js +468 -0
- package/dist/src/infrastructure/adapters/OracleAdapter.d.ts +150 -0
- package/dist/src/infrastructure/adapters/OracleAdapter.js +388 -0
- package/dist/src/infrastructure/adapters/PlaywrightAdapter.d.ts +192 -0
- package/dist/src/infrastructure/adapters/PlaywrightAdapter.js +382 -0
- package/dist/src/infrastructure/adapters/SSHAdapter.d.ts +141 -0
- package/dist/src/infrastructure/adapters/SSHAdapter.js +428 -0
- package/dist/src/interfaces.d.ts +501 -0
- package/dist/src/interfaces.js +25 -0
- package/dist/src/internal/fakes/__fake-actions__.d.ts +17 -0
- package/dist/src/internal/fakes/__fake-actions__.js +21 -0
- package/dist/src/internal/fakes/__forbidden__.d.ts +10 -0
- package/dist/src/internal/fakes/__forbidden__.js +18 -0
- package/dist/src/internal/fakes/__honeypot__.d.ts +15 -0
- package/dist/src/internal/fakes/__honeypot__.js +24 -0
- package/dist/src/octane/OctaneReporter.d.ts +13 -0
- package/dist/src/octane/OctaneReporter.js +61 -0
- package/dist/src/playwright/CryptoActions.d.ts +20 -0
- package/dist/src/playwright/CryptoActions.js +75 -0
- package/dist/src/playwright/EnhancedWebActions.d.ts +7 -0
- package/dist/src/playwright/EnhancedWebActions.js +65 -0
- package/dist/src/playwright/WebActions.d.ts +1599 -0
- package/dist/src/playwright/WebActions.js +11788 -0
- package/dist/src/playwright/actions/ActionTimeline.d.ts +36 -0
- package/dist/src/playwright/actions/ActionTimeline.js +101 -0
- package/dist/src/playwright/actions/RecoveryQueue.d.ts +82 -0
- package/dist/src/playwright/actions/RecoveryQueue.js +130 -0
- package/dist/src/playwright/actions/SelectorCache.d.ts +53 -0
- package/dist/src/playwright/actions/SelectorCache.js +96 -0
- package/dist/src/playwright/actions/index.d.ts +13 -0
- package/dist/src/playwright/actions/index.js +14 -0
- package/dist/src/playwright/actions/types.d.ts +147 -0
- package/dist/src/playwright/actions/types.js +5 -0
- package/dist/src/playwright/fixtures.d.ts +112 -0
- package/dist/src/playwright/fixtures.js +718 -0
- package/dist/src/playwright/network-logs-reporter.d.ts +7 -0
- package/dist/src/playwright/network-logs-reporter.js +66 -0
- package/dist/src/playwright/registerRecoveryWrappers.d.ts +1 -0
- package/dist/src/playwright/registerRecoveryWrappers.js +54 -0
- package/dist/src/security/BuildSecurity.d.ts +12 -0
- package/dist/src/security/BuildSecurity.js +138 -0
- package/dist/src/security/EulaProtection.d.ts +70 -0
- package/dist/src/security/EulaProtection.js +155 -0
- package/dist/src/security/HoneypotManager.d.ts +46 -0
- package/dist/src/security/HoneypotManager.js +234 -0
- package/dist/src/security/KeysManager.d.ts +36 -0
- package/dist/src/security/KeysManager.js +158 -0
- package/dist/src/security/ProofOfWorkIntegration.d.ts +64 -0
- package/dist/src/security/ProofOfWorkIntegration.js +206 -0
- package/dist/src/security/SecurityValidation.d.ts +21 -0
- package/dist/src/security/SecurityValidation.js +163 -0
- package/dist/src/security/SourceMapProtection.d.ts +55 -0
- package/dist/src/security/SourceMapProtection.js +220 -0
- package/dist/src/security/protector.d.ts +1 -0
- package/dist/src/security/protector.js +97 -0
- package/dist/src/ssh/SSHActions.d.ts +262 -0
- package/dist/src/ssh/SSHActions.js +790 -0
- package/dist/src/ssh/SSHClient.d.ts +99 -0
- package/dist/src/ssh/SSHClient.js +409 -0
- package/dist/src/statements/BaseStatement.d.ts +38 -0
- package/dist/src/statements/BaseStatement.js +78 -0
- package/dist/src/testContext/AuthStateManager.d.ts +93 -0
- package/dist/src/testContext/AuthStateManager.js +256 -0
- package/dist/src/testContext/CoverageManager.d.ts +198 -0
- package/dist/src/testContext/CoverageManager.js +917 -0
- package/dist/src/testContext/TestAnnotations.d.ts +476 -0
- package/dist/src/testContext/TestAnnotations.js +2647 -0
- package/dist/src/testContext/TestContext.d.ts +138 -0
- package/dist/src/testContext/TestContext.js +369 -0
- package/dist/src/testContext/UnifiedHtmlGenerator.d.ts +7 -0
- package/dist/src/testContext/UnifiedHtmlGenerator.js +264 -0
- package/dist/src/testContext/UnifiedReportManager.d.ts +211 -0
- package/dist/src/testContext/UnifiedReportManager.js +1206 -0
- package/dist/src/testhub/DynamicConfigManager.d.ts +121 -0
- package/dist/src/testhub/DynamicConfigManager.js +320 -0
- package/dist/src/testhub/SystemsManager.d.ts +119 -0
- package/dist/src/testhub/SystemsManager.js +365 -0
- package/dist/src/testhub/TestHubClient.d.ts +335 -0
- package/dist/src/testhub/TestHubClient.js +1215 -0
- package/dist/src/testhub/TestHubReporter.d.ts +62 -0
- package/dist/src/testhub/TestHubReporter.js +576 -0
- package/dist/src/testhub/TestHubVars.d.ts +116 -0
- package/dist/src/testhub/TestHubVars.js +273 -0
- package/dist/src/utils/ActionInterceptor.d.ts +59 -0
- package/dist/src/utils/ActionInterceptor.js +741 -0
- package/dist/src/utils/ArtifactsCompressor.d.ts +43 -0
- package/dist/src/utils/ArtifactsCompressor.js +181 -0
- package/dist/src/utils/AutoLogsFinal.d.ts +47 -0
- package/dist/src/utils/AutoLogsFinal.js +148 -0
- package/dist/src/utils/CodeGenSession.d.ts +114 -0
- package/dist/src/utils/CodeGenSession.js +264 -0
- package/dist/src/utils/ConfigLogger.d.ts +133 -0
- package/dist/src/utils/ConfigLogger.js +611 -0
- package/dist/src/utils/CustomReporter.d.ts +22 -0
- package/dist/src/utils/CustomReporter.js +352 -0
- package/dist/src/utils/DataStore.d.ts +171 -0
- package/dist/src/utils/DataStore.js +484 -0
- package/dist/src/utils/DatabaseInterceptor.d.ts +19 -0
- package/dist/src/utils/DatabaseInterceptor.js +295 -0
- package/dist/src/utils/DateHelper.d.ts +16 -0
- package/dist/src/utils/DateHelper.js +120 -0
- package/dist/src/utils/DateValidator.d.ts +4 -0
- package/dist/src/utils/DateValidator.js +51 -0
- package/dist/src/utils/DocumentGenerator.d.ts +35 -0
- package/dist/src/utils/DocumentGenerator.js +129 -0
- package/dist/src/utils/EvidenceCapture.d.ts +90 -0
- package/dist/src/utils/EvidenceCapture.js +600 -0
- package/dist/src/utils/EvidenceReportGenerator.d.ts +70 -0
- package/dist/src/utils/EvidenceReportGenerator.js +799 -0
- package/dist/src/utils/FrameManagementUtil.d.ts +42 -0
- package/dist/src/utils/FrameManagementUtil.js +75 -0
- package/dist/src/utils/GlobalStatementsInterceptor.d.ts +1 -0
- package/dist/src/utils/GlobalStatementsInterceptor.js +1 -0
- package/dist/src/utils/HTMLTemplate.d.ts +1 -0
- package/dist/src/utils/HTMLTemplate.js +1034 -0
- package/dist/src/utils/InterceptacaoMagica.d.ts +23 -0
- package/dist/src/utils/InterceptacaoMagica.js +365 -0
- package/dist/src/utils/LogSanitizer.d.ts +35 -0
- package/dist/src/utils/LogSanitizer.js +110 -0
- package/dist/src/utils/Logger.d.ts +65 -0
- package/dist/src/utils/Logger.js +284 -0
- package/dist/src/utils/McpLocalClient.d.ts +141 -0
- package/dist/src/utils/McpLocalClient.js +871 -0
- package/dist/src/utils/PDFEvidenceGenerator.d.ts +20 -0
- package/dist/src/utils/PDFEvidenceGenerator.js +156 -0
- package/dist/src/utils/SpecFileAnalyzer.d.ts +35 -0
- package/dist/src/utils/SpecFileAnalyzer.js +209 -0
- package/dist/src/utils/StatementInterceptor.d.ts +18 -0
- package/dist/src/utils/StatementInterceptor.js +87 -0
- package/dist/src/utils/StatementLogger.d.ts +33 -0
- package/dist/src/utils/StatementLogger.js +113 -0
- package/dist/src/utils/StatementsInterceptor.d.ts +1 -0
- package/dist/src/utils/StatementsInterceptor.js +1 -0
- package/dist/src/utils/TeamsFlushHook.d.ts +17 -0
- package/dist/src/utils/TeamsFlushHook.js +168 -0
- package/dist/src/utils/TerminalLogCapture.d.ts +158 -0
- package/dist/src/utils/TerminalLogCapture.js +531 -0
- package/dist/src/utils/TestMethodLogger.d.ts +70 -0
- package/dist/src/utils/TestMethodLogger.js +95 -0
- package/dist/src/utils/UnifiedTeardown.d.ts +4 -0
- package/dist/src/utils/UnifiedTeardown.js +400 -0
- package/dist/src/utils/XPathCatalog.d.ts +152 -0
- package/dist/src/utils/XPathCatalog.js +350 -0
- package/dist/src/utils/generators.d.ts +90 -0
- package/dist/src/utils/generators.js +167 -0
- package/dist/src/utils/testRecovery/ResilientPlaywright.d.ts +152 -0
- package/dist/src/utils/testRecovery/ResilientPlaywright.js +715 -0
- package/dist/src/utils/testRecovery/TestRecoveryClient.d.ts +801 -0
- package/dist/src/utils/testRecovery/TestRecoveryClient.js +1415 -0
- package/dist/src/utils/testRecovery/autoFixCode.d.ts +65 -0
- package/dist/src/utils/testRecovery/autoFixCode.js +32 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.config.js +59 -0
- package/dist/wdio.conf.d.ts +1 -0
- package/dist/wdio.conf.js +420 -0
- package/package.json +137 -0
- package/protect-loader.mjs +643 -0
- package/scripts/consumer-postinstall.ts +975 -0
- package/scripts/generate-index.ts +343 -0
- package/scripts/init-api.ts +613 -0
- package/scripts/init-banco.ts +437 -0
- package/scripts/init-frontend.ts +727 -0
- package/scripts/init-mobile.ts +558 -0
- package/scripts/init-scenarios.ts +925 -0
- package/scripts/init-ssh.ts +734 -0
- package/scripts/package-versions.ts +978 -0
- package/scripts/postinstall.ts +605 -0
- package/scripts/smart-override.ts +1675 -0
- package/scripts/sync-configs.ts +302 -0
- package/scripts/ultracite-setup.ts +370 -0
- package/src/types/globals.d.ts +48 -0
- package/tsconfig.json +29 -0
- package/types/autocore-sync-signal.d.ts +10 -0
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔍 ExecutionTracker - Interceptador Principal
|
|
3
|
+
* @silasfmartins/testhub - Auto Documentation System
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { createRequire } from 'module';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
export class ExecutionTracker {
|
|
10
|
+
// 🛡️ CRITICAL: Proteção contra recursão infinita
|
|
11
|
+
static isExecutingInternal = false;
|
|
12
|
+
/**
|
|
13
|
+
* 🔗 HOOK: Notificar StatementTracker sobre ações executadas
|
|
14
|
+
*/
|
|
15
|
+
static notifyStatementTracker(actionType, description, success, duration) {
|
|
16
|
+
try {
|
|
17
|
+
// Import dinâmico para evitar dependência circular
|
|
18
|
+
const { StatementTracker } = require('./StatementTracker.js');
|
|
19
|
+
StatementTracker.recordAction(actionType, description, success, duration);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
// Silencioso - StatementTracker pode não estar disponível
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ✅ NOVO: Obter versão atual do AutoCore (com proteção contra recursão)
|
|
27
|
+
*/
|
|
28
|
+
static getAutoCoreVersion() {
|
|
29
|
+
// 🛡️ Evita recursão infinita durante interceptação
|
|
30
|
+
if (ExecutionTracker.isExecutingInternal) {
|
|
31
|
+
return '1.1.X'; // Fallback seguro
|
|
32
|
+
}
|
|
33
|
+
ExecutionTracker.isExecutingInternal = true;
|
|
34
|
+
try {
|
|
35
|
+
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
|
|
36
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
37
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
38
|
+
return (packageJson.dependencies?.['@silasfmartins/testhub'] ||
|
|
39
|
+
packageJson.devDependencies?.['@silasfmartins/testhub'] ||
|
|
40
|
+
'1.1.X');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.warn(`⚠️ Erro ao ler versão do AutoCore: ${error}`);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
ExecutionTracker.isExecutingInternal = false;
|
|
48
|
+
}
|
|
49
|
+
return '1.1.X';
|
|
50
|
+
}
|
|
51
|
+
static data = {
|
|
52
|
+
apis: [],
|
|
53
|
+
ssh: [],
|
|
54
|
+
db: [],
|
|
55
|
+
ui: [],
|
|
56
|
+
mobile: [],
|
|
57
|
+
metadata: {
|
|
58
|
+
startTime: new Date().toISOString(),
|
|
59
|
+
endTime: '',
|
|
60
|
+
environment: process.env.NODE_ENV || 'development',
|
|
61
|
+
totalTests: 0,
|
|
62
|
+
passedTests: 0,
|
|
63
|
+
failedTests: 0,
|
|
64
|
+
framework: 'TestHub',
|
|
65
|
+
version: '1.1.X', // ✅ FIXO INICIALMENTE - será atualizado no initialize()
|
|
66
|
+
projectName: 'TestHub Project',
|
|
67
|
+
projectType: 'Mixed',
|
|
68
|
+
duration: 0,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
static config = {
|
|
72
|
+
enabled: true,
|
|
73
|
+
categories: ['api', 'ssh', 'db', 'ui', 'mobile'],
|
|
74
|
+
outputDir: './docs',
|
|
75
|
+
includeRequestBody: true,
|
|
76
|
+
includeResponseBody: true,
|
|
77
|
+
generateSwagger: true,
|
|
78
|
+
includeScreenshots: false,
|
|
79
|
+
maxRequestSize: 10_000, // 10KB
|
|
80
|
+
maxResponseSize: 50_000, // 50KB
|
|
81
|
+
};
|
|
82
|
+
static tempDir = path.resolve(process.cwd(), '.rbqa');
|
|
83
|
+
static dataFile = path.join(this.tempDir, 'execution-data.json');
|
|
84
|
+
/**
|
|
85
|
+
* ✅ Inicializar o tracker
|
|
86
|
+
*/
|
|
87
|
+
static initialize(projectName, projectType) {
|
|
88
|
+
// ✅ ATUALIZAR: Versão dinâmica sempre
|
|
89
|
+
ExecutionTracker.data.metadata.version =
|
|
90
|
+
ExecutionTracker.getAutoCoreVersion();
|
|
91
|
+
// ✅ NOVA: Detecção inteligente do nome do projeto
|
|
92
|
+
const detectedProjectName = projectName ||
|
|
93
|
+
process.env.npm_package_name ||
|
|
94
|
+
ExecutionTracker.detectProjectNameFromPath() ||
|
|
95
|
+
'AutoCore Project';
|
|
96
|
+
// ✅ NOVA: Detecção inteligente do tipo de projeto
|
|
97
|
+
const detectedProjectType = projectType || ExecutionTracker.detectProjectType() || 'API';
|
|
98
|
+
ExecutionTracker.data.metadata.projectName = detectedProjectName;
|
|
99
|
+
ExecutionTracker.data.metadata.projectType = detectedProjectType;
|
|
100
|
+
ExecutionTracker.data.metadata.startTime = new Date().toISOString();
|
|
101
|
+
// Criar diretório temporário
|
|
102
|
+
if (!fs.existsSync(ExecutionTracker.tempDir)) {
|
|
103
|
+
fs.mkdirSync(ExecutionTracker.tempDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* ✅ NOVO: Detectar nome do projeto a partir do caminho
|
|
108
|
+
*/
|
|
109
|
+
static detectProjectNameFromPath() {
|
|
110
|
+
try {
|
|
111
|
+
const cwd = process.cwd();
|
|
112
|
+
const projectName = path.basename(cwd);
|
|
113
|
+
// Se contém indicadores de projeto de teste API
|
|
114
|
+
if (projectName.includes('test') ||
|
|
115
|
+
projectName.includes('api') ||
|
|
116
|
+
projectName.includes('oss')) {
|
|
117
|
+
return projectName;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* ✅ NOVO: Detectar tipo de projeto automaticamente
|
|
127
|
+
*/
|
|
128
|
+
static detectProjectType() {
|
|
129
|
+
try {
|
|
130
|
+
const cwd = process.cwd();
|
|
131
|
+
const projectName = path.basename(cwd).toLowerCase();
|
|
132
|
+
const packageName = process.env.npm_package_name?.toLowerCase() || '';
|
|
133
|
+
// Verificar indicadores de API
|
|
134
|
+
const apiIndicators = [
|
|
135
|
+
'api',
|
|
136
|
+
'test-oss-api',
|
|
137
|
+
'oss-api',
|
|
138
|
+
'autocore',
|
|
139
|
+
'rest',
|
|
140
|
+
'service',
|
|
141
|
+
];
|
|
142
|
+
if (apiIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
|
|
143
|
+
return 'API';
|
|
144
|
+
}
|
|
145
|
+
// Verificar indicadores Mobile
|
|
146
|
+
const mobileIndicators = ['mobile', 'appium', 'android', 'ios'];
|
|
147
|
+
if (mobileIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
|
|
148
|
+
return 'Mobile';
|
|
149
|
+
}
|
|
150
|
+
// Verificar indicadores Frontend
|
|
151
|
+
const frontendIndicators = ['frontend', 'web', 'ui', 'playwright'];
|
|
152
|
+
if (frontendIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
|
|
153
|
+
return 'Frontend';
|
|
154
|
+
}
|
|
155
|
+
// Padrão para projetos com "test" no nome
|
|
156
|
+
if (projectName.includes('test') || packageName.includes('test')) {
|
|
157
|
+
return 'API'; // Assumir API como padrão para projetos de teste
|
|
158
|
+
}
|
|
159
|
+
return 'Mixed';
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return 'Mixed';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 🌐 Rastrear chamada de API
|
|
167
|
+
*/
|
|
168
|
+
static trackAPI(call) {
|
|
169
|
+
// ✅ CRÍTICO: Auto-inicializar se necessário
|
|
170
|
+
if (!fs.existsSync(ExecutionTracker.tempDir)) {
|
|
171
|
+
ExecutionTracker.initialize();
|
|
172
|
+
}
|
|
173
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
174
|
+
ExecutionTracker.config.categories.includes('api')))
|
|
175
|
+
return;
|
|
176
|
+
// Limitar tamanho de payload/response se configurado
|
|
177
|
+
if (call.payload &&
|
|
178
|
+
JSON.stringify(call.payload).length >
|
|
179
|
+
ExecutionTracker.config.maxRequestSize) {
|
|
180
|
+
call.payload = {
|
|
181
|
+
__truncated: true,
|
|
182
|
+
size: JSON.stringify(call.payload).length,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (call.response &&
|
|
186
|
+
JSON.stringify(call.response).length >
|
|
187
|
+
ExecutionTracker.config.maxResponseSize) {
|
|
188
|
+
call.response = {
|
|
189
|
+
__truncated: true,
|
|
190
|
+
size: JSON.stringify(call.response).length,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
ExecutionTracker.data.apis.push(call);
|
|
194
|
+
ExecutionTracker.saveToFile();
|
|
195
|
+
// 🔗 HOOK: Notificar StatementTracker
|
|
196
|
+
ExecutionTracker.notifyStatementTracker('API', `${call.method} ${call.url}`, call.success, call.duration);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* 🔄 Atualizar resultado de API específica
|
|
200
|
+
*/
|
|
201
|
+
static updateAPIResult(docId, response, statusCode, error) {
|
|
202
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
203
|
+
ExecutionTracker.config.categories.includes('api')))
|
|
204
|
+
return;
|
|
205
|
+
try {
|
|
206
|
+
// Encontrar a API pelo ID
|
|
207
|
+
const apiIndex = ExecutionTracker.data.apis.findIndex((api) => api.id === docId);
|
|
208
|
+
if (apiIndex !== -1) {
|
|
209
|
+
// Atualizar dados da API
|
|
210
|
+
ExecutionTracker.data.apis[apiIndex].success =
|
|
211
|
+
!error && statusCode !== undefined && statusCode < 400;
|
|
212
|
+
ExecutionTracker.data.apis[apiIndex].statusCode =
|
|
213
|
+
statusCode || (error ? 500 : 200);
|
|
214
|
+
ExecutionTracker.data.apis[apiIndex].error = error
|
|
215
|
+
? String(error)
|
|
216
|
+
: null;
|
|
217
|
+
// Adicionar response se fornecido
|
|
218
|
+
if (response) {
|
|
219
|
+
ExecutionTracker.data.apis[apiIndex].response = response;
|
|
220
|
+
}
|
|
221
|
+
// Calcular duração se possível
|
|
222
|
+
const startTime = new Date(ExecutionTracker.data.apis[apiIndex].timestamp).getTime();
|
|
223
|
+
ExecutionTracker.data.apis[apiIndex].duration = Date.now() - startTime;
|
|
224
|
+
ExecutionTracker.saveToFile();
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.warn(`📚 ExecutionTracker: API com ID ${docId} não encontrada para atualização`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
console.error(`❌ ExecutionTracker.updateAPIResult erro crítico: ${error}`);
|
|
232
|
+
// ✅ NOVO: Mesmo com erro, tentar salvar o que já existe
|
|
233
|
+
try {
|
|
234
|
+
ExecutionTracker.saveToFile();
|
|
235
|
+
}
|
|
236
|
+
catch (saveError) {
|
|
237
|
+
console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 🖥️ Rastrear comando SSH
|
|
243
|
+
*/
|
|
244
|
+
static trackSSH(command) {
|
|
245
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
246
|
+
ExecutionTracker.config.categories.includes('ssh')))
|
|
247
|
+
return;
|
|
248
|
+
ExecutionTracker.data.ssh.push(command);
|
|
249
|
+
ExecutionTracker.saveToFile();
|
|
250
|
+
// 🔗 HOOK: Notificar StatementTracker
|
|
251
|
+
ExecutionTracker.notifyStatementTracker('SSH', command.command, command.success, command.duration);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 🔄 Atualizar resultado de comando SSH específico
|
|
255
|
+
*/
|
|
256
|
+
static updateSSHResult(command, timestamp, success, duration, exitCode, error) {
|
|
257
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
258
|
+
ExecutionTracker.config.categories.includes('ssh')))
|
|
259
|
+
return;
|
|
260
|
+
try {
|
|
261
|
+
// Encontrar o comando SSH pelo command e timestamp (mais preciso)
|
|
262
|
+
const sshIndex = ExecutionTracker.data.ssh.findIndex((ssh) => ssh.command === command &&
|
|
263
|
+
Math.abs(new Date(ssh.timestamp).getTime() - new Date(timestamp).getTime()) < 5000);
|
|
264
|
+
if (sshIndex !== -1) {
|
|
265
|
+
// Atualizar dados do comando SSH
|
|
266
|
+
ExecutionTracker.data.ssh[sshIndex].success = success;
|
|
267
|
+
ExecutionTracker.data.ssh[sshIndex].duration = duration;
|
|
268
|
+
ExecutionTracker.data.ssh[sshIndex].error = error || undefined;
|
|
269
|
+
// Atualizar exitCode se fornecido
|
|
270
|
+
if (exitCode !== undefined) {
|
|
271
|
+
ExecutionTracker.data.ssh[sshIndex].exitCode = exitCode;
|
|
272
|
+
}
|
|
273
|
+
ExecutionTracker.saveToFile();
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
console.warn('📊 ExecutionTracker: Comando SSH não encontrado para atualização');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
console.error(`❌ ExecutionTracker.updateSSHResult erro crítico: ${error}`);
|
|
281
|
+
try {
|
|
282
|
+
ExecutionTracker.saveToFile();
|
|
283
|
+
}
|
|
284
|
+
catch (saveError) {
|
|
285
|
+
console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* 🗄️ Rastrear query de banco
|
|
291
|
+
*/
|
|
292
|
+
static trackDB(query) {
|
|
293
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
294
|
+
ExecutionTracker.config.categories.includes('db')))
|
|
295
|
+
return;
|
|
296
|
+
ExecutionTracker.data.db.push(query);
|
|
297
|
+
ExecutionTracker.saveToFile();
|
|
298
|
+
// 🔗 HOOK: Notificar StatementTracker
|
|
299
|
+
ExecutionTracker.notifyStatementTracker('DB', query.query.substring(0, 50) + '...', query.success, query.duration);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* 🔄 Atualizar resultado de query de banco específica
|
|
303
|
+
*/
|
|
304
|
+
static updateDBResult(query, timestamp, success, duration, error, resultCount) {
|
|
305
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
306
|
+
ExecutionTracker.config.categories.includes('db')))
|
|
307
|
+
return;
|
|
308
|
+
try {
|
|
309
|
+
console.log(`🔄 [ExecutionTracker] Tentando atualizar query: ${query.substring(0, 50)}... (success: ${success})`);
|
|
310
|
+
// Encontrar a query pelo SQL e timestamp (mais preciso)
|
|
311
|
+
const dbIndex = ExecutionTracker.data.db.findIndex((db) => db.query === query &&
|
|
312
|
+
Math.abs(new Date(db.timestamp).getTime() - new Date(timestamp).getTime()) < 5000);
|
|
313
|
+
if (dbIndex !== -1) {
|
|
314
|
+
console.log(`✅ [ExecutionTracker] Query encontrada no índice ${dbIndex}, atualizando...`);
|
|
315
|
+
// Atualizar dados da query
|
|
316
|
+
ExecutionTracker.data.db[dbIndex].success = success;
|
|
317
|
+
ExecutionTracker.data.db[dbIndex].duration = duration;
|
|
318
|
+
ExecutionTracker.data.db[dbIndex].error = error || undefined;
|
|
319
|
+
// Adicionar contagem de resultados se fornecida
|
|
320
|
+
if (resultCount !== undefined) {
|
|
321
|
+
;
|
|
322
|
+
ExecutionTracker.data.db[dbIndex].resultCount = resultCount;
|
|
323
|
+
console.log(`📊 [ExecutionTracker] Resultados: ${resultCount} registros`);
|
|
324
|
+
}
|
|
325
|
+
ExecutionTracker.saveToFile();
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
console.warn('📊 ExecutionTracker: Query de banco não encontrada para atualização');
|
|
329
|
+
console.warn(`📊 Queries disponíveis: ${ExecutionTracker.data.db.length}`);
|
|
330
|
+
if (ExecutionTracker.data.db.length > 0) {
|
|
331
|
+
console.warn(`📊 Primeira query: ${ExecutionTracker.data.db[0].query.substring(0, 50)}...`);
|
|
332
|
+
console.warn(`📊 Timestamp procurado: ${timestamp}`);
|
|
333
|
+
console.warn(`📊 Timestamp primeira: ${ExecutionTracker.data.db[0].timestamp}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
console.error(`❌ ExecutionTracker.updateDBResult erro crítico: ${error}`);
|
|
339
|
+
try {
|
|
340
|
+
ExecutionTracker.saveToFile();
|
|
341
|
+
}
|
|
342
|
+
catch (saveError) {
|
|
343
|
+
console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* 🎨 Rastrear ação de UI
|
|
349
|
+
*/
|
|
350
|
+
static trackUI(action) {
|
|
351
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
352
|
+
ExecutionTracker.config.categories.includes('ui')))
|
|
353
|
+
return;
|
|
354
|
+
ExecutionTracker.data.ui.push(action);
|
|
355
|
+
ExecutionTracker.saveToFile();
|
|
356
|
+
// 🔗 HOOK: Notificar StatementTracker
|
|
357
|
+
ExecutionTracker.notifyStatementTracker('UI', `${action.action} ${action.element || ''}`, action.success, action.duration);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* 📱 Rastrear ação mobile
|
|
361
|
+
*/
|
|
362
|
+
static trackMobile(action) {
|
|
363
|
+
if (!(ExecutionTracker.config.enabled &&
|
|
364
|
+
ExecutionTracker.config.categories.includes('mobile')))
|
|
365
|
+
return;
|
|
366
|
+
ExecutionTracker.data.mobile.push(action);
|
|
367
|
+
ExecutionTracker.saveToFile();
|
|
368
|
+
// 🔗 HOOK: Notificar StatementTracker
|
|
369
|
+
ExecutionTracker.notifyStatementTracker('MOBILE', `${action.action} ${action.element || ''}`, undefined, undefined);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* 📊 Atualizar estatísticas de testes
|
|
373
|
+
*/
|
|
374
|
+
static updateTestStats(total, passed, failed) {
|
|
375
|
+
ExecutionTracker.data.metadata.totalTests = total;
|
|
376
|
+
ExecutionTracker.data.metadata.passedTests = passed;
|
|
377
|
+
ExecutionTracker.data.metadata.failedTests = failed;
|
|
378
|
+
ExecutionTracker.saveToFile();
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* 💾 Salvar dados em arquivo temporário (COM PROTEÇÃO CONTRA PERDA)
|
|
382
|
+
*/
|
|
383
|
+
static saveToFile() {
|
|
384
|
+
// 🛡️ CRITICAL: Proteção total contra recursão infinita
|
|
385
|
+
if (ExecutionTracker.isExecutingInternal) {
|
|
386
|
+
return; // Sair silenciosamente se já executando
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
// Marcar como executando para evitar recursão
|
|
390
|
+
ExecutionTracker.isExecutingInternal = true;
|
|
391
|
+
// Garantir que o diretório existe
|
|
392
|
+
if (!fs.existsSync(ExecutionTracker.tempDir)) {
|
|
393
|
+
fs.mkdirSync(ExecutionTracker.tempDir, { recursive: true });
|
|
394
|
+
}
|
|
395
|
+
// ✅ PROTEÇÃO: Verificar se há dados antes de salvar
|
|
396
|
+
const totalItems = ExecutionTracker.data.apis.length +
|
|
397
|
+
ExecutionTracker.data.ssh.length +
|
|
398
|
+
ExecutionTracker.data.db.length +
|
|
399
|
+
ExecutionTracker.data.ui.length +
|
|
400
|
+
ExecutionTracker.data.mobile.length;
|
|
401
|
+
// ✅ CRÍTICO: Se arquivo existe e tem dados, mas memória está vazia, CARREGAR do arquivo
|
|
402
|
+
if (totalItems === 0 && fs.existsSync(ExecutionTracker.dataFile)) {
|
|
403
|
+
const fileData = ExecutionTracker.loadFromFile();
|
|
404
|
+
if (fileData &&
|
|
405
|
+
(fileData.apis.length > 0 ||
|
|
406
|
+
fileData.ssh.length > 0 ||
|
|
407
|
+
fileData.db.length > 0 ||
|
|
408
|
+
fileData.ui.length > 0 ||
|
|
409
|
+
fileData.mobile.length > 0)) {
|
|
410
|
+
ExecutionTracker.data = {
|
|
411
|
+
...fileData,
|
|
412
|
+
metadata: {
|
|
413
|
+
...fileData.metadata,
|
|
414
|
+
// Manter metadados atualizados mas preservar dados
|
|
415
|
+
endTime: ExecutionTracker.data.metadata.endTime ||
|
|
416
|
+
fileData.metadata.endTime,
|
|
417
|
+
duration: ExecutionTracker.data.metadata.duration ||
|
|
418
|
+
fileData.metadata.duration,
|
|
419
|
+
},
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// ✅ NOVO: Detectar versão atual do AutoCore (com proteção)
|
|
424
|
+
if (!ExecutionTracker.isExecutingInternal) {
|
|
425
|
+
ExecutionTracker.data.metadata.version =
|
|
426
|
+
ExecutionTracker.getAutoCoreVersion();
|
|
427
|
+
}
|
|
428
|
+
// ✅ MELHORAR: Detectar tipo de projeto baseado nos dados coletados
|
|
429
|
+
if (ExecutionTracker.data.apis.length > 0 &&
|
|
430
|
+
ExecutionTracker.data.ui.length === 0 &&
|
|
431
|
+
ExecutionTracker.data.mobile.length === 0) {
|
|
432
|
+
ExecutionTracker.data.metadata.projectType = 'API';
|
|
433
|
+
}
|
|
434
|
+
else if (ExecutionTracker.data.ui.length > 0 &&
|
|
435
|
+
ExecutionTracker.data.mobile.length === 0) {
|
|
436
|
+
ExecutionTracker.data.metadata.projectType = 'Frontend';
|
|
437
|
+
}
|
|
438
|
+
else if (ExecutionTracker.data.mobile.length > 0) {
|
|
439
|
+
ExecutionTracker.data.metadata.projectType = 'Mobile';
|
|
440
|
+
}
|
|
441
|
+
else if (ExecutionTracker.data.ssh.length > 0) {
|
|
442
|
+
ExecutionTracker.data.metadata.projectType = 'SSH';
|
|
443
|
+
}
|
|
444
|
+
else if (ExecutionTracker.data.db.length > 0) {
|
|
445
|
+
ExecutionTracker.data.metadata.projectType = 'Database';
|
|
446
|
+
}
|
|
447
|
+
else if (ExecutionTracker.data.apis.length > 0 &&
|
|
448
|
+
(ExecutionTracker.data.ui.length > 0 ||
|
|
449
|
+
ExecutionTracker.data.mobile.length > 0 ||
|
|
450
|
+
ExecutionTracker.data.ssh.length > 0 ||
|
|
451
|
+
ExecutionTracker.data.db.length > 0)) {
|
|
452
|
+
ExecutionTracker.data.metadata.projectType = 'Mixed';
|
|
453
|
+
}
|
|
454
|
+
// ✅ NOVO: Atualizar estatísticas em tempo real
|
|
455
|
+
ExecutionTracker.data.metadata.endTime = new Date().toISOString();
|
|
456
|
+
ExecutionTracker.data.metadata.duration =
|
|
457
|
+
new Date().getTime() -
|
|
458
|
+
new Date(ExecutionTracker.data.metadata.startTime).getTime();
|
|
459
|
+
// ✅ PROTEÇÃO MELHORADA: Backup seguro com retry
|
|
460
|
+
const backupFile = ExecutionTracker.dataFile + '.backup';
|
|
461
|
+
let backupSuccess = false;
|
|
462
|
+
// Tentar fazer backup com retry para arquivo ocupado
|
|
463
|
+
if (fs.existsSync(ExecutionTracker.dataFile)) {
|
|
464
|
+
for (let retry = 0; retry < 3; retry++) {
|
|
465
|
+
try {
|
|
466
|
+
// Se backup existe, remover primeiro
|
|
467
|
+
if (fs.existsSync(backupFile)) {
|
|
468
|
+
fs.unlinkSync(backupFile);
|
|
469
|
+
}
|
|
470
|
+
// Fazer backup
|
|
471
|
+
fs.copyFileSync(ExecutionTracker.dataFile, backupFile);
|
|
472
|
+
backupSuccess = true;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
if (error.code === 'EBUSY' && retry < 2) {
|
|
477
|
+
// Esperar um pouco e tentar novamente (sem async/await para evitar problemas)
|
|
478
|
+
const start = Date.now();
|
|
479
|
+
while (Date.now() - start < 100) {
|
|
480
|
+
// Busy wait for 100ms
|
|
481
|
+
}
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
// Ignorar erros de backup - não é crítico
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
fs.writeFileSync(ExecutionTracker.dataFile, JSON.stringify(ExecutionTracker.data, null, 2));
|
|
490
|
+
// Log de debug detalhado
|
|
491
|
+
const stats = `APIs: ${ExecutionTracker.data.apis.length}, SSH: ${ExecutionTracker.data.ssh.length}, DB: ${ExecutionTracker.data.db.length}, UI: ${ExecutionTracker.data.ui.length}, Mobile: ${ExecutionTracker.data.mobile.length}`;
|
|
492
|
+
// ✅ VERIFICAÇÃO: Confirmar que arquivo foi salvo corretamente
|
|
493
|
+
if (fs.existsSync(ExecutionTracker.dataFile)) {
|
|
494
|
+
const savedSize = fs.statSync(ExecutionTracker.dataFile).size;
|
|
495
|
+
if (savedSize > 10) {
|
|
496
|
+
// Arquivo deve ter pelo menos estrutura mínima
|
|
497
|
+
// Remover backup após confirmação
|
|
498
|
+
if (fs.existsSync(backupFile)) {
|
|
499
|
+
fs.unlinkSync(backupFile);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
console.warn(`⚠️ ExecutionTracker: Arquivo muito pequeno (${savedSize} bytes), possível problema`);
|
|
504
|
+
// Restaurar backup se houver
|
|
505
|
+
if (fs.existsSync(backupFile)) {
|
|
506
|
+
fs.copyFileSync(backupFile, ExecutionTracker.dataFile);
|
|
507
|
+
console.log('🔄 ExecutionTracker: Backup restaurado');
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
console.warn(' ⚠️ AutoDocs: Erro ao salvar dados temporários:', error);
|
|
514
|
+
}
|
|
515
|
+
finally {
|
|
516
|
+
// SEMPRE resetar flag de execução
|
|
517
|
+
ExecutionTracker.isExecutingInternal = false;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* 📖 Recuperar dados do arquivo
|
|
522
|
+
*/
|
|
523
|
+
static loadFromFile() {
|
|
524
|
+
try {
|
|
525
|
+
if (fs.existsSync(ExecutionTracker.dataFile)) {
|
|
526
|
+
const fileData = fs.readFileSync(ExecutionTracker.dataFile, 'utf8');
|
|
527
|
+
const parsedData = JSON.parse(fileData);
|
|
528
|
+
const stats = `APIs: ${parsedData.apis?.length || 0}, SSH: ${parsedData.ssh?.length || 0}, DB: ${parsedData.db?.length || 0}, UI: ${parsedData.ui?.length || 0}, Mobile: ${parsedData.mobile?.length || 0}`;
|
|
529
|
+
return parsedData;
|
|
530
|
+
}
|
|
531
|
+
console.log('📊 ExecutionTracker.loadFromFile: Arquivo não existe');
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
console.warn(`⚠️ ExecutionTracker.loadFromFile: Erro ao carregar dados: ${error}`);
|
|
535
|
+
}
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* 📋 Obter dados atuais (COM PROTEÇÃO CONTRA PERDA)
|
|
540
|
+
*/
|
|
541
|
+
static getData() {
|
|
542
|
+
// ✅ PROTEÇÃO: Verificar se dados em memória estão vazios mas arquivo existe
|
|
543
|
+
const memoryTotal = ExecutionTracker.data.apis.length +
|
|
544
|
+
ExecutionTracker.data.ssh.length +
|
|
545
|
+
ExecutionTracker.data.db.length +
|
|
546
|
+
ExecutionTracker.data.ui.length +
|
|
547
|
+
ExecutionTracker.data.mobile.length;
|
|
548
|
+
// Tentar carregar do arquivo primeiro
|
|
549
|
+
const fileData = ExecutionTracker.loadFromFile();
|
|
550
|
+
if (fileData) {
|
|
551
|
+
const fileTotal = fileData.apis.length +
|
|
552
|
+
fileData.ssh.length +
|
|
553
|
+
fileData.db.length +
|
|
554
|
+
fileData.ui.length +
|
|
555
|
+
fileData.mobile.length;
|
|
556
|
+
// ✅ CRÍTICO: Se arquivo tem dados mas memória está vazia, usar arquivo
|
|
557
|
+
if (fileTotal > 0 && memoryTotal === 0) {
|
|
558
|
+
ExecutionTracker.data = fileData;
|
|
559
|
+
return fileData;
|
|
560
|
+
}
|
|
561
|
+
// ✅ NOVO: Se arquivo tem mais dados que memória, usar arquivo
|
|
562
|
+
if (fileTotal > memoryTotal) {
|
|
563
|
+
ExecutionTracker.data = fileData;
|
|
564
|
+
return fileData;
|
|
565
|
+
}
|
|
566
|
+
// ✅ MESCLAR: Se ambos têm dados, mesclar preservando o que for maior
|
|
567
|
+
if (fileTotal > 0 && memoryTotal > 0) {
|
|
568
|
+
// Usar o que tiver mais dados para cada categoria
|
|
569
|
+
const mergedData = {
|
|
570
|
+
apis: fileData.apis.length >= ExecutionTracker.data.apis.length
|
|
571
|
+
? fileData.apis
|
|
572
|
+
: ExecutionTracker.data.apis,
|
|
573
|
+
ssh: fileData.ssh.length >= ExecutionTracker.data.ssh.length
|
|
574
|
+
? fileData.ssh
|
|
575
|
+
: ExecutionTracker.data.ssh,
|
|
576
|
+
db: fileData.db.length >= ExecutionTracker.data.db.length
|
|
577
|
+
? fileData.db
|
|
578
|
+
: ExecutionTracker.data.db,
|
|
579
|
+
ui: fileData.ui.length >= ExecutionTracker.data.ui.length
|
|
580
|
+
? fileData.ui
|
|
581
|
+
: ExecutionTracker.data.ui,
|
|
582
|
+
mobile: fileData.mobile.length >= ExecutionTracker.data.mobile.length
|
|
583
|
+
? fileData.mobile
|
|
584
|
+
: ExecutionTracker.data.mobile,
|
|
585
|
+
metadata: {
|
|
586
|
+
...ExecutionTracker.data.metadata,
|
|
587
|
+
...fileData.metadata,
|
|
588
|
+
// Preservar contadores mais altos
|
|
589
|
+
totalTests: Math.max(ExecutionTracker.data.metadata.totalTests, fileData.metadata.totalTests),
|
|
590
|
+
passedTests: Math.max(ExecutionTracker.data.metadata.passedTests, fileData.metadata.passedTests),
|
|
591
|
+
failedTests: Math.max(ExecutionTracker.data.metadata.failedTests, fileData.metadata.failedTests),
|
|
592
|
+
},
|
|
593
|
+
};
|
|
594
|
+
ExecutionTracker.data = mergedData;
|
|
595
|
+
ExecutionTracker.saveToFile(); // Salvar dados mesclados
|
|
596
|
+
return mergedData;
|
|
597
|
+
}
|
|
598
|
+
return fileData;
|
|
599
|
+
}
|
|
600
|
+
// ✅ IMPORTANTE: Sempre salvar antes de retornar
|
|
601
|
+
if (memoryTotal > 0) {
|
|
602
|
+
ExecutionTracker.saveToFile();
|
|
603
|
+
}
|
|
604
|
+
return ExecutionTracker.data;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* 🏁 Finalizar execução (PRESERVA TODOS OS DADOS)
|
|
608
|
+
*/
|
|
609
|
+
static finalize() {
|
|
610
|
+
// Preservar dados atuais antes de qualquer alteração
|
|
611
|
+
const currentData = { ...ExecutionTracker.data };
|
|
612
|
+
// Apenas atualizar metadados de finalização
|
|
613
|
+
ExecutionTracker.data.metadata.endTime = new Date().toISOString();
|
|
614
|
+
ExecutionTracker.data.metadata.duration =
|
|
615
|
+
new Date(ExecutionTracker.data.metadata.endTime).getTime() -
|
|
616
|
+
new Date(ExecutionTracker.data.metadata.startTime).getTime();
|
|
617
|
+
// ✅ SALVAR: Forçar salvamento com dados preservados
|
|
618
|
+
ExecutionTracker.saveToFile();
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* 🧹 Limpar dados (APENAS EM DESENVOLVIMENTO - NUNCA EM PRODUÇÃO)
|
|
622
|
+
*/
|
|
623
|
+
static reset() {
|
|
624
|
+
// ✅ PROTEÇÃO: Só permitir reset em desenvolvimento ou com confirmação explícita
|
|
625
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
626
|
+
const forceReset = process.env.FORCE_EXECUTION_TRACKER_RESET === 'true';
|
|
627
|
+
if (isProduction && !forceReset) {
|
|
628
|
+
console.warn('⚠️ ExecutionTracker.reset: Ignorado em produção. Use FORCE_EXECUTION_TRACKER_RESET=true se necessário');
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
console.log('⚠️ ExecutionTracker.reset: LIMPANDO TODOS OS DADOS - Esta ação é irreversível!');
|
|
632
|
+
// Backup antes de resetar
|
|
633
|
+
if (fs.existsSync(ExecutionTracker.dataFile)) {
|
|
634
|
+
const backupFile = ExecutionTracker.dataFile + '.reset-backup-' + Date.now();
|
|
635
|
+
try {
|
|
636
|
+
fs.copyFileSync(ExecutionTracker.dataFile, backupFile);
|
|
637
|
+
console.log(`💾 ExecutionTracker.reset: Backup criado em ${backupFile}`);
|
|
638
|
+
}
|
|
639
|
+
catch (error) {
|
|
640
|
+
console.warn(`⚠️ ExecutionTracker.reset: Falha ao criar backup: ${error}`);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
ExecutionTracker.data = {
|
|
644
|
+
apis: [],
|
|
645
|
+
ssh: [],
|
|
646
|
+
db: [],
|
|
647
|
+
ui: [],
|
|
648
|
+
mobile: [],
|
|
649
|
+
metadata: {
|
|
650
|
+
startTime: new Date().toISOString(),
|
|
651
|
+
endTime: '',
|
|
652
|
+
environment: process.env.NODE_ENV || 'development',
|
|
653
|
+
totalTests: 0,
|
|
654
|
+
passedTests: 0,
|
|
655
|
+
failedTests: 0,
|
|
656
|
+
framework: '@silasfmartins/testhub',
|
|
657
|
+
version: ExecutionTracker.getAutoCoreVersion(),
|
|
658
|
+
projectName: 'AutoCore Project',
|
|
659
|
+
projectType: 'Mixed',
|
|
660
|
+
duration: 0,
|
|
661
|
+
},
|
|
662
|
+
};
|
|
663
|
+
// Remover arquivo temporário
|
|
664
|
+
if (fs.existsSync(ExecutionTracker.dataFile)) {
|
|
665
|
+
fs.unlinkSync(ExecutionTracker.dataFile);
|
|
666
|
+
}
|
|
667
|
+
console.log('🧹 ExecutionTracker.reset: Reset concluído');
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* ⚙️ Configurar opções
|
|
671
|
+
*/
|
|
672
|
+
static configure(config) {
|
|
673
|
+
ExecutionTracker.config = { ...ExecutionTracker.config, ...config };
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* 📊 Obter configuração atual
|
|
677
|
+
*/
|
|
678
|
+
static getConfig() {
|
|
679
|
+
return ExecutionTracker.config;
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* 📈 Obter estatísticas rápidas
|
|
683
|
+
*/
|
|
684
|
+
static getStats() {
|
|
685
|
+
const data = ExecutionTracker.getData();
|
|
686
|
+
return {
|
|
687
|
+
totalActions: data.apis.length +
|
|
688
|
+
data.ssh.length +
|
|
689
|
+
data.db.length +
|
|
690
|
+
data.ui.length +
|
|
691
|
+
data.mobile.length,
|
|
692
|
+
categories: [
|
|
693
|
+
{ name: 'API', count: data.apis.length },
|
|
694
|
+
{ name: 'SSH', count: data.ssh.length },
|
|
695
|
+
{ name: 'Database', count: data.db.length },
|
|
696
|
+
{ name: 'UI', count: data.ui.length },
|
|
697
|
+
{ name: 'Mobile', count: data.mobile.length },
|
|
698
|
+
].filter((cat) => cat.count > 0),
|
|
699
|
+
duration: data.metadata.duration,
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
}
|