@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,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cliente SSH de baixo nĂvel para execução de comandos e leitura de saĂda.
|
|
3
|
+
*/
|
|
4
|
+
export declare class SSHClient {
|
|
5
|
+
private conn;
|
|
6
|
+
private output;
|
|
7
|
+
private isConnected;
|
|
8
|
+
private startTime;
|
|
9
|
+
/**
|
|
10
|
+
* Cria uma nova instância de SSHClient e adiciona ao pool de clientes ativos.
|
|
11
|
+
*/
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Conecta ao servidor SSH usando chave privada.
|
|
15
|
+
*
|
|
16
|
+
* 🆕 IMPORTANTE: HOST e USERNAME são obtidos automaticamente do AutoCore Hub
|
|
17
|
+
* quando vocĂŞ chama TestAnnotations.setSystem('SISTEMA').
|
|
18
|
+
* A CHAVE PRIVADA é passada pelo usuário (keyPath).
|
|
19
|
+
*
|
|
20
|
+
* O Hub injeta em process.env.SSH_HOST, SSH_USER, SSH_PASSWORD, SSH_PORT.
|
|
21
|
+
*
|
|
22
|
+
* @param keyPath Caminho para a chave privada (obrigatório - fornecido pelo usuário)
|
|
23
|
+
* @param options Opções opcionais para sobrescrever valores do Hub
|
|
24
|
+
* @returns this
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Uso simples - host/user vĂŞm do Hub, chave Ă© local
|
|
28
|
+
* await SSHActions.connectWithKey('secrets/minha_chave')
|
|
29
|
+
*
|
|
30
|
+
* // Uso avançado - sobrescrevendo valores do Hub
|
|
31
|
+
* await SSHClient.setPrivateKeyPath('secrets/chave', { host: 'outro-host.com' })
|
|
32
|
+
*/
|
|
33
|
+
setPrivateKeyPath(keyPath: string, options?: {
|
|
34
|
+
host?: string;
|
|
35
|
+
port?: number;
|
|
36
|
+
username?: string;
|
|
37
|
+
passphrase?: string;
|
|
38
|
+
}): Promise<this>;
|
|
39
|
+
/**
|
|
40
|
+
* 🆕 Conecta ao servidor SSH usando usuário e senha (sem chave privada).
|
|
41
|
+
* Útil para conexões automatizadas via AutoCore Hub.
|
|
42
|
+
*
|
|
43
|
+
* @param host Host do servidor SSH
|
|
44
|
+
* @param port Porta SSH (default: 22)
|
|
45
|
+
* @param username Usuário SSH
|
|
46
|
+
* @param password Senha SSH
|
|
47
|
+
* @returns this
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const client = new SSHClient()
|
|
51
|
+
* await client.connectWithPassword('servidor.com', 22, 'user', 'senha')
|
|
52
|
+
*/
|
|
53
|
+
connectWithPassword(host: string, port: number | undefined, username: string, password: string): Promise<this>;
|
|
54
|
+
/**
|
|
55
|
+
* Envia um comando SSH para o servidor remoto.
|
|
56
|
+
* @param command Comando SSH a ser enviado.
|
|
57
|
+
* @param description Descrição da ação.
|
|
58
|
+
* @returns this
|
|
59
|
+
*/
|
|
60
|
+
write(command: string, description?: string): Promise<this>;
|
|
61
|
+
/**
|
|
62
|
+
* LĂŞ a saĂda do log do servidor remoto.
|
|
63
|
+
* @param description Descrição da ação.
|
|
64
|
+
* @returns SaĂda do log como string.
|
|
65
|
+
*/
|
|
66
|
+
read(description?: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* LĂŞ a Ăşltima linha da saĂda do log.
|
|
69
|
+
* @param description Descrição da ação.
|
|
70
|
+
* @returns Ăšltima linha da saĂda.
|
|
71
|
+
*/
|
|
72
|
+
readLast(description?: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Limpa o buffer de saĂda.
|
|
75
|
+
*/
|
|
76
|
+
clearOutput(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Verifica se a conexão SSH está ativa.
|
|
79
|
+
* @returns true se conectado, false caso contrário.
|
|
80
|
+
*/
|
|
81
|
+
isSSHConnected(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Desconecta do servidor SSH.
|
|
84
|
+
*/
|
|
85
|
+
disconnect(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Executa um comando e retorna a saĂda.
|
|
88
|
+
* @param command Comando SSH a ser enviado.
|
|
89
|
+
* @param description Descrição da ação.
|
|
90
|
+
* @returns SaĂda do comando.
|
|
91
|
+
*/
|
|
92
|
+
executeAndRead(command: string, description?: string): Promise<string>;
|
|
93
|
+
/**
|
|
94
|
+
* Desconecta todos os SSHClient ativos (usado no teardown global).
|
|
95
|
+
*/
|
|
96
|
+
static disconnectAll(): Promise<void>;
|
|
97
|
+
/** Pool de clientes ativos para teardown global */
|
|
98
|
+
private static activeSSHClients;
|
|
99
|
+
}
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { Client } from 'ssh2';
|
|
5
|
+
import { ExecutionTracker } from '../hubdocs/ExecutionTracker.js';
|
|
6
|
+
import { StatementTracker } from '../hubdocs/StatementTracker.js';
|
|
7
|
+
import { TestContext } from '../testContext/TestContext.js';
|
|
8
|
+
import { Logger } from '../utils/Logger.js';
|
|
9
|
+
import { SSHActions } from './SSHActions.js';
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
/**
|
|
12
|
+
* Cliente SSH de baixo nĂvel para execução de comandos e leitura de saĂda.
|
|
13
|
+
*/
|
|
14
|
+
export class SSHClient {
|
|
15
|
+
conn = new Client();
|
|
16
|
+
output = '';
|
|
17
|
+
isConnected = false;
|
|
18
|
+
startTime = 0;
|
|
19
|
+
/**
|
|
20
|
+
* Cria uma nova instância de SSHClient e adiciona ao pool de clientes ativos.
|
|
21
|
+
*/
|
|
22
|
+
constructor() {
|
|
23
|
+
SSHClient.activeSSHClients.push(this);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Conecta ao servidor SSH usando chave privada.
|
|
27
|
+
*
|
|
28
|
+
* 🆕 IMPORTANTE: HOST e USERNAME são obtidos automaticamente do AutoCore Hub
|
|
29
|
+
* quando vocĂŞ chama TestAnnotations.setSystem('SISTEMA').
|
|
30
|
+
* A CHAVE PRIVADA é passada pelo usuário (keyPath).
|
|
31
|
+
*
|
|
32
|
+
* O Hub injeta em process.env.SSH_HOST, SSH_USER, SSH_PASSWORD, SSH_PORT.
|
|
33
|
+
*
|
|
34
|
+
* @param keyPath Caminho para a chave privada (obrigatório - fornecido pelo usuário)
|
|
35
|
+
* @param options Opções opcionais para sobrescrever valores do Hub
|
|
36
|
+
* @returns this
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Uso simples - host/user vĂŞm do Hub, chave Ă© local
|
|
40
|
+
* await SSHActions.connectWithKey('secrets/minha_chave')
|
|
41
|
+
*
|
|
42
|
+
* // Uso avançado - sobrescrevendo valores do Hub
|
|
43
|
+
* await SSHClient.setPrivateKeyPath('secrets/chave', { host: 'outro-host.com' })
|
|
44
|
+
*/
|
|
45
|
+
async setPrivateKeyPath(keyPath, options) {
|
|
46
|
+
const privateKey = fs.readFileSync(path.resolve(keyPath), 'utf-8');
|
|
47
|
+
// 🆕 Credenciais do Hub (injetadas via setSystem → injectIntoEnvironment)
|
|
48
|
+
// O usuário pode sobrescrever via options se necessário
|
|
49
|
+
const host = options?.host || process.env.SSH_HOST;
|
|
50
|
+
const port = options?.port || Number.parseInt(process.env.SSH_PORT || '22', 10);
|
|
51
|
+
const username = options?.username || process.env.SSH_USER;
|
|
52
|
+
const passphrase = options?.passphrase || process.env.SSH_PASSPHRASE || process.env.SSH_PASSWORD || '';
|
|
53
|
+
// Validar credenciais obrigatĂłrias
|
|
54
|
+
if (!host || host === 'nĂŁo definido') {
|
|
55
|
+
throw new Error(`
|
|
56
|
+
❌ SSH_HOST não configurado!
|
|
57
|
+
|
|
58
|
+
Certifique-se de:
|
|
59
|
+
1. Chamar TestAnnotations.setSystem('NOME_DO_SISTEMA') antes de conectar
|
|
60
|
+
2. O sistema ter o campo 'url' (host SSH) configurado no Hub
|
|
61
|
+
3. Ou passar o host manualmente: setPrivateKeyPath('chave', { host: 'seu-host.com' })
|
|
62
|
+
|
|
63
|
+
Valor atual de SSH_HOST: ${process.env.SSH_HOST || '(nĂŁo definido)'}
|
|
64
|
+
`);
|
|
65
|
+
}
|
|
66
|
+
if (!username || username === 'nĂŁo definido') {
|
|
67
|
+
throw new Error(`
|
|
68
|
+
❌ SSH_USER não configurado!
|
|
69
|
+
|
|
70
|
+
Certifique-se de:
|
|
71
|
+
1. Chamar TestAnnotations.setSystem('NOME_DO_SISTEMA') antes de conectar
|
|
72
|
+
2. O sistema ter o campo 'username' configurado no Hub
|
|
73
|
+
3. Ou passar o username manualmente: setPrivateKeyPath('chave', { username: 'seu-user' })
|
|
74
|
+
|
|
75
|
+
Valor atual de SSH_USER: ${process.env.SSH_USER || '(nĂŁo definido)'}
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
Logger.bloco('Iniciando conexĂŁo SSH com chave privada');
|
|
79
|
+
Logger.info(`Host: ${host} (do Hub)`);
|
|
80
|
+
Logger.info(`Porta: ${port}`);
|
|
81
|
+
Logger.info(`Usuário: ${username} (do Hub)`);
|
|
82
|
+
Logger.info(`Chave: ${keyPath} (local)`);
|
|
83
|
+
Logger.info(`Passphrase: ${passphrase ? '********' : 'nĂŁo definida'}`);
|
|
84
|
+
SSHActions.adicionarLog(`Iniciando conexĂŁo SSH em ${host}:${port}`, 'info');
|
|
85
|
+
SSHActions.registrarInicioExecucao();
|
|
86
|
+
Logger.debug && Logger.debug('SSHClient: iniciando conexĂŁo (setPrivateKeyPath)');
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
this.conn
|
|
89
|
+
.on('ready', () => {
|
|
90
|
+
this.isConnected = true;
|
|
91
|
+
Logger.success(`ConexĂŁo SSH estabelecida com sucesso em ${host}:${port}`);
|
|
92
|
+
Logger.debug && Logger.debug('SSHClient: evento ready recebido');
|
|
93
|
+
SSHActions.adicionarLog(`ConexĂŁo SSH estabelecida: ${host}:${port}`, 'success');
|
|
94
|
+
resolve(this);
|
|
95
|
+
})
|
|
96
|
+
.on('error', (err) => {
|
|
97
|
+
Logger.error(`Erro ao conectar no SSH (${host}:${port})`, err);
|
|
98
|
+
Logger.debug && Logger.debug(`SSHClient: erro de conexĂŁo: ${err.stack || err}`);
|
|
99
|
+
SSHActions.adicionarLog(`Erro na conexĂŁo SSH: ${err.message}`, 'error');
|
|
100
|
+
reject(err);
|
|
101
|
+
})
|
|
102
|
+
.connect({
|
|
103
|
+
host,
|
|
104
|
+
port,
|
|
105
|
+
username,
|
|
106
|
+
privateKey,
|
|
107
|
+
passphrase: passphrase || undefined,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 🆕 Conecta ao servidor SSH usando usuário e senha (sem chave privada).
|
|
113
|
+
* Útil para conexões automatizadas via AutoCore Hub.
|
|
114
|
+
*
|
|
115
|
+
* @param host Host do servidor SSH
|
|
116
|
+
* @param port Porta SSH (default: 22)
|
|
117
|
+
* @param username Usuário SSH
|
|
118
|
+
* @param password Senha SSH
|
|
119
|
+
* @returns this
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* const client = new SSHClient()
|
|
123
|
+
* await client.connectWithPassword('servidor.com', 22, 'user', 'senha')
|
|
124
|
+
*/
|
|
125
|
+
async connectWithPassword(host, port = 22, username, password) {
|
|
126
|
+
Logger.bloco('Iniciando conexĂŁo SSH com senha');
|
|
127
|
+
Logger.info(`Host: ${host}`);
|
|
128
|
+
Logger.info(`Porta: ${port}`);
|
|
129
|
+
Logger.info(`Usuário: ${username}`);
|
|
130
|
+
Logger.info(`Senha: ********`);
|
|
131
|
+
SSHActions.adicionarLog(`Iniciando conexĂŁo SSH em ${host}:${port}`, 'info');
|
|
132
|
+
SSHActions.registrarInicioExecucao();
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
this.conn
|
|
135
|
+
.on('ready', () => {
|
|
136
|
+
this.isConnected = true;
|
|
137
|
+
Logger.success(`ConexĂŁo SSH estabelecida com sucesso em ${host}:${port}`);
|
|
138
|
+
SSHActions.adicionarLog(`ConexĂŁo SSH estabelecida: ${host}:${port}`, 'success');
|
|
139
|
+
resolve(this);
|
|
140
|
+
})
|
|
141
|
+
.on('error', (err) => {
|
|
142
|
+
Logger.error(`Erro ao conectar no SSH (${host}:${port})`, err);
|
|
143
|
+
SSHActions.adicionarLog(`Erro na conexĂŁo SSH: ${err.message}`, 'error');
|
|
144
|
+
reject(err);
|
|
145
|
+
})
|
|
146
|
+
.connect({
|
|
147
|
+
host,
|
|
148
|
+
port,
|
|
149
|
+
username,
|
|
150
|
+
password,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Envia um comando SSH para o servidor remoto.
|
|
156
|
+
* @param command Comando SSH a ser enviado.
|
|
157
|
+
* @param description Descrição da ação.
|
|
158
|
+
* @returns this
|
|
159
|
+
*/
|
|
160
|
+
async write(command, description = '') {
|
|
161
|
+
return new Promise(async (resolve, reject) => {
|
|
162
|
+
if (!this.isConnected) {
|
|
163
|
+
const msg = 'Tentativa de escrever sem conexĂŁo SSH ativa.';
|
|
164
|
+
Logger.error(msg);
|
|
165
|
+
SSHActions.adicionarLog(`Erro: ${msg}`, 'error');
|
|
166
|
+
return reject(msg);
|
|
167
|
+
}
|
|
168
|
+
// 🆕 Registrar inĂcio da execução SSH
|
|
169
|
+
SSHActions.registrarInicioExecucao();
|
|
170
|
+
// 🆕 Registrar statement no StatementTracker
|
|
171
|
+
let statementTimestamp = null;
|
|
172
|
+
try {
|
|
173
|
+
statementTimestamp = StatementTracker.startStatement('SSHClient', `write: ${description || command}`);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
Logger.warning(`NĂŁo foi possĂvel registrar statement no StatementTracker: ${error}`);
|
|
177
|
+
}
|
|
178
|
+
this.startTime = Date.now();
|
|
179
|
+
const commandTimestamp = new Date().toISOString();
|
|
180
|
+
// 🆕 Registrar comando SSH no ExecutionTracker para AutoDocs
|
|
181
|
+
const sshCommand = {
|
|
182
|
+
command,
|
|
183
|
+
output: '',
|
|
184
|
+
host: process.env.SSH_HOST || 'unknown',
|
|
185
|
+
user: process.env.SSH_USER || 'unknown',
|
|
186
|
+
timestamp: commandTimestamp,
|
|
187
|
+
testName: TestContext.getSafeTestInfo()?.title || description || 'SSH Command',
|
|
188
|
+
duration: 0,
|
|
189
|
+
exitCode: undefined,
|
|
190
|
+
};
|
|
191
|
+
this.conn.exec(command, (err, stream) => {
|
|
192
|
+
if (err) {
|
|
193
|
+
Logger.error(`Erro ao executar comando: ${command}`, err);
|
|
194
|
+
SSHActions.logEvent(`❌ ${description} → ${command}: ${err.message}`);
|
|
195
|
+
// 🆕 Atualizar ExecutionTracker com erro
|
|
196
|
+
sshCommand.duration = Date.now() - this.startTime;
|
|
197
|
+
sshCommand.output = `ERROR: ${err.message}`;
|
|
198
|
+
sshCommand.exitCode = 1;
|
|
199
|
+
ExecutionTracker.trackSSH(sshCommand);
|
|
200
|
+
// 🆕 Finalizar statement com erro
|
|
201
|
+
if (statementTimestamp) {
|
|
202
|
+
import('../hubdocs/StatementTracker.js')
|
|
203
|
+
.then(({ StatementTracker }) => {
|
|
204
|
+
StatementTracker.finishStatement(statementTimestamp, false, `❌ ${description}: ${err.message}`);
|
|
205
|
+
})
|
|
206
|
+
.catch((error) => {
|
|
207
|
+
Logger.warning(`NĂŁo foi possĂvel finalizar statement no StatementTracker: ${error}`);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return reject(err);
|
|
211
|
+
}
|
|
212
|
+
Logger.info(`Executando: ${description} → ${command}`);
|
|
213
|
+
SSHActions.logEvent(`🔹 ${description} → ${command}`);
|
|
214
|
+
stream
|
|
215
|
+
.on('close', (code) => {
|
|
216
|
+
const duracao = Date.now() - this.startTime;
|
|
217
|
+
SSHActions.registrarDuracaoDoTeste(description, duracao);
|
|
218
|
+
Logger.success(`Comando finalizado: ${description}`);
|
|
219
|
+
SSHActions.adicionarLog(`Comando finalizado: ${description} (${duracao}ms)`, 'success');
|
|
220
|
+
// 🆕 Atualizar ExecutionTracker com sucesso
|
|
221
|
+
sshCommand.duration = duracao;
|
|
222
|
+
sshCommand.output = this.output;
|
|
223
|
+
sshCommand.exitCode = code;
|
|
224
|
+
ExecutionTracker.trackSSH(sshCommand);
|
|
225
|
+
// 🚀 CRÍTICO: Registrar ação automaticamente no StatementTracker como o API faz
|
|
226
|
+
import('../hubdocs/StatementTracker.js')
|
|
227
|
+
.then(({ StatementTracker }) => {
|
|
228
|
+
StatementTracker.recordAction('SSH', `${description || command}`, code === 0, duracao, {
|
|
229
|
+
command,
|
|
230
|
+
action: `SSH: ${description || command}`,
|
|
231
|
+
});
|
|
232
|
+
})
|
|
233
|
+
.catch((error) => {
|
|
234
|
+
Logger.error('NĂŁo foi possĂvel registrar ação SSH no StatementTracker:', error);
|
|
235
|
+
});
|
|
236
|
+
// 🆕 Atualizar resultado SSH com base no exitCode
|
|
237
|
+
const success = code === 0;
|
|
238
|
+
ExecutionTracker.updateSSHResult(command, commandTimestamp, success, duracao, code, success ? undefined : `Exit code: ${code}`);
|
|
239
|
+
// 🆕 Finalizar statement no StatementTracker
|
|
240
|
+
if (statementTimestamp) {
|
|
241
|
+
import('../hubdocs/StatementTracker.js')
|
|
242
|
+
.then(({ StatementTracker }) => {
|
|
243
|
+
const statusMessage = success
|
|
244
|
+
? `âś… ${description}: Comando executado com sucesso (${duracao}ms)`
|
|
245
|
+
: `❌ ${description}: Comando falhou com exit code ${code}`;
|
|
246
|
+
StatementTracker.finishStatement(statementTimestamp, success, statusMessage);
|
|
247
|
+
})
|
|
248
|
+
.catch((error) => {
|
|
249
|
+
Logger.warning(`NĂŁo foi possĂvel finalizar statement no StatementTracker: ${error}`);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
resolve(this);
|
|
253
|
+
})
|
|
254
|
+
.on('data', (data) => {
|
|
255
|
+
const text = data.toString();
|
|
256
|
+
this.output += `\n[${description}] ${text}`;
|
|
257
|
+
sshCommand.output += text;
|
|
258
|
+
SSHActions.adicionarLog(`SaĂda recebida de "${description}": ${text.trim()}`, 'info');
|
|
259
|
+
})
|
|
260
|
+
.stderr.on('data', (data) => {
|
|
261
|
+
const errorText = data.toString();
|
|
262
|
+
this.output += `\n[${description} - STDERR] ${errorText}`;
|
|
263
|
+
sshCommand.output += `\nSTDERR: ${errorText}`;
|
|
264
|
+
Logger.warning(`STDERR: ${errorText.trim()}`);
|
|
265
|
+
SSHActions.adicionarLog(`STDERR de "${description}": ${errorText.trim()}`, 'warning');
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* LĂŞ a saĂda do log do servidor remoto.
|
|
272
|
+
* @param description Descrição da ação.
|
|
273
|
+
* @returns SaĂda do log como string.
|
|
274
|
+
*/
|
|
275
|
+
read(description = '') {
|
|
276
|
+
// 🆕 Registrar statement no StatementTracker
|
|
277
|
+
let statementTimestamp = null;
|
|
278
|
+
try {
|
|
279
|
+
const { StatementTracker } = require('../hubdocs/StatementTracker.js');
|
|
280
|
+
statementTimestamp = StatementTracker.startStatement('SSHClient', `read: ${description}`);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
Logger.warning(`NĂŁo foi possĂvel registrar statement no StatementTracker: ${error}`);
|
|
284
|
+
}
|
|
285
|
+
if (this.output) {
|
|
286
|
+
Logger.info(`[${description}] SaĂda capturada com sucesso.`);
|
|
287
|
+
SSHActions.adicionarLog(`SaĂda capturada com sucesso: ${description}`, 'success');
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
Logger.warning(`[${description}] Nenhuma saĂda foi capturada atĂ© o momento.`);
|
|
291
|
+
SSHActions.adicionarLog(`Nenhuma saĂda capturada para: ${description}`, 'warning');
|
|
292
|
+
}
|
|
293
|
+
SSHActions.logEvent(`📤 ${description} → ${this.output.trim()}`);
|
|
294
|
+
SSHActions.registrarFimExecucao();
|
|
295
|
+
// 🆕 Registrar operação de leitura SSH no ExecutionTracker
|
|
296
|
+
// ✅ CORRIGIDO: read() sempre é sucesso se não lança exceção
|
|
297
|
+
const sshReadCommand = {
|
|
298
|
+
command: `read: ${description}`,
|
|
299
|
+
output: this.output,
|
|
300
|
+
host: process.env.SSH_HOST || 'unknown',
|
|
301
|
+
user: process.env.SSH_USER || 'unknown',
|
|
302
|
+
timestamp: new Date().toISOString(),
|
|
303
|
+
testName: TestContext.getSafeTestInfo()?.title || description || 'SSH Read',
|
|
304
|
+
duration: 0,
|
|
305
|
+
exitCode: 0, // ✅ Sempre 0 - read() sempre é sucesso se chegou até aqui
|
|
306
|
+
};
|
|
307
|
+
ExecutionTracker.trackSSH(sshReadCommand);
|
|
308
|
+
// 🆕 Finalizar statement
|
|
309
|
+
if (statementTimestamp) {
|
|
310
|
+
try {
|
|
311
|
+
const { StatementTracker } = require('../hubdocs/StatementTracker.js');
|
|
312
|
+
const success = this.output ? true : false;
|
|
313
|
+
const message = success
|
|
314
|
+
? `âś… ${description}: SaĂda capturada com sucesso`
|
|
315
|
+
: `⚠️ ${description}: Nenhuma saĂda capturada`;
|
|
316
|
+
StatementTracker.finishStatement(statementTimestamp, success, message);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
Logger.warning(`NĂŁo foi possĂvel finalizar statement no StatementTracker: ${error}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return this.output;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* LĂŞ a Ăşltima linha da saĂda do log.
|
|
326
|
+
* @param description Descrição da ação.
|
|
327
|
+
* @returns Ăšltima linha da saĂda.
|
|
328
|
+
*/
|
|
329
|
+
readLast(description = '') {
|
|
330
|
+
const lines = this.output.split('\n');
|
|
331
|
+
const lastOutput = lines[lines.length - 1] || '';
|
|
332
|
+
Logger.info(`[${description}] Ăšltima saĂda capturada: ${lastOutput.trim()}`);
|
|
333
|
+
SSHActions.adicionarLog(`Ăšltima saĂda: ${description} → ${lastOutput.trim()}`, 'info');
|
|
334
|
+
return lastOutput;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Limpa o buffer de saĂda.
|
|
338
|
+
*/
|
|
339
|
+
clearOutput() {
|
|
340
|
+
this.output = '';
|
|
341
|
+
Logger.info('Buffer de saĂda SSH limpo');
|
|
342
|
+
SSHActions.adicionarLog('Buffer de saĂda limpo', 'info');
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Verifica se a conexão SSH está ativa.
|
|
346
|
+
* @returns true se conectado, false caso contrário.
|
|
347
|
+
*/
|
|
348
|
+
isSSHConnected() {
|
|
349
|
+
return this.isConnected;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Desconecta do servidor SSH.
|
|
353
|
+
*/
|
|
354
|
+
async disconnect() {
|
|
355
|
+
if (this.isConnected) {
|
|
356
|
+
this.conn.end();
|
|
357
|
+
this.isConnected = false;
|
|
358
|
+
Logger.info('ConexĂŁo SSH encerrada');
|
|
359
|
+
SSHActions.adicionarLog('ConexĂŁo SSH encerrada', 'info');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Executa um comando e retorna a saĂda.
|
|
364
|
+
* @param command Comando SSH a ser enviado.
|
|
365
|
+
* @param description Descrição da ação.
|
|
366
|
+
* @returns SaĂda do comando.
|
|
367
|
+
*/
|
|
368
|
+
async executeAndRead(command, description = '') {
|
|
369
|
+
const startTime = Date.now();
|
|
370
|
+
const commandTimestamp = new Date().toISOString();
|
|
371
|
+
await this.write(command, description);
|
|
372
|
+
const output = this.read(description);
|
|
373
|
+
const duration = Date.now() - startTime;
|
|
374
|
+
// 🆕 Registrar comando completo SSH no ExecutionTracker
|
|
375
|
+
const sshCompleteCommand = {
|
|
376
|
+
command: `execute: ${command}`,
|
|
377
|
+
output,
|
|
378
|
+
host: process.env.SSH_HOST || 'unknown',
|
|
379
|
+
user: process.env.SSH_USER || 'unknown',
|
|
380
|
+
timestamp: commandTimestamp,
|
|
381
|
+
testName: TestContext.getSafeTestInfo()?.title ||
|
|
382
|
+
description ||
|
|
383
|
+
'SSH Execute+Read',
|
|
384
|
+
duration,
|
|
385
|
+
exitCode: 0,
|
|
386
|
+
};
|
|
387
|
+
ExecutionTracker.trackSSH(sshCompleteCommand);
|
|
388
|
+
// 🆕 Atualizar resultado SSH - assumindo sucesso se não houve exceção
|
|
389
|
+
ExecutionTracker.updateSSHResult(`execute: ${command}`, commandTimestamp, true, // sucesso se chegou até aqui
|
|
390
|
+
duration, 0);
|
|
391
|
+
return output;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Desconecta todos os SSHClient ativos (usado no teardown global).
|
|
395
|
+
*/
|
|
396
|
+
static async disconnectAll() {
|
|
397
|
+
for (const client of SSHClient.activeSSHClients) {
|
|
398
|
+
try {
|
|
399
|
+
await client.disconnect();
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
// Ignorar erros individuais
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
SSHClient.activeSSHClients.length = 0;
|
|
406
|
+
}
|
|
407
|
+
/** Pool de clientes ativos para teardown global */
|
|
408
|
+
static activeSSHClients = [];
|
|
409
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🎯 Classe base para Statements - Interface de tracking
|
|
3
|
+
*/
|
|
4
|
+
export declare abstract class Track {
|
|
5
|
+
/**
|
|
6
|
+
* âś… Nome do CT sendo executado
|
|
7
|
+
*/
|
|
8
|
+
ctName: string;
|
|
9
|
+
/**
|
|
10
|
+
* ✅ Dados de execução
|
|
11
|
+
*/
|
|
12
|
+
executionData: any;
|
|
13
|
+
/**
|
|
14
|
+
* ✅ Status da execução
|
|
15
|
+
*/
|
|
16
|
+
status: 'pending' | 'running' | 'completed' | 'error';
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* 🔧 Método abstrato para execução do CT
|
|
20
|
+
*/
|
|
21
|
+
abstract execute(...args: any[]): Promise<any> | any;
|
|
22
|
+
/**
|
|
23
|
+
* 📊 Registrar dados de execução
|
|
24
|
+
*/
|
|
25
|
+
track(data: any): void;
|
|
26
|
+
/**
|
|
27
|
+
* âś… Marcar como completado
|
|
28
|
+
*/
|
|
29
|
+
complete(result?: any): void;
|
|
30
|
+
/**
|
|
31
|
+
* ❌ Marcar como erro
|
|
32
|
+
*/
|
|
33
|
+
error(error: any): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 🎯 Decorator para métodos Statement
|
|
37
|
+
*/
|
|
38
|
+
export declare function statement(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Logger } from '../utils/Logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* 🎯 Classe base para Statements - Interface de tracking
|
|
4
|
+
*/
|
|
5
|
+
export class Track {
|
|
6
|
+
/**
|
|
7
|
+
* âś… Nome do CT sendo executado
|
|
8
|
+
*/
|
|
9
|
+
ctName = '';
|
|
10
|
+
/**
|
|
11
|
+
* ✅ Dados de execução
|
|
12
|
+
*/
|
|
13
|
+
executionData = {};
|
|
14
|
+
/**
|
|
15
|
+
* ✅ Status da execução
|
|
16
|
+
*/
|
|
17
|
+
status = 'pending';
|
|
18
|
+
constructor() {
|
|
19
|
+
// Garantir que o tracking está ativo
|
|
20
|
+
this.ctName = this.constructor.name;
|
|
21
|
+
Logger.info(`🎯 [Track] Statement criado: ${this.ctName}`);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 📊 Registrar dados de execução
|
|
25
|
+
*/
|
|
26
|
+
track(data) {
|
|
27
|
+
this.executionData = { ...this.executionData, ...data };
|
|
28
|
+
Logger.info(`📊 [Track] Dados registrados para ${this.ctName}: ${JSON.stringify(data)}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* âś… Marcar como completado
|
|
32
|
+
*/
|
|
33
|
+
complete(result) {
|
|
34
|
+
this.status = 'completed';
|
|
35
|
+
if (result !== undefined) {
|
|
36
|
+
this.executionData.result = result;
|
|
37
|
+
}
|
|
38
|
+
Logger.success(`âś… [Track] ${this.ctName} completado`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* ❌ Marcar como erro
|
|
42
|
+
*/
|
|
43
|
+
error(error) {
|
|
44
|
+
this.status = 'error';
|
|
45
|
+
this.executionData.error = error;
|
|
46
|
+
Logger.error(`❌ [Track] ${this.ctName} com erro`, error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 🎯 Decorator para métodos Statement
|
|
51
|
+
*/
|
|
52
|
+
export function statement(target, propertyKey, descriptor) {
|
|
53
|
+
const originalMethod = descriptor.value;
|
|
54
|
+
descriptor.value = function (...args) {
|
|
55
|
+
Logger.info(`🚀 [Statement] Executando método: ${propertyKey}`);
|
|
56
|
+
try {
|
|
57
|
+
const result = originalMethod.apply(this, args);
|
|
58
|
+
if (result instanceof Promise) {
|
|
59
|
+
return result
|
|
60
|
+
.then((res) => {
|
|
61
|
+
Logger.success(`✅ [Statement] Método ${propertyKey} completado`);
|
|
62
|
+
return res;
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
Logger.error(`❌ [Statement] Método ${propertyKey} com erro`, error);
|
|
66
|
+
throw error;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
Logger.success(`✅ [Statement] Método ${propertyKey} completado`);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
Logger.error(`❌ [Statement] Método ${propertyKey} com erro`, error);
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
return descriptor;
|
|
78
|
+
}
|