@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,295 @@
|
|
|
1
|
+
import { StatementTracker } from '../hubdocs/StatementTracker.js';
|
|
2
|
+
import { analyzeCurrentSpecFile } from './SpecFileAnalyzer.js';
|
|
3
|
+
import { Logger } from './Logger.js';
|
|
4
|
+
const interceptorsInstalled = new Set();
|
|
5
|
+
// Regex constants para performance
|
|
6
|
+
const SQL_PATTERN = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)/i;
|
|
7
|
+
const FROM_PATTERN = /FROM\s+([^\s,]+)/i;
|
|
8
|
+
const INSERT_PATTERN = /INSERT\s+INTO\s+([^\s,(]+)/i;
|
|
9
|
+
const UPDATE_PATTERN = /UPDATE\s+([^\s,]+)/i;
|
|
10
|
+
const DELETE_PATTERN = /DELETE\s+FROM\s+([^\s,]+)/i;
|
|
11
|
+
/**
|
|
12
|
+
* 🎯 Detecta tipo de operação SQL automaticamente
|
|
13
|
+
*/
|
|
14
|
+
function detectSqlType(sql) {
|
|
15
|
+
const sqlUpper = sql.trim().toUpperCase();
|
|
16
|
+
if (sqlUpper.startsWith('SELECT')) {
|
|
17
|
+
return 'SELECT';
|
|
18
|
+
}
|
|
19
|
+
if (sqlUpper.startsWith('INSERT')) {
|
|
20
|
+
return 'INSERT';
|
|
21
|
+
}
|
|
22
|
+
if (sqlUpper.startsWith('UPDATE')) {
|
|
23
|
+
return 'UPDATE';
|
|
24
|
+
}
|
|
25
|
+
if (sqlUpper.startsWith('DELETE')) {
|
|
26
|
+
return 'DELETE';
|
|
27
|
+
}
|
|
28
|
+
if (sqlUpper.startsWith('CREATE')) {
|
|
29
|
+
return 'CREATE';
|
|
30
|
+
}
|
|
31
|
+
if (sqlUpper.startsWith('ALTER')) {
|
|
32
|
+
return 'ALTER';
|
|
33
|
+
}
|
|
34
|
+
if (sqlUpper.startsWith('DROP')) {
|
|
35
|
+
return 'DROP';
|
|
36
|
+
}
|
|
37
|
+
return 'SQL';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 🎯 Extrai descrição ou SQL da lista de argumentos
|
|
41
|
+
*/
|
|
42
|
+
function extractInfo(methodName, args) {
|
|
43
|
+
if (args.length === 0) {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
// BancoActions.execute(description, sql)
|
|
47
|
+
if (methodName === 'execute' && args.length >= 2) {
|
|
48
|
+
return { description: String(args[0]), sql: String(args[1]) };
|
|
49
|
+
}
|
|
50
|
+
// BancoActions.executeQuery(sql) ou BancoHelper.executarQuery(sql)
|
|
51
|
+
if ((methodName === 'executeQuery' || methodName === 'executarQuery') &&
|
|
52
|
+
args.length >= 1) {
|
|
53
|
+
return { sql: String(args[0]) };
|
|
54
|
+
}
|
|
55
|
+
// BancoActions.update(description, sql)
|
|
56
|
+
if (methodName === 'update' && args.length >= 2) {
|
|
57
|
+
return { description: String(args[0]), sql: String(args[1]) };
|
|
58
|
+
}
|
|
59
|
+
// BancoActions.select(sql)
|
|
60
|
+
if (methodName === 'select' && args.length >= 1) {
|
|
61
|
+
return { sql: String(args[0]) };
|
|
62
|
+
}
|
|
63
|
+
// Fallback: primeiro argumento que é string
|
|
64
|
+
const firstStringArg = args.find((arg) => typeof arg === 'string');
|
|
65
|
+
if (firstStringArg) {
|
|
66
|
+
// Se parece com SQL, é SQL
|
|
67
|
+
if (String(firstStringArg).trim().toUpperCase().match(SQL_PATTERN)) {
|
|
68
|
+
return { sql: String(firstStringArg) };
|
|
69
|
+
}
|
|
70
|
+
return { description: String(firstStringArg) };
|
|
71
|
+
}
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 🎯 Extrai nome da tabela do SQL
|
|
76
|
+
*/
|
|
77
|
+
function extractTableName(sql) {
|
|
78
|
+
const sqlUpper = sql.trim().toUpperCase();
|
|
79
|
+
// SELECT ... FROM table
|
|
80
|
+
let match = sqlUpper.match(FROM_PATTERN);
|
|
81
|
+
if (match) {
|
|
82
|
+
return match[1];
|
|
83
|
+
}
|
|
84
|
+
// INSERT INTO table
|
|
85
|
+
match = sqlUpper.match(INSERT_PATTERN);
|
|
86
|
+
if (match) {
|
|
87
|
+
return match[1];
|
|
88
|
+
}
|
|
89
|
+
// UPDATE table
|
|
90
|
+
match = sqlUpper.match(UPDATE_PATTERN);
|
|
91
|
+
if (match) {
|
|
92
|
+
return match[1];
|
|
93
|
+
}
|
|
94
|
+
// DELETE FROM table
|
|
95
|
+
match = sqlUpper.match(DELETE_PATTERN);
|
|
96
|
+
if (match) {
|
|
97
|
+
return match[1];
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 🎯 Gera nome do CT automaticamente
|
|
103
|
+
*/
|
|
104
|
+
function generateCtName(info) {
|
|
105
|
+
const { className, methodName, sql, description } = info;
|
|
106
|
+
// 🆕 NOVO: Obter informações do CN/CT do arquivo .spec.ts atual
|
|
107
|
+
let ctPrefix = '';
|
|
108
|
+
try {
|
|
109
|
+
const specAnalysis = analyzeCurrentSpecFile();
|
|
110
|
+
const cnName = specAnalysis.cn;
|
|
111
|
+
const ctName = specAnalysis.ct;
|
|
112
|
+
if (cnName || ctName) {
|
|
113
|
+
const parts = [];
|
|
114
|
+
if (cnName)
|
|
115
|
+
parts.push(cnName);
|
|
116
|
+
if (ctName)
|
|
117
|
+
parts.push(ctName);
|
|
118
|
+
ctPrefix = `${parts.join(' → ')} → `;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Silenciosamente ignorar erros na análise do spec
|
|
123
|
+
}
|
|
124
|
+
// Se tem descrição, usar ela
|
|
125
|
+
if (description) {
|
|
126
|
+
return `${ctPrefix}${className}.${methodName}() - ${description}`;
|
|
127
|
+
}
|
|
128
|
+
// Se tem SQL, detectar tipo e usar
|
|
129
|
+
if (sql) {
|
|
130
|
+
const sqlType = detectSqlType(sql);
|
|
131
|
+
const tableName = extractTableName(sql);
|
|
132
|
+
return `${ctPrefix}${className}.${methodName}() - ${sqlType}${tableName ? ` ${tableName}` : ''}`;
|
|
133
|
+
}
|
|
134
|
+
// Fallback: nome do método
|
|
135
|
+
return `${ctPrefix}${className}.${methodName}()`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 🤖 Intercepta método automaticamente
|
|
139
|
+
*/
|
|
140
|
+
function interceptMethod(target, className, methodName, originalMethod) {
|
|
141
|
+
return async (...args) => {
|
|
142
|
+
// Extrair informações da chamada
|
|
143
|
+
const info = extractInfo(methodName, args);
|
|
144
|
+
const methodInfo = {
|
|
145
|
+
className,
|
|
146
|
+
methodName,
|
|
147
|
+
args,
|
|
148
|
+
...info,
|
|
149
|
+
};
|
|
150
|
+
// 🔧 CORREÇÃO CRÍTICA: NÃO criar CTs para métodos de banco
|
|
151
|
+
// DatabaseInterceptor deve apenas REGISTRAR AÇÕES, não criar CTs
|
|
152
|
+
// CTs são criados apenas para métodos Statement (validateCep, processOrder, etc.)
|
|
153
|
+
Logger.info(`🗄️ [DatabaseInterceptor] Executando ${className}.${methodName}() - REGISTRANDO AÇÃO`);
|
|
154
|
+
// Gerar nome da ação (não CT)
|
|
155
|
+
const actionName = generateCtName(methodInfo);
|
|
156
|
+
const startTime = Date.now();
|
|
157
|
+
try {
|
|
158
|
+
// Executar método original
|
|
159
|
+
const result = await originalMethod.apply(target, args);
|
|
160
|
+
const duration = Date.now() - startTime;
|
|
161
|
+
// ✅ NOVO: Registrar como AÇÃO executada, não como CT
|
|
162
|
+
StatementTracker.recordAction('DB', `${className}.${methodName}() - ${actionName}`, true, duration, {
|
|
163
|
+
query: methodInfo.sql?.slice(0, 500) || 'N/A',
|
|
164
|
+
});
|
|
165
|
+
Logger.info(`✅ [DatabaseInterceptor] ${className}.${methodName}() executado com sucesso (${duration}ms)`);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
const duration = Date.now() - startTime;
|
|
170
|
+
// ✅ NOVO: Registrar como AÇÃO falhada, não como CT falhado
|
|
171
|
+
StatementTracker.recordAction('DB', `${className}.${methodName}() - ${actionName}`, false, duration, {
|
|
172
|
+
query: methodInfo.sql?.slice(0, 500) || 'N/A',
|
|
173
|
+
});
|
|
174
|
+
Logger.error(`❌ [DatabaseInterceptor] ${className}.${methodName}() falhou (${duration}ms): ${error}`);
|
|
175
|
+
// Re-throw o erro
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 🎯 Métodos que devem ser interceptados por classe
|
|
182
|
+
* APENAS métodos de negócio - NÃO métodos internos do framework
|
|
183
|
+
*/
|
|
184
|
+
const METHODS_TO_INTERCEPT = {
|
|
185
|
+
// Banco de Dados - apenas métodos de execução SQL
|
|
186
|
+
BancoActions: ['execute', 'executeQuery', 'update', 'select', 'selectColumn'],
|
|
187
|
+
BancoHelper: ['executarQuery', 'validateEquals'],
|
|
188
|
+
// SSH - apenas métodos de comando e validação
|
|
189
|
+
SSHActions: [
|
|
190
|
+
'write',
|
|
191
|
+
'read',
|
|
192
|
+
'executeAndRead',
|
|
193
|
+
'validateContains',
|
|
194
|
+
'validateEquals',
|
|
195
|
+
],
|
|
196
|
+
// 🚫 API REMOVIDO - ApiActions são métodos internos que não devem ser interceptados como CTs
|
|
197
|
+
// 'ApiActions': ['get', 'post', 'put', 'delete', 'patch', 'request'], // <- REMOVIDO
|
|
198
|
+
// Web (Playwright) - apenas ações de interação
|
|
199
|
+
WebActions: [
|
|
200
|
+
'navegarPara',
|
|
201
|
+
'click',
|
|
202
|
+
'doubleClick',
|
|
203
|
+
'rightClick',
|
|
204
|
+
'preencher',
|
|
205
|
+
'hover',
|
|
206
|
+
'mouseMove',
|
|
207
|
+
'selecionarOpcao',
|
|
208
|
+
'selecionarEmLista',
|
|
209
|
+
'selecionarOpcaoTabela',
|
|
210
|
+
'trocarFrame',
|
|
211
|
+
'esperarElemento',
|
|
212
|
+
'esperarTexto',
|
|
213
|
+
'obterTexto',
|
|
214
|
+
'obterValor',
|
|
215
|
+
'capturarPrint',
|
|
216
|
+
'verificarExistencia',
|
|
217
|
+
'validarTextoCampo',
|
|
218
|
+
'validarExistencia',
|
|
219
|
+
'executarJavaScript',
|
|
220
|
+
],
|
|
221
|
+
// Mobile (Appium) - apenas ações de interação
|
|
222
|
+
MobileActions: [
|
|
223
|
+
'click',
|
|
224
|
+
'tap',
|
|
225
|
+
'setText',
|
|
226
|
+
'swipe',
|
|
227
|
+
'scroll',
|
|
228
|
+
'longPress',
|
|
229
|
+
'doubleClick',
|
|
230
|
+
'dragAndDrop',
|
|
231
|
+
'hideKeyboard',
|
|
232
|
+
'swipeLeft',
|
|
233
|
+
'swipeRight',
|
|
234
|
+
'swipeUp',
|
|
235
|
+
'swipeDown',
|
|
236
|
+
'pinch',
|
|
237
|
+
'zoom',
|
|
238
|
+
'waitForElement',
|
|
239
|
+
'back',
|
|
240
|
+
'switchToContext',
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* 🚀 Instala interceptação automática em uma classe
|
|
245
|
+
*/
|
|
246
|
+
export function installDatabaseInterceptor(targetClass, className) {
|
|
247
|
+
const interceptorKey = `${className}`;
|
|
248
|
+
if (interceptorsInstalled.has(interceptorKey)) {
|
|
249
|
+
return; // Já instalado
|
|
250
|
+
}
|
|
251
|
+
// Obter lista de métodos permitidos para esta classe
|
|
252
|
+
const allowedMethods = METHODS_TO_INTERCEPT[className] || [];
|
|
253
|
+
if (allowedMethods.length === 0) {
|
|
254
|
+
// Se não tem métodos específicos, não interceptar nada
|
|
255
|
+
if (process.env.AUTOCORE_DEBUG_LOGS === 'true') {
|
|
256
|
+
process.stderr.write(`[DatabaseInterceptor] Nenhum método definido para interceptar em ${className}\n`);
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
let interceptedCount = 0;
|
|
261
|
+
for (const methodName of allowedMethods) {
|
|
262
|
+
const target = targetClass;
|
|
263
|
+
const originalMethod = target[methodName];
|
|
264
|
+
// Interceptar apenas se método existir e for função
|
|
265
|
+
if (typeof originalMethod === 'function') {
|
|
266
|
+
target[methodName] = interceptMethod(targetClass, className, methodName, originalMethod);
|
|
267
|
+
interceptedCount++;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
interceptorsInstalled.add(interceptorKey);
|
|
271
|
+
// Log interno do framework - silent mode disponível
|
|
272
|
+
if (process.env.AUTOCORE_DEBUG_LOGS === 'true') {
|
|
273
|
+
process.stdout.write(`🤖 [DatabaseInterceptor] Interceptação instalada em ${className} (${interceptedCount}/${allowedMethods.length} métodos)\n`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* 🚀 Instala interceptação automática em múltiplas classes
|
|
278
|
+
*/
|
|
279
|
+
export function installDatabaseInterceptors(classes) {
|
|
280
|
+
for (const { class: targetClass, name } of classes) {
|
|
281
|
+
installDatabaseInterceptor(targetClass, name);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* 📋 Lista interceptadores instalados
|
|
286
|
+
*/
|
|
287
|
+
export function getInstalledDatabaseInterceptors() {
|
|
288
|
+
return Array.from(interceptorsInstalled);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* 🧹 Remove todos os interceptadores
|
|
292
|
+
*/
|
|
293
|
+
export function clearDatabaseInterceptors() {
|
|
294
|
+
interceptorsInstalled.clear();
|
|
295
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type DateFormat = "DD/MM/YYYY" | "MM/DD/YYYY" | "YYYY-MM-DD" | "DD-MM-YYYY" | "MM-DD-YYYY" | "DD.MM.YYYY" | "MM.DD.YYYY" | string;
|
|
2
|
+
export type DateOptions = {
|
|
3
|
+
descricao?: string;
|
|
4
|
+
tirarPrint?: boolean;
|
|
5
|
+
delay?: number;
|
|
6
|
+
inputFormat?: DateFormat;
|
|
7
|
+
outputFormat?: DateFormat;
|
|
8
|
+
outputSeparator?: "/" | "-" | ".";
|
|
9
|
+
pressTab?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare class DateHelper {
|
|
12
|
+
static convert(value: string, inputFormat?: DateFormat, outputFormat?: DateFormat): string;
|
|
13
|
+
static changeSeparator(value: string, separator: "/" | "-" | "."): string;
|
|
14
|
+
static toISO(value: string, inputFormat?: DateFormat): string;
|
|
15
|
+
static detectFormat(value: string): DateFormat;
|
|
16
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
2
|
+
const pad2 = (value) => String(clamp(value, 0, 99)).padStart(2, "0");
|
|
3
|
+
const pad4 = (value) => String(clamp(value, 0, 9999)).padStart(4, "0");
|
|
4
|
+
const normalizeFormat = (format) => format
|
|
5
|
+
.trim()
|
|
6
|
+
.toUpperCase()
|
|
7
|
+
.replace(/D{2}/g, "DD")
|
|
8
|
+
.replace(/M{2}/g, "MM")
|
|
9
|
+
.replace(/Y{4}/g, "YYYY");
|
|
10
|
+
const detectSeparator = (value) => {
|
|
11
|
+
if (value.includes("/"))
|
|
12
|
+
return "/";
|
|
13
|
+
if (value.includes("-"))
|
|
14
|
+
return "-";
|
|
15
|
+
if (value.includes("."))
|
|
16
|
+
return ".";
|
|
17
|
+
return "/";
|
|
18
|
+
};
|
|
19
|
+
const parseParts = (value) => value
|
|
20
|
+
.trim()
|
|
21
|
+
.split(/[^0-9]+/g)
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.map((part) => Number.parseInt(part, 10))
|
|
24
|
+
.filter((part) => Number.isFinite(part));
|
|
25
|
+
const parseWithFormat = (value, format) => {
|
|
26
|
+
const fmt = normalizeFormat(format);
|
|
27
|
+
const sep = detectSeparator(fmt);
|
|
28
|
+
const fmtParts = fmt.split(sep);
|
|
29
|
+
const values = parseParts(value);
|
|
30
|
+
if (fmtParts.length !== 3 || values.length < 3)
|
|
31
|
+
return null;
|
|
32
|
+
let day = 1;
|
|
33
|
+
let month = 1;
|
|
34
|
+
let year = 1970;
|
|
35
|
+
for (let i = 0; i < fmtParts.length; i++) {
|
|
36
|
+
const token = fmtParts[i];
|
|
37
|
+
const parsed = values[i];
|
|
38
|
+
if (!Number.isFinite(parsed))
|
|
39
|
+
return null;
|
|
40
|
+
if (token === "DD")
|
|
41
|
+
day = parsed;
|
|
42
|
+
if (token === "MM")
|
|
43
|
+
month = parsed;
|
|
44
|
+
if (token === "YYYY")
|
|
45
|
+
year = parsed;
|
|
46
|
+
}
|
|
47
|
+
if (year < 100 && year >= 0)
|
|
48
|
+
year += 2000;
|
|
49
|
+
if (month < 1 || month > 12)
|
|
50
|
+
return null;
|
|
51
|
+
if (day < 1 || day > 31)
|
|
52
|
+
return null;
|
|
53
|
+
return { day, month, year };
|
|
54
|
+
};
|
|
55
|
+
const parseAuto = (value) => {
|
|
56
|
+
const parts = parseParts(value);
|
|
57
|
+
if (parts.length < 3)
|
|
58
|
+
return null;
|
|
59
|
+
let day = parts[0];
|
|
60
|
+
let month = parts[1];
|
|
61
|
+
let year = parts[2];
|
|
62
|
+
if (String(parts[0]).length === 4) {
|
|
63
|
+
year = parts[0];
|
|
64
|
+
month = parts[1];
|
|
65
|
+
day = parts[2];
|
|
66
|
+
}
|
|
67
|
+
else if (parts[0] <= 12 && parts[1] > 12) {
|
|
68
|
+
month = parts[0];
|
|
69
|
+
day = parts[1];
|
|
70
|
+
}
|
|
71
|
+
if (year < 100 && year >= 0)
|
|
72
|
+
year += 2000;
|
|
73
|
+
if (month < 1 || month > 12)
|
|
74
|
+
return null;
|
|
75
|
+
if (day < 1 || day > 31)
|
|
76
|
+
return null;
|
|
77
|
+
return { day, month, year };
|
|
78
|
+
};
|
|
79
|
+
const formatParsedDate = (parsed, format) => {
|
|
80
|
+
const fmt = normalizeFormat(String(format || "DD/MM/YYYY"));
|
|
81
|
+
return fmt
|
|
82
|
+
.replace(/DD/g, pad2(parsed.day))
|
|
83
|
+
.replace(/MM/g, pad2(parsed.month))
|
|
84
|
+
.replace(/YYYY/g, pad4(parsed.year));
|
|
85
|
+
};
|
|
86
|
+
export class DateHelper {
|
|
87
|
+
static convert(value, inputFormat = "DD/MM/YYYY", outputFormat = "DD/MM/YYYY") {
|
|
88
|
+
const parsed = parseWithFormat(value, String(inputFormat)) || parseAuto(value);
|
|
89
|
+
if (!parsed)
|
|
90
|
+
return String(value || "").trim();
|
|
91
|
+
return formatParsedDate(parsed, outputFormat);
|
|
92
|
+
}
|
|
93
|
+
static changeSeparator(value, separator) {
|
|
94
|
+
return String(value || "").replace(/[\/\-.]/g, separator);
|
|
95
|
+
}
|
|
96
|
+
static toISO(value, inputFormat) {
|
|
97
|
+
const parsed = (inputFormat ? parseWithFormat(value, String(inputFormat)) : null) ||
|
|
98
|
+
parseAuto(value);
|
|
99
|
+
if (!parsed)
|
|
100
|
+
return String(value || "").trim();
|
|
101
|
+
return `${pad4(parsed.year)}-${pad2(parsed.month)}-${pad2(parsed.day)}`;
|
|
102
|
+
}
|
|
103
|
+
static detectFormat(value) {
|
|
104
|
+
const trimmed = String(value || "").trim();
|
|
105
|
+
if (!trimmed)
|
|
106
|
+
return "DD/MM/YYYY";
|
|
107
|
+
if (/^\d{4}[\/\-.]\d{1,2}[\/\-.]\d{1,2}$/.test(trimmed)) {
|
|
108
|
+
return "YYYY-MM-DD";
|
|
109
|
+
}
|
|
110
|
+
const parts = parseParts(trimmed);
|
|
111
|
+
if (parts.length >= 3) {
|
|
112
|
+
const [a, b] = parts;
|
|
113
|
+
if (a > 12)
|
|
114
|
+
return "DD/MM/YYYY";
|
|
115
|
+
if (b > 12)
|
|
116
|
+
return "MM/DD/YYYY";
|
|
117
|
+
}
|
|
118
|
+
return "DD/MM/YYYY";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DateHelper } from "./DateHelper.js";
|
|
2
|
+
const normalize = (value) => String(value || "")
|
|
3
|
+
.trim()
|
|
4
|
+
.replace(/\s+/g, "")
|
|
5
|
+
.toLowerCase();
|
|
6
|
+
const normalizeDateLike = (value) => String(value || "").replace(/[^0-9]/g, "");
|
|
7
|
+
export class DateValidator {
|
|
8
|
+
static async validateFilled(locator, expectedValue, _context) {
|
|
9
|
+
try {
|
|
10
|
+
const expected = String(expectedValue || "").trim();
|
|
11
|
+
if (!expected)
|
|
12
|
+
return false;
|
|
13
|
+
let actual = "";
|
|
14
|
+
try {
|
|
15
|
+
actual = await locator.inputValue();
|
|
16
|
+
}
|
|
17
|
+
catch { }
|
|
18
|
+
if (!actual) {
|
|
19
|
+
try {
|
|
20
|
+
actual = (await locator.textContent()) || "";
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
}
|
|
24
|
+
if (!actual) {
|
|
25
|
+
try {
|
|
26
|
+
actual = (await locator.getAttribute("value")) || "";
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
}
|
|
30
|
+
const expectedNorm = normalize(expected);
|
|
31
|
+
const actualNorm = normalize(actual);
|
|
32
|
+
if (expectedNorm && actualNorm && expectedNorm === actualNorm) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
const expectedDigits = normalizeDateLike(expected);
|
|
36
|
+
const actualDigits = normalizeDateLike(actual);
|
|
37
|
+
if (expectedDigits && actualDigits && expectedDigits === actualDigits) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const expectedIso = DateHelper.toISO(expected);
|
|
41
|
+
const actualIso = DateHelper.toISO(actual);
|
|
42
|
+
if (expectedIso && actualIso && expectedIso === actualIso) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility class to generate documents and IDs used in tests.
|
|
3
|
+
*/
|
|
4
|
+
export declare class DocumentGenerator {
|
|
5
|
+
private static readonly CPF_INITIAL_DIGITS;
|
|
6
|
+
private static readonly CPF_RANDOM_MULTIPLIER;
|
|
7
|
+
private static readonly CPF_MODULO_DIVISOR;
|
|
8
|
+
private static readonly CNPJ_RANDOM_MULTIPLIER;
|
|
9
|
+
private static readonly CNPJ_FIXED_PART;
|
|
10
|
+
private static readonly CNPJ_FIRST_MULTIPLIERS;
|
|
11
|
+
private static readonly CNPJ_SECOND_MULTIPLIERS;
|
|
12
|
+
private static readonly HEX_CHARS;
|
|
13
|
+
private static readonly ALPHANUMERIC_CHARS;
|
|
14
|
+
private static readonly EXTERNAL_ID_PART1_LENGTH;
|
|
15
|
+
private static readonly EXTERNAL_ID_PART2_LENGTH;
|
|
16
|
+
private static readonly EXTERNAL_ID_PART3_PREFIX_LENGTH;
|
|
17
|
+
private static readonly SERVICENOW_PART1_LENGTH;
|
|
18
|
+
private static readonly SERVICENOW_PART2_LENGTH;
|
|
19
|
+
/** Generate a valid CPF (returns digits only) and writes to DataStore key 'CPF' */
|
|
20
|
+
static generateCPF(): string;
|
|
21
|
+
private static computeCpfCheckDigits;
|
|
22
|
+
/** Generate a valid CNPJ (returns digits only) and writes to DataStore key 'CNPJ' */
|
|
23
|
+
static generateCNPJ(): string;
|
|
24
|
+
private static computeCheckDigit;
|
|
25
|
+
/** Generate a random alphanumeric string based on Node UUID (no hyphens) */
|
|
26
|
+
static generateRandomAlphanumericUUID(length: number): string;
|
|
27
|
+
/** Generate complex external id similar to example */
|
|
28
|
+
static generateComplexExternalId(): string;
|
|
29
|
+
static generateRandomAlphanumeric(length: number): string;
|
|
30
|
+
static generateRandomNumeric(length: number): string;
|
|
31
|
+
static generateServiceNowTaskId(): string;
|
|
32
|
+
/** Generate a random email and store in DataStore 'EMAIL' */
|
|
33
|
+
static generateRandomEmail(): string;
|
|
34
|
+
}
|
|
35
|
+
export default DocumentGenerator;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { DataStore } from '@silasfmartins/testhub';
|
|
3
|
+
/**
|
|
4
|
+
* Utility class to generate documents and IDs used in tests.
|
|
5
|
+
*/
|
|
6
|
+
export class DocumentGenerator {
|
|
7
|
+
// CPF constants
|
|
8
|
+
static CPF_INITIAL_DIGITS = 9;
|
|
9
|
+
static CPF_RANDOM_MULTIPLIER = 10;
|
|
10
|
+
static CPF_MODULO_DIVISOR = 11;
|
|
11
|
+
// CNPJ constants
|
|
12
|
+
static CNPJ_RANDOM_MULTIPLIER = 10;
|
|
13
|
+
static CNPJ_FIXED_PART = [0, 0, 0, 1];
|
|
14
|
+
static CNPJ_FIRST_MULTIPLIERS = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
15
|
+
static CNPJ_SECOND_MULTIPLIERS = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
16
|
+
// Other generators
|
|
17
|
+
static HEX_CHARS = 'abcdef0123456789';
|
|
18
|
+
static ALPHANUMERIC_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
19
|
+
// ServiceNow / external id lengths
|
|
20
|
+
static EXTERNAL_ID_PART1_LENGTH = 32;
|
|
21
|
+
static EXTERNAL_ID_PART2_LENGTH = 32;
|
|
22
|
+
static EXTERNAL_ID_PART3_PREFIX_LENGTH = 30;
|
|
23
|
+
static SERVICENOW_PART1_LENGTH = 32;
|
|
24
|
+
static SERVICENOW_PART2_LENGTH = 31;
|
|
25
|
+
/** Generate a valid CPF (returns digits only) and writes to DataStore key 'CPF' */
|
|
26
|
+
static generateCPF() {
|
|
27
|
+
const initials = [];
|
|
28
|
+
for (let i = 0; i < this.CPF_INITIAL_DIGITS; i++) {
|
|
29
|
+
initials.push(Math.floor(Math.random() * this.CPF_RANDOM_MULTIPLIER));
|
|
30
|
+
}
|
|
31
|
+
const [d1, d2] = this.computeCpfCheckDigits(initials);
|
|
32
|
+
const cpf = [...initials, d1, d2].join('');
|
|
33
|
+
try {
|
|
34
|
+
DataStore.set('CPF', cpf);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// ignore if DataStore not available in environment
|
|
38
|
+
}
|
|
39
|
+
return cpf;
|
|
40
|
+
}
|
|
41
|
+
static computeCpfCheckDigits(digits) {
|
|
42
|
+
const firstMultipliers = [10, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
43
|
+
const secondMultipliers = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
44
|
+
const sum1 = digits.reduce((s, d, i) => s + d * firstMultipliers[i], 0);
|
|
45
|
+
const r1 = sum1 % this.CPF_MODULO_DIVISOR;
|
|
46
|
+
const dig1 = r1 < 2 ? 0 : this.CPF_MODULO_DIVISOR - r1;
|
|
47
|
+
const digitsWithFirst = [...digits, dig1];
|
|
48
|
+
const sum2 = digitsWithFirst.reduce((s, d, i) => s + d * secondMultipliers[i], 0);
|
|
49
|
+
const r2 = sum2 % this.CPF_MODULO_DIVISOR;
|
|
50
|
+
const dig2 = r2 < 2 ? 0 : this.CPF_MODULO_DIVISOR - r2;
|
|
51
|
+
return [dig1, dig2];
|
|
52
|
+
}
|
|
53
|
+
/** Generate a valid CNPJ (returns digits only) and writes to DataStore key 'CNPJ' */
|
|
54
|
+
static generateCNPJ() {
|
|
55
|
+
// generate first 8 random digits
|
|
56
|
+
const first8 = [];
|
|
57
|
+
for (let i = 0; i < 8; i++) {
|
|
58
|
+
first8.push(Math.floor(Math.random() * this.CNPJ_RANDOM_MULTIPLIER));
|
|
59
|
+
}
|
|
60
|
+
const base = [...first8, ...this.CNPJ_FIXED_PART]; // 12 digits
|
|
61
|
+
const dig1 = this.computeCheckDigit(base, this.CNPJ_FIRST_MULTIPLIERS);
|
|
62
|
+
const dig2 = this.computeCheckDigit([...base, dig1], this.CNPJ_SECOND_MULTIPLIERS);
|
|
63
|
+
const cnpj = [...base, dig1, dig2].join('');
|
|
64
|
+
try {
|
|
65
|
+
DataStore.set('CNPJ', cnpj);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// ignore
|
|
69
|
+
}
|
|
70
|
+
return cnpj;
|
|
71
|
+
}
|
|
72
|
+
static computeCheckDigit(digits, multipliers) {
|
|
73
|
+
const sum = digits.reduce((s, d, i) => s + d * multipliers[i], 0);
|
|
74
|
+
const r = sum % 11;
|
|
75
|
+
return r < 2 ? 0 : 11 - r;
|
|
76
|
+
}
|
|
77
|
+
/** Generate a random alphanumeric string based on Node UUID (no hyphens) */
|
|
78
|
+
static generateRandomAlphanumericUUID(length) {
|
|
79
|
+
let result = randomUUID().replace(/-/g, '');
|
|
80
|
+
while (result.length < length) {
|
|
81
|
+
result += randomUUID().replace(/-/g, '');
|
|
82
|
+
}
|
|
83
|
+
return result.substring(0, length);
|
|
84
|
+
}
|
|
85
|
+
/** Generate complex external id similar to example */
|
|
86
|
+
static generateComplexExternalId() {
|
|
87
|
+
const randomHex = (len) => Array.from({ length: len }, () => this.HEX_CHARS[Math.floor(Math.random() * this.HEX_CHARS.length)]).join('');
|
|
88
|
+
const part1 = randomHex(this.EXTERNAL_ID_PART1_LENGTH);
|
|
89
|
+
const part2 = randomHex(this.EXTERNAL_ID_PART2_LENGTH);
|
|
90
|
+
const part3 = '0x' +
|
|
91
|
+
randomHex(this.EXTERNAL_ID_PART3_PREFIX_LENGTH) +
|
|
92
|
+
String.fromCharCode(97 + Math.floor(Math.random() * 26));
|
|
93
|
+
return `${part1}-${part2}${part3}`;
|
|
94
|
+
}
|
|
95
|
+
static generateRandomAlphanumeric(length) {
|
|
96
|
+
let out = '';
|
|
97
|
+
for (let i = 0; i < length; i++) {
|
|
98
|
+
out += this.ALPHANUMERIC_CHARS.charAt(Math.floor(Math.random() * this.ALPHANUMERIC_CHARS.length));
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
static generateRandomNumeric(length) {
|
|
103
|
+
const digits = '0123456789';
|
|
104
|
+
let out = '';
|
|
105
|
+
for (let i = 0; i < length; i++) {
|
|
106
|
+
out += digits.charAt(Math.floor(Math.random() * digits.length));
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
static generateServiceNowTaskId() {
|
|
111
|
+
const randomHex = (len) => Array.from({ length: len }, () => this.HEX_CHARS[Math.floor(Math.random() * this.HEX_CHARS.length)]).join('');
|
|
112
|
+
const part1 = randomHex(this.SERVICENOW_PART1_LENGTH);
|
|
113
|
+
const part2 = randomHex(this.SERVICENOW_PART2_LENGTH);
|
|
114
|
+
return `${part1}x${part2}`;
|
|
115
|
+
}
|
|
116
|
+
/** Generate a random email and store in DataStore 'EMAIL' */
|
|
117
|
+
static generateRandomEmail() {
|
|
118
|
+
const randomString = Math.random().toString(36).substring(2, 10);
|
|
119
|
+
const email = `test_${randomString}@email.com`;
|
|
120
|
+
try {
|
|
121
|
+
DataStore.set('EMAIL', email);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// ignore
|
|
125
|
+
}
|
|
126
|
+
return email;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export default DocumentGenerator;
|