@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,741 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔧 Sistema de Interceptação para Captura Automática de Evidências
|
|
3
|
+
* @description Intercepta ações do WebActions, MobileActions e ApiActions para capturar evidências
|
|
4
|
+
* @author TestHUB Team
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { TestContext } from "../testContext/TestContext.js";
|
|
8
|
+
import { EvidenceCapture } from "./EvidenceCapture.js";
|
|
9
|
+
import { createFrameHelper } from "./FrameManagementUtil.js";
|
|
10
|
+
import { Logger } from "./Logger.js";
|
|
11
|
+
import { analyzeFailure, markSuccess, reportResult, getRecoveryMetadata, } from "./testRecovery/TestRecoveryClient.js";
|
|
12
|
+
export class ActionInterceptor {
|
|
13
|
+
static isInitialized = false;
|
|
14
|
+
static interceptedMethods = new Set();
|
|
15
|
+
/**
|
|
16
|
+
* ✅ Inicializa os interceptadores
|
|
17
|
+
*/
|
|
18
|
+
static initialize() {
|
|
19
|
+
if (ActionInterceptor.isInitialized)
|
|
20
|
+
return;
|
|
21
|
+
ActionInterceptor.isInitialized = true;
|
|
22
|
+
// Aguardar um pouco para garantir que os módulos foram carregados
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
ActionInterceptor.interceptWebActions();
|
|
25
|
+
ActionInterceptor.interceptMobileActions();
|
|
26
|
+
ActionInterceptor.interceptApiActions();
|
|
27
|
+
ActionInterceptor.interceptDesktopActions();
|
|
28
|
+
}, 100);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* ✅ Intercepta WebActions
|
|
32
|
+
*/
|
|
33
|
+
static interceptWebActions() {
|
|
34
|
+
try {
|
|
35
|
+
// Importação dinâmica para evitar dependência circular
|
|
36
|
+
import("../playwright/WebActions.js")
|
|
37
|
+
.then(({ WebActions }) => {
|
|
38
|
+
const methodsToIntercept = [
|
|
39
|
+
"click",
|
|
40
|
+
"switchTo",
|
|
41
|
+
"fill",
|
|
42
|
+
"type",
|
|
43
|
+
"press",
|
|
44
|
+
"selectOption",
|
|
45
|
+
"check",
|
|
46
|
+
"uncheck",
|
|
47
|
+
"hover",
|
|
48
|
+
"dragAndDrop",
|
|
49
|
+
"navigate",
|
|
50
|
+
"waitForElement",
|
|
51
|
+
"waitForText",
|
|
52
|
+
];
|
|
53
|
+
methodsToIntercept.forEach((methodName) => {
|
|
54
|
+
ActionInterceptor.interceptMethod(WebActions, methodName, "Web");
|
|
55
|
+
});
|
|
56
|
+
})
|
|
57
|
+
.catch(() => {
|
|
58
|
+
// Ignorar se não conseguir importar
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
// Ignorar erros de interceptação
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* ✅ Intercepta DesktopActions
|
|
67
|
+
*/
|
|
68
|
+
static interceptDesktopActions() {
|
|
69
|
+
try {
|
|
70
|
+
import("../desktop/DesktopActions.js")
|
|
71
|
+
.then(({ DesktopActions }) => {
|
|
72
|
+
const methodsToIntercept = [
|
|
73
|
+
"click",
|
|
74
|
+
"setText",
|
|
75
|
+
"doubleClick",
|
|
76
|
+
"selectInTableActiveRow",
|
|
77
|
+
"clickOptionInTable",
|
|
78
|
+
"clickOptionInTableRowAndHeader",
|
|
79
|
+
"doubleClickOptionInTable",
|
|
80
|
+
"selectRowInTable",
|
|
81
|
+
"selectRowOptionInTable",
|
|
82
|
+
"selectInTreeView",
|
|
83
|
+
"selectInTabControl",
|
|
84
|
+
"setValueTable",
|
|
85
|
+
"setStateCheckBox",
|
|
86
|
+
"implicitWait",
|
|
87
|
+
"selectInList",
|
|
88
|
+
"validateObject",
|
|
89
|
+
"getText",
|
|
90
|
+
"getLabel",
|
|
91
|
+
"closeWindow",
|
|
92
|
+
"maximizeWindow",
|
|
93
|
+
"pressKey",
|
|
94
|
+
"releaseKey",
|
|
95
|
+
"waitForElementJavaToDisappear",
|
|
96
|
+
];
|
|
97
|
+
methodsToIntercept.forEach((methodName) => {
|
|
98
|
+
ActionInterceptor.interceptMethod(DesktopActions, methodName, "Web");
|
|
99
|
+
});
|
|
100
|
+
})
|
|
101
|
+
.catch(() => {
|
|
102
|
+
// Ignorar se não conseguir importar
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// Ignorar erros de interceptação
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* ✅ Intercepta MobileActions
|
|
111
|
+
*/
|
|
112
|
+
static interceptMobileActions() {
|
|
113
|
+
try {
|
|
114
|
+
import("../appium/MobileActions.js")
|
|
115
|
+
.then(({ MobileActions }) => {
|
|
116
|
+
const methodsToIntercept = [
|
|
117
|
+
"click",
|
|
118
|
+
"setText",
|
|
119
|
+
"tap",
|
|
120
|
+
"swipe",
|
|
121
|
+
"scroll",
|
|
122
|
+
"waitForElement",
|
|
123
|
+
"longPress",
|
|
124
|
+
"doubleClick",
|
|
125
|
+
"dragAndDrop",
|
|
126
|
+
"hideKeyboard",
|
|
127
|
+
"swipeLeft",
|
|
128
|
+
"swipeRight",
|
|
129
|
+
"swipeUp",
|
|
130
|
+
"swipeDown",
|
|
131
|
+
"pinch",
|
|
132
|
+
"zoom",
|
|
133
|
+
];
|
|
134
|
+
methodsToIntercept.forEach((methodName) => {
|
|
135
|
+
ActionInterceptor.interceptMethod(MobileActions, methodName, "Mobile");
|
|
136
|
+
});
|
|
137
|
+
})
|
|
138
|
+
.catch(() => {
|
|
139
|
+
// Ignorar se não conseguir importar
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
// Ignorar erros de interceptação
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 🚫 Intercepta ApiActions - DESABILITADO
|
|
148
|
+
* Métodos do ApiActions são internos e não devem ser capturados como CTs
|
|
149
|
+
*/
|
|
150
|
+
static interceptApiActions() {
|
|
151
|
+
// 🚫 DESABILITADO: ApiActions são métodos internos que não devem ser capturados como CTs
|
|
152
|
+
return;
|
|
153
|
+
/* CÓDIGO ORIGINAL DESABILITADO
|
|
154
|
+
try {
|
|
155
|
+
import('../api/ApiActions.js').then(({ ApiActions }) => {
|
|
156
|
+
const methodsToIntercept = [
|
|
157
|
+
'get',
|
|
158
|
+
'post',
|
|
159
|
+
'put',
|
|
160
|
+
'delete',
|
|
161
|
+
'patch',
|
|
162
|
+
'request'
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
methodsToIntercept.forEach(methodName => {
|
|
166
|
+
ActionInterceptor.interceptMethod(ApiActions, methodName, 'API')
|
|
167
|
+
})
|
|
168
|
+
}).catch(() => {
|
|
169
|
+
// Ignorar se não conseguir importar
|
|
170
|
+
})
|
|
171
|
+
} catch (error) {
|
|
172
|
+
// Ignorar erros de interceptação
|
|
173
|
+
}
|
|
174
|
+
*/
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* ✅ Intercepta um método específico
|
|
178
|
+
*/
|
|
179
|
+
static interceptMethod(targetClass, methodName, actionType) {
|
|
180
|
+
const key = `${targetClass.name}.${methodName}`;
|
|
181
|
+
if (ActionInterceptor.interceptedMethods.has(key))
|
|
182
|
+
return;
|
|
183
|
+
const originalMethod = targetClass[methodName];
|
|
184
|
+
if (!originalMethod || typeof originalMethod !== "function")
|
|
185
|
+
return;
|
|
186
|
+
targetClass[methodName] = async function (...args) {
|
|
187
|
+
let testName = "Unknown Test";
|
|
188
|
+
let description = "";
|
|
189
|
+
try {
|
|
190
|
+
// Obter nome do teste atual
|
|
191
|
+
const testInfo = TestContext.getSafeTestInfo();
|
|
192
|
+
if (testInfo?.title) {
|
|
193
|
+
testName = testInfo.title;
|
|
194
|
+
}
|
|
195
|
+
// Gerar descrição da ação
|
|
196
|
+
description = ActionInterceptor.generateActionDescription(methodName, args, actionType);
|
|
197
|
+
// Capturar evidência ANTES da ação (estado inicial)
|
|
198
|
+
await EvidenceCapture.captureAction(testName, `${actionType}: ${methodName}`, `🎯 INICIANDO: ${description}`);
|
|
199
|
+
// Executar método original
|
|
200
|
+
const result = await originalMethod.apply(this, args);
|
|
201
|
+
// Capturar evidência DEPOIS da ação (resultado)
|
|
202
|
+
await EvidenceCapture.captureAction(testName, `${actionType}: ${methodName}`, `✅ CONCLUÍDO: ${description}`);
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
// Capturar evidência de erro
|
|
207
|
+
await EvidenceCapture.captureAction(testName, `${actionType}: ${methodName}`, `❌ ERRO: ${description} - ${error}`);
|
|
208
|
+
// Tentativa de auto-recovery apenas para ações Web relevantes
|
|
209
|
+
try {
|
|
210
|
+
const recoverable = [
|
|
211
|
+
"click",
|
|
212
|
+
"fill",
|
|
213
|
+
"type",
|
|
214
|
+
"press",
|
|
215
|
+
"selectOption",
|
|
216
|
+
"check",
|
|
217
|
+
"uncheck",
|
|
218
|
+
"hover",
|
|
219
|
+
"switchTo",
|
|
220
|
+
];
|
|
221
|
+
const MIN_CONF = Number(process.env.AUTOCORE_RECOVERY_MIN_CONFIDENCE || "0.7");
|
|
222
|
+
const MAX_RETRIES_DEFAULT = Number(process.env.AUTOCORE_RECOVERY_MAX_RETRIES || "8");
|
|
223
|
+
if (actionType === "Web" && recoverable.includes(methodName)) {
|
|
224
|
+
const failedXPath = ActionInterceptor.extractSelector(args[0]);
|
|
225
|
+
const actionTypeStr = (() => {
|
|
226
|
+
switch (methodName) {
|
|
227
|
+
case "click":
|
|
228
|
+
return "click";
|
|
229
|
+
case "switchTo":
|
|
230
|
+
return "switchTo";
|
|
231
|
+
case "fill":
|
|
232
|
+
case "type":
|
|
233
|
+
return "fill";
|
|
234
|
+
case "press":
|
|
235
|
+
return "press";
|
|
236
|
+
case "selectOption":
|
|
237
|
+
return "select";
|
|
238
|
+
case "check":
|
|
239
|
+
return "check";
|
|
240
|
+
case "uncheck":
|
|
241
|
+
return "uncheck";
|
|
242
|
+
case "hover":
|
|
243
|
+
return "hover";
|
|
244
|
+
default:
|
|
245
|
+
return "click";
|
|
246
|
+
}
|
|
247
|
+
})();
|
|
248
|
+
const pageUrl = TestContext.isPageInitialized()
|
|
249
|
+
? TestContext.getPage().url()
|
|
250
|
+
: undefined;
|
|
251
|
+
// Obter filledInputs/filledFields do singleton e metadados (v2.7.44)
|
|
252
|
+
let filledInputs = [];
|
|
253
|
+
let filledFields = [];
|
|
254
|
+
try {
|
|
255
|
+
const { testRecoveryHelper } = await import("./testRecovery/TestRecoveryClient.js");
|
|
256
|
+
filledInputs = testRecoveryHelper.getFilledInputs();
|
|
257
|
+
filledFields = testRecoveryHelper.getFilledFields();
|
|
258
|
+
}
|
|
259
|
+
catch { }
|
|
260
|
+
const recoveryMeta = getRecoveryMetadata();
|
|
261
|
+
// Obter metadados de página do stack trace (item 20 v2.7.44)
|
|
262
|
+
let pageMeta = {};
|
|
263
|
+
try {
|
|
264
|
+
const mod = await import("../playwright/WebActions.js").catch(() => null);
|
|
265
|
+
const WA = mod ? mod.WebActions : null;
|
|
266
|
+
if (WA && typeof WA.getCallerPageMetadata === "function") {
|
|
267
|
+
pageMeta = WA.getCallerPageMetadata();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch { }
|
|
271
|
+
const contextPayload = {
|
|
272
|
+
text: typeof args[1] === "string" ? args[1] : undefined,
|
|
273
|
+
value: typeof args[1] === "string" ? args[1] : undefined,
|
|
274
|
+
originalMethod: methodName,
|
|
275
|
+
filledInputs,
|
|
276
|
+
filledFields,
|
|
277
|
+
pageFileName: pageMeta.pageFileName,
|
|
278
|
+
pageName: pageMeta.pageName,
|
|
279
|
+
pageObjectName: pageMeta.pageObjectName,
|
|
280
|
+
};
|
|
281
|
+
// Capturar contexto de página para melhor análise
|
|
282
|
+
let pageStructure = undefined;
|
|
283
|
+
let pageHtml;
|
|
284
|
+
try {
|
|
285
|
+
if (TestContext.isPageInitialized()) {
|
|
286
|
+
const page = TestContext.getPage();
|
|
287
|
+
// Tentar importar WebActions para usar extractBasicPageStructure
|
|
288
|
+
const mod = await import("../playwright/WebActions.js").catch(() => null);
|
|
289
|
+
const WebActionsLocal = mod ? mod.WebActions : null;
|
|
290
|
+
if (WebActionsLocal &&
|
|
291
|
+
typeof WebActionsLocal.extractBasicPageStructure ===
|
|
292
|
+
"function") {
|
|
293
|
+
pageStructure =
|
|
294
|
+
await WebActionsLocal.extractBasicPageStructure(page).catch(() => undefined);
|
|
295
|
+
}
|
|
296
|
+
// Fallback: capturar HTML se não conseguiu estrutura
|
|
297
|
+
if (!pageStructure) {
|
|
298
|
+
const html = await page.content().catch(() => "");
|
|
299
|
+
if (html) {
|
|
300
|
+
pageHtml =
|
|
301
|
+
html.length > 50000
|
|
302
|
+
? html.substring(0, 50000) + "... (truncated)"
|
|
303
|
+
: html;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch { }
|
|
309
|
+
// Detectar tipo de erro a partir da exceção
|
|
310
|
+
const detectErrorType = (err) => {
|
|
311
|
+
const msg = err && err.message
|
|
312
|
+
? String(err.message).toLowerCase()
|
|
313
|
+
: String(err || "").toLowerCase();
|
|
314
|
+
if (msg.includes("strict mode violation") ||
|
|
315
|
+
msg.includes("multiple elements"))
|
|
316
|
+
return "multiple_elements";
|
|
317
|
+
if (msg.includes("timeout") ||
|
|
318
|
+
msg.includes("timed out") ||
|
|
319
|
+
err?.code === "ETIMEDOUT")
|
|
320
|
+
return "timeout";
|
|
321
|
+
if (msg.includes("detached") || msg.includes("stale"))
|
|
322
|
+
return "stale_element";
|
|
323
|
+
if (msg.includes("navigation") && msg.includes("wrong"))
|
|
324
|
+
return "wrong_navigation";
|
|
325
|
+
return "not_found";
|
|
326
|
+
};
|
|
327
|
+
const detectedErrorType = detectErrorType(error);
|
|
328
|
+
Logger.info(`[ActionInterceptor] 🔍 AutoHealing: chamando analyze-failure para XPath "${failedXPath}" (${detectedErrorType}, executionSource=${recoveryMeta.executionSource})`);
|
|
329
|
+
const response = await analyzeFailure({
|
|
330
|
+
url: pageUrl || "",
|
|
331
|
+
failedXPath,
|
|
332
|
+
errorType: detectedErrorType,
|
|
333
|
+
actionType: actionTypeStr,
|
|
334
|
+
sessionId: TestContext.getOrCreateSessionId(),
|
|
335
|
+
executionSource: recoveryMeta.executionSource,
|
|
336
|
+
testCaseName: recoveryMeta.testCaseName,
|
|
337
|
+
testCaseId: recoveryMeta.testCaseId,
|
|
338
|
+
testMethodName: recoveryMeta.testMethodName,
|
|
339
|
+
context: contextPayload,
|
|
340
|
+
pageStructure,
|
|
341
|
+
pageHtml,
|
|
342
|
+
});
|
|
343
|
+
if (!response) {
|
|
344
|
+
Logger.warning(`[ActionInterceptor] ⚠️ AutoHealing: sem resposta do backend (verifique AUTOCORE_HUB_URL ou conectividade)`);
|
|
345
|
+
}
|
|
346
|
+
else if (!response.analysis ||
|
|
347
|
+
!response.analysis.suggestedXPath) {
|
|
348
|
+
Logger.warning(`[ActionInterceptor] ⚠️ AutoHealing: backend não encontrou XPath alternativo para "${failedXPath}"`);
|
|
349
|
+
}
|
|
350
|
+
if (response &&
|
|
351
|
+
response.analysis &&
|
|
352
|
+
response.analysis.suggestedXPath) {
|
|
353
|
+
const { suggestedXPath, confidence } = response.analysis;
|
|
354
|
+
if (confidence < MIN_CONF) {
|
|
355
|
+
Logger.warning(`[ActionInterceptor] ⚠️ AutoHealing: confiança ${(confidence * 100).toFixed(0)}% abaixo do mínimo (${(MIN_CONF * 100).toFixed(0)}%). XPath sugerido: "${suggestedXPath}"`);
|
|
356
|
+
}
|
|
357
|
+
if (confidence >= MIN_CONF) {
|
|
358
|
+
// Executar ações recomendadas antes do retry (v2.7.43)
|
|
359
|
+
const frameHelper = createFrameHelper();
|
|
360
|
+
if (response.actions && response.actions.length) {
|
|
361
|
+
for (const a of response.actions) {
|
|
362
|
+
try {
|
|
363
|
+
// Tentar usar as Actions do framework quando possível
|
|
364
|
+
const mod = await import("../playwright/WebActions.js").catch(() => null);
|
|
365
|
+
const WebActions = mod ? mod.WebActions : null;
|
|
366
|
+
switch (a.type) {
|
|
367
|
+
case "wait":
|
|
368
|
+
if (TestContext.isPageInitialized())
|
|
369
|
+
await TestContext.getPage().waitForTimeout(a.waitMs || 1000);
|
|
370
|
+
break;
|
|
371
|
+
case "click_other":
|
|
372
|
+
if (WebActions &&
|
|
373
|
+
typeof WebActions.click === "function") {
|
|
374
|
+
try {
|
|
375
|
+
await WebActions.click(a.selector || "", "", false);
|
|
376
|
+
}
|
|
377
|
+
catch { }
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
try {
|
|
381
|
+
if (TestContext.isPageInitialized())
|
|
382
|
+
await TestContext.getPage()
|
|
383
|
+
.locator(a.selector || "")
|
|
384
|
+
.click();
|
|
385
|
+
}
|
|
386
|
+
catch { }
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
case "navigate":
|
|
390
|
+
if (WebActions &&
|
|
391
|
+
typeof WebActions.navigate === "function") {
|
|
392
|
+
try {
|
|
393
|
+
if (a.url)
|
|
394
|
+
await WebActions.navigate(a.url);
|
|
395
|
+
}
|
|
396
|
+
catch { }
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
try {
|
|
400
|
+
if (a.url && TestContext.isPageInitialized())
|
|
401
|
+
await TestContext.getPage().goto(a.url);
|
|
402
|
+
}
|
|
403
|
+
catch { }
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case "refresh":
|
|
407
|
+
if (WebActions &&
|
|
408
|
+
typeof WebActions.refresh === "function") {
|
|
409
|
+
try {
|
|
410
|
+
await WebActions.refresh();
|
|
411
|
+
}
|
|
412
|
+
catch { }
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
try {
|
|
416
|
+
if (TestContext.isPageInitialized())
|
|
417
|
+
await TestContext.getPage().reload();
|
|
418
|
+
}
|
|
419
|
+
catch { }
|
|
420
|
+
}
|
|
421
|
+
break;
|
|
422
|
+
case "switch_frame":
|
|
423
|
+
if (a.selector) {
|
|
424
|
+
try {
|
|
425
|
+
await frameHelper.switchTo(a.selector);
|
|
426
|
+
}
|
|
427
|
+
catch { }
|
|
428
|
+
}
|
|
429
|
+
break;
|
|
430
|
+
default:
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch { }
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// Preparar candidatos: suggested + alternatives
|
|
438
|
+
const alternatives = response.analysis.alternatives || [];
|
|
439
|
+
const candidates = [];
|
|
440
|
+
if (suggestedXPath)
|
|
441
|
+
candidates.push(suggestedXPath);
|
|
442
|
+
if (Array.isArray(alternatives) && alternatives.length)
|
|
443
|
+
candidates.push(...alternatives);
|
|
444
|
+
const maxRetries = MAX_RETRIES_DEFAULT;
|
|
445
|
+
let attemptNumber = 2; // primeira tentativa de recovery é tentativa 2
|
|
446
|
+
const logId = response.logId;
|
|
447
|
+
for (; attemptNumber <= Math.max(2, maxRetries); attemptNumber++) {
|
|
448
|
+
const candidateIndex = Math.min(attemptNumber - 2, candidates.length - 1);
|
|
449
|
+
const candidate = candidates.length
|
|
450
|
+
? candidates[candidateIndex]
|
|
451
|
+
: suggestedXPath;
|
|
452
|
+
if (!candidate)
|
|
453
|
+
break;
|
|
454
|
+
// Gerenciar contexto de frame (v2.7.43)
|
|
455
|
+
await frameHelper.switchToDefaultIfNeeded();
|
|
456
|
+
// Re-executar switch_frame antes de cada tentativa
|
|
457
|
+
if (response.actions && response.actions.length) {
|
|
458
|
+
await frameHelper.applySwitchFrameActions(response.actions);
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
const newArgs = [...args];
|
|
462
|
+
newArgs[0] = candidate;
|
|
463
|
+
const retryResult = await originalMethod.apply(this, newArgs);
|
|
464
|
+
// Gerenciar contexto de frame (v2.7.43)
|
|
465
|
+
await frameHelper.switchToDefaultIfNeeded();
|
|
466
|
+
// Capturar evidência de sucesso após retry
|
|
467
|
+
await EvidenceCapture.captureAction(testName, `${actionType}: ${methodName}`, `🔁 RECOVERY SUCCESS (attempt ${attemptNumber}): ${description} -> ${candidate}`);
|
|
468
|
+
// Marcar sucesso no Hub com número da tentativa
|
|
469
|
+
try {
|
|
470
|
+
const sessionId = TestContext.getOrCreateSessionId();
|
|
471
|
+
await markSuccess(sessionId, attemptNumber);
|
|
472
|
+
}
|
|
473
|
+
catch { }
|
|
474
|
+
// Report success com logId (v2.7.44)
|
|
475
|
+
try {
|
|
476
|
+
await reportResult({
|
|
477
|
+
logId,
|
|
478
|
+
sessionId: TestContext.getOrCreateSessionId(),
|
|
479
|
+
xpath: candidate,
|
|
480
|
+
attemptNumber,
|
|
481
|
+
success: true,
|
|
482
|
+
autoFixed: false,
|
|
483
|
+
recoverySource: "framework",
|
|
484
|
+
executionSource: recoveryMeta.executionSource,
|
|
485
|
+
testCaseName: recoveryMeta.testCaseName,
|
|
486
|
+
testCaseId: recoveryMeta.testCaseId,
|
|
487
|
+
testMethodName: recoveryMeta.testMethodName,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
catch { }
|
|
491
|
+
// Auto-fix local se confiança >= 0.7 e autoFixAvailable (v2.7.44)
|
|
492
|
+
if (!response.analysis?.autoFixAvailable) {
|
|
493
|
+
Logger.info(`[ActionInterceptor] AutoFix não disponível (autoFixAvailable=${response.analysis?.autoFixAvailable}, executionSource=${recoveryMeta.executionSource})`);
|
|
494
|
+
}
|
|
495
|
+
if (response.analysis?.autoFixAvailable &&
|
|
496
|
+
confidence >= 0.7) {
|
|
497
|
+
Logger.info(`[ActionInterceptor] 🛠️ AutoFix: iniciando correção local "${failedXPath}" → "${candidate}"`);
|
|
498
|
+
try {
|
|
499
|
+
const { testRecoveryHelper } = await import("./testRecovery/TestRecoveryClient.js");
|
|
500
|
+
const projRoot = testRecoveryHelper.getProjectRoot() ||
|
|
501
|
+
process.env.AUTOCORE_PROJECT_ROOT ||
|
|
502
|
+
process.cwd();
|
|
503
|
+
// Enriquecer auto-fix com contexto de Attributes/Page (item 7/12 v2.7.44)
|
|
504
|
+
let attrCtx = {};
|
|
505
|
+
try {
|
|
506
|
+
const { WebActions } = await import("../playwright/WebActions.js");
|
|
507
|
+
attrCtx = WebActions.getCallerAttributesContext();
|
|
508
|
+
}
|
|
509
|
+
catch { }
|
|
510
|
+
const resolvedMethodName = attrCtx.methodName || recoveryMeta.testMethodName;
|
|
511
|
+
let autoFixConfirmed = false;
|
|
512
|
+
// 1) MCP local-first (preferencial)
|
|
513
|
+
try {
|
|
514
|
+
const { fixXPathViaLocalMcp } = await import("./McpLocalClient.js");
|
|
515
|
+
const mcpFix = await fixXPathViaLocalMcp({
|
|
516
|
+
projectRoot: projRoot,
|
|
517
|
+
oldXPath: failedXPath,
|
|
518
|
+
newXPath: candidate,
|
|
519
|
+
confidence,
|
|
520
|
+
className: attrCtx.className,
|
|
521
|
+
attributesFile: attrCtx.attributesFile,
|
|
522
|
+
methodName: resolvedMethodName,
|
|
523
|
+
executionSource: "Local",
|
|
524
|
+
});
|
|
525
|
+
autoFixConfirmed = !!(mcpFix?.success && mcpFix.fileUpdated !== false);
|
|
526
|
+
}
|
|
527
|
+
catch (mcpFixError) {
|
|
528
|
+
Logger.warning(`[ActionInterceptor] Auto-fix via MCP local falhou: ${mcpFixError instanceof Error ? mcpFixError.message : String(mcpFixError)}`);
|
|
529
|
+
}
|
|
530
|
+
// 2) Fallback HTTP auto-fix-local quando MCP local não confirmou escrita
|
|
531
|
+
if (!autoFixConfirmed) {
|
|
532
|
+
const apiFix = await testRecoveryHelper.autoFixLocal({
|
|
533
|
+
projectRoot: projRoot,
|
|
534
|
+
oldXPath: failedXPath,
|
|
535
|
+
newXPath: candidate,
|
|
536
|
+
confidence,
|
|
537
|
+
methodName: resolvedMethodName,
|
|
538
|
+
executionSource: "Local",
|
|
539
|
+
className: attrCtx.className,
|
|
540
|
+
attributesFile: attrCtx.attributesFile,
|
|
541
|
+
});
|
|
542
|
+
autoFixConfirmed = !!(apiFix.success && apiFix.fix?.filePath);
|
|
543
|
+
if (!autoFixConfirmed) {
|
|
544
|
+
Logger.warning(`[ActionInterceptor] Auto-fix não confirmou escrita local para ${failedXPath} -> ${candidate}`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (autoFixConfirmed) {
|
|
548
|
+
try {
|
|
549
|
+
await reportResult({
|
|
550
|
+
logId,
|
|
551
|
+
sessionId: TestContext.getOrCreateSessionId(),
|
|
552
|
+
xpath: candidate,
|
|
553
|
+
attemptNumber,
|
|
554
|
+
success: true,
|
|
555
|
+
autoFixed: true,
|
|
556
|
+
recoverySource: "framework",
|
|
557
|
+
executionSource: recoveryMeta.executionSource,
|
|
558
|
+
testCaseName: recoveryMeta.testCaseName,
|
|
559
|
+
testCaseId: recoveryMeta.testCaseId,
|
|
560
|
+
testMethodName: recoveryMeta.testMethodName,
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
catch { }
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
catch { }
|
|
567
|
+
}
|
|
568
|
+
return retryResult;
|
|
569
|
+
}
|
|
570
|
+
catch (retryErr) {
|
|
571
|
+
// continuar para próximo candidato/attempt
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Reportar falha após esgotar tentativas (v2.7.44)
|
|
576
|
+
await frameHelper.switchToDefaultIfNeeded();
|
|
577
|
+
try {
|
|
578
|
+
await reportResult({
|
|
579
|
+
logId,
|
|
580
|
+
sessionId: TestContext.getOrCreateSessionId(),
|
|
581
|
+
xpath: suggestedXPath,
|
|
582
|
+
attemptNumber: attemptNumber - 1,
|
|
583
|
+
success: false,
|
|
584
|
+
recoverySource: "framework",
|
|
585
|
+
executionSource: recoveryMeta.executionSource,
|
|
586
|
+
testCaseName: recoveryMeta.testCaseName,
|
|
587
|
+
testCaseId: recoveryMeta.testCaseId,
|
|
588
|
+
testMethodName: recoveryMeta.testMethodName,
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
catch { }
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
catch (recoveryErr) {
|
|
597
|
+
Logger.warning(`[ActionInterceptor] ⚠️ AutoHealing falhou: ${recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr)}`);
|
|
598
|
+
}
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
ActionInterceptor.interceptedMethods.add(key);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* ✅ Gera descrição amigável da ação
|
|
606
|
+
*/
|
|
607
|
+
static generateActionDescription(methodName, args, actionType) {
|
|
608
|
+
try {
|
|
609
|
+
switch (actionType) {
|
|
610
|
+
case "Web":
|
|
611
|
+
return ActionInterceptor.generateWebDescription(methodName, args);
|
|
612
|
+
case "Mobile":
|
|
613
|
+
return ActionInterceptor.generateMobileDescription(methodName, args);
|
|
614
|
+
case "API":
|
|
615
|
+
return ActionInterceptor.generateApiDescription(methodName, args);
|
|
616
|
+
default:
|
|
617
|
+
return `${methodName} com ${args.length} parâmetros`;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
catch {
|
|
621
|
+
return `${methodName} executado`;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* ✅ Gera descrição para ações Web
|
|
626
|
+
*/
|
|
627
|
+
static generateWebDescription(methodName, args) {
|
|
628
|
+
const [selector, value, description] = args;
|
|
629
|
+
const element = ActionInterceptor.extractSelector(selector);
|
|
630
|
+
switch (methodName) {
|
|
631
|
+
case "click":
|
|
632
|
+
return description || `Clicar no elemento "${element}"`;
|
|
633
|
+
case "fill":
|
|
634
|
+
case "type":
|
|
635
|
+
return description || `Preencher "${element}" com "${value}"`;
|
|
636
|
+
case "press":
|
|
637
|
+
return description || `Pressionar tecla "${value}" em "${element}"`;
|
|
638
|
+
case "selectOption":
|
|
639
|
+
return description || `Selecionar opção "${value}" em "${element}"`;
|
|
640
|
+
case "check":
|
|
641
|
+
return description || `Marcar checkbox "${element}"`;
|
|
642
|
+
case "uncheck":
|
|
643
|
+
return description || `Desmarcar checkbox "${element}"`;
|
|
644
|
+
case "hover":
|
|
645
|
+
return description || `Passar mouse sobre "${element}"`;
|
|
646
|
+
case "navigate":
|
|
647
|
+
return description || `Navegar para "${selector}"`;
|
|
648
|
+
case "waitForElement":
|
|
649
|
+
return description || `Aguardar elemento "${element}"`;
|
|
650
|
+
case "waitForText":
|
|
651
|
+
return description || `Aguardar texto "${value}" em "${element}"`;
|
|
652
|
+
default:
|
|
653
|
+
return description || `Executar ${methodName} em "${element}"`;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* ✅ Gera descrição para ações Mobile
|
|
658
|
+
*/
|
|
659
|
+
static generateMobileDescription(methodName, args) {
|
|
660
|
+
const [selector, value, description] = args;
|
|
661
|
+
const element = ActionInterceptor.extractSelector(selector);
|
|
662
|
+
switch (methodName) {
|
|
663
|
+
case "click":
|
|
664
|
+
case "tap":
|
|
665
|
+
return description || `Tocar no elemento "${element}"`;
|
|
666
|
+
case "setText":
|
|
667
|
+
return description || `Inserir texto "${value}" em "${element}"`;
|
|
668
|
+
case "swipe":
|
|
669
|
+
return description || `Deslizar de ${args[0]} para ${args[1]}`;
|
|
670
|
+
case "scroll":
|
|
671
|
+
return description || `Rolar tela ${args[0] || "para baixo"}`;
|
|
672
|
+
case "waitForElement":
|
|
673
|
+
return description || `Aguardar elemento "${element}"`;
|
|
674
|
+
default:
|
|
675
|
+
return description || `Executar ${methodName} no mobile`;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* ✅ Gera descrição para ações API
|
|
680
|
+
*/
|
|
681
|
+
static generateApiDescription(methodName, args) {
|
|
682
|
+
const [url, data, description] = args;
|
|
683
|
+
switch (methodName) {
|
|
684
|
+
case "get":
|
|
685
|
+
return description || `Requisição GET para "${url}"`;
|
|
686
|
+
case "post":
|
|
687
|
+
return description || `Requisição POST para "${url}"`;
|
|
688
|
+
case "put":
|
|
689
|
+
return description || `Requisição PUT para "${url}"`;
|
|
690
|
+
case "delete":
|
|
691
|
+
return description || `Requisição DELETE para "${url}"`;
|
|
692
|
+
case "patch":
|
|
693
|
+
return description || `Requisição PATCH para "${url}"`;
|
|
694
|
+
case "request":
|
|
695
|
+
return description || `Requisição HTTP para "${url}"`;
|
|
696
|
+
default:
|
|
697
|
+
return description || `Requisição ${methodName} executada`;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* ✅ Extrai seletor de diferentes tipos
|
|
702
|
+
*/
|
|
703
|
+
static extractSelector(selector) {
|
|
704
|
+
if (typeof selector === "string") {
|
|
705
|
+
return selector;
|
|
706
|
+
}
|
|
707
|
+
if (selector && typeof selector === "object") {
|
|
708
|
+
// Playwright Locator
|
|
709
|
+
if (selector._selector)
|
|
710
|
+
return selector._selector;
|
|
711
|
+
if (selector.selector)
|
|
712
|
+
return selector.selector;
|
|
713
|
+
// Mobile selector
|
|
714
|
+
if (selector.using && selector.value) {
|
|
715
|
+
return `${selector.using}="${selector.value}"`;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return String(selector).substring(0, 50) + "...";
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* ✅ Força o refresh da página
|
|
722
|
+
*/
|
|
723
|
+
static async forceRefresh() {
|
|
724
|
+
try {
|
|
725
|
+
if (TestContext.isPageInitialized()) {
|
|
726
|
+
const page = TestContext.getPage();
|
|
727
|
+
// Tentar recarregar a página com Playwright
|
|
728
|
+
await page.reload({ waitUntil: "networkidle" });
|
|
729
|
+
// Fallback: Forçar refresh com JavaScript (cache-busting)
|
|
730
|
+
await page.evaluate(() => {
|
|
731
|
+
location.reload();
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
catch (error) {
|
|
736
|
+
console.error("Erro ao tentar forçar o refresh da página:", error);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
// ✅ Auto-inicialização
|
|
741
|
+
ActionInterceptor.initialize();
|