stigmergy 1.0.89 → 1.0.93
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/README.md +202 -189
- package/bin/stigmergy +12 -0
- package/bin/stigmergy.cmd +5 -0
- package/docs/CONFLICT_PREVENTION.md +150 -0
- package/package.json +12 -6
- package/scripts/post-deployment-config.js +289 -0
- package/scripts/preinstall-check.js +111 -0
- package/scripts/safe-install.js +139 -0
- package/src/main.js +963 -892
- package/src/main_english.js +179 -35
- package/test/comprehensive-execution-test.js +428 -0
- package/test/conflict-prevention-test.js +95 -0
- package/test/deploy-hooks-test.js +250 -0
- package/test/error-handling-test.js +341 -0
- package/test/final-deploy-test.js +221 -0
- package/test/final-install-test.js +226 -0
- package/test/iflow-integration-test.js +292 -0
- package/test/improved-install-test.js +362 -0
- package/test/install-command-test.js +370 -0
- package/test/plugin-deployment-test.js +316 -0
- package/test/postinstall-test.js +269 -0
- package/test/simple-iflow-hook-test.js +137 -0
- package/test/tdd-deploy-fix-test.js +324 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Final Test for deployHooks Implementation
|
|
5
|
+
* This test verifies that the deployHooks function now properly executes installation scripts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs').promises;
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
class FinalDeployTester {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.testResults = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Test 1: Verify deployHooks function can be imported and has the new functionality
|
|
18
|
+
async testDeployHooksFunctionality() {
|
|
19
|
+
console.log('[TEST 1] Verifying deployHooks function has new functionality...');
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
// Import the StigmergyInstaller class
|
|
23
|
+
const { StigmergyInstaller } = require('../src/main_english.js');
|
|
24
|
+
const installer = new StigmergyInstaller();
|
|
25
|
+
|
|
26
|
+
// Check if deployHooks method exists
|
|
27
|
+
if (typeof installer.deployHooks !== 'function') {
|
|
28
|
+
console.log(' ✗ deployHooks method not found');
|
|
29
|
+
this.testResults.push({
|
|
30
|
+
name: 'DeployHooks Functionality',
|
|
31
|
+
passed: false,
|
|
32
|
+
details: 'deployHooks method not found'
|
|
33
|
+
});
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check if the method includes the new configuration execution code
|
|
38
|
+
const methodCode = installer.deployHooks.toString();
|
|
39
|
+
const hasNewFunctionality = methodCode.includes('PostDeploymentConfigurer') &&
|
|
40
|
+
methodCode.includes('configureTool');
|
|
41
|
+
|
|
42
|
+
if (hasNewFunctionality) {
|
|
43
|
+
console.log(' ✓ deployHooks includes new configuration execution functionality');
|
|
44
|
+
} else {
|
|
45
|
+
console.log(' ✗ deployHooks missing new configuration execution functionality');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.testResults.push({
|
|
49
|
+
name: 'DeployHooks Functionality',
|
|
50
|
+
passed: hasNewFunctionality,
|
|
51
|
+
details: hasNewFunctionality ?
|
|
52
|
+
'Includes PostDeploymentConfigurer and configureTool execution' :
|
|
53
|
+
'Missing new configuration execution functionality'
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return hasNewFunctionality;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.log(` ✗ Failed to test deployHooks functionality: ${error.message}`);
|
|
59
|
+
this.testResults.push({
|
|
60
|
+
name: 'DeployHooks Functionality',
|
|
61
|
+
passed: false,
|
|
62
|
+
details: `Failed to test: ${error.message}`
|
|
63
|
+
});
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Test 2: Verify post-deployment config script integration
|
|
69
|
+
async testPostDeploymentConfigIntegration() {
|
|
70
|
+
console.log('\n[TEST 2] Verifying post-deployment config integration...');
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
// Check if the post-deployment config script can be imported
|
|
74
|
+
const { PostDeploymentConfigurer } = require('../scripts/post-deployment-config.js');
|
|
75
|
+
|
|
76
|
+
// Check if the class exists
|
|
77
|
+
if (typeof PostDeploymentConfigurer === 'function') {
|
|
78
|
+
console.log(' ✓ PostDeploymentConfigurer class exists');
|
|
79
|
+
|
|
80
|
+
// Try to instantiate it
|
|
81
|
+
const configurer = new PostDeploymentConfigurer();
|
|
82
|
+
|
|
83
|
+
// Check if required methods exist
|
|
84
|
+
const hasRequiredMethods = typeof configurer.configureTool === 'function' &&
|
|
85
|
+
typeof configurer.checkInstallScript === 'function';
|
|
86
|
+
|
|
87
|
+
if (hasRequiredMethods) {
|
|
88
|
+
console.log(' ✓ PostDeploymentConfigurer has required methods');
|
|
89
|
+
} else {
|
|
90
|
+
console.log(' ✗ PostDeploymentConfigurer missing required methods');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.testResults.push({
|
|
94
|
+
name: 'Post-Deployment Config Integration',
|
|
95
|
+
passed: hasRequiredMethods,
|
|
96
|
+
details: hasRequiredMethods ?
|
|
97
|
+
'PostDeploymentConfigurer class and methods exist' :
|
|
98
|
+
'Missing required methods in PostDeploymentConfigurer'
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return hasRequiredMethods;
|
|
102
|
+
} else {
|
|
103
|
+
console.log(' ✗ PostDeploymentConfigurer class not found');
|
|
104
|
+
this.testResults.push({
|
|
105
|
+
name: 'Post-Deployment Config Integration',
|
|
106
|
+
passed: false,
|
|
107
|
+
details: 'PostDeploymentConfigurer class not found'
|
|
108
|
+
});
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.log(` ✗ Failed to test post-deployment config integration: ${error.message}`);
|
|
113
|
+
this.testResults.push({
|
|
114
|
+
name: 'Post-Deployment Config Integration',
|
|
115
|
+
passed: false,
|
|
116
|
+
details: `Failed to test: ${error.message}`
|
|
117
|
+
});
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Test 3: Verify installation script execution would work
|
|
123
|
+
async testInstallationScriptExecutionFeasibility() {
|
|
124
|
+
console.log('\n[TEST 3] Verifying installation script execution feasibility...');
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// Check if installation scripts exist in assets
|
|
128
|
+
const stigmergyAssetsDir = path.join(os.homedir(), '.stigmergy', 'assets', 'adapters');
|
|
129
|
+
|
|
130
|
+
// Check a few key tools
|
|
131
|
+
const toolsToCheck = ['iflow', 'claude', 'qoder'];
|
|
132
|
+
let scriptsFound = 0;
|
|
133
|
+
|
|
134
|
+
for (const tool of toolsToCheck) {
|
|
135
|
+
const installScriptPath = path.join(stigmergyAssetsDir, tool, `install_${tool}_integration.py`);
|
|
136
|
+
try {
|
|
137
|
+
await fs.access(installScriptPath);
|
|
138
|
+
console.log(` ✓ ${tool} installation script found: ${installScriptPath}`);
|
|
139
|
+
scriptsFound++;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.log(` ✗ ${tool} installation script not found: ${installScriptPath}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const allScriptsFound = scriptsFound === toolsToCheck.length;
|
|
146
|
+
|
|
147
|
+
this.testResults.push({
|
|
148
|
+
name: 'Installation Script Execution Feasibility',
|
|
149
|
+
passed: allScriptsFound,
|
|
150
|
+
details: `Found ${scriptsFound}/${toolsToCheck.length} installation scripts`
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return allScriptsFound;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.log(` ✗ Failed to check installation script feasibility: ${error.message}`);
|
|
156
|
+
this.testResults.push({
|
|
157
|
+
name: 'Installation Script Execution Feasibility',
|
|
158
|
+
passed: false,
|
|
159
|
+
details: `Failed to check: ${error.message}`
|
|
160
|
+
});
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Run all tests
|
|
166
|
+
async runAllTests() {
|
|
167
|
+
console.log('Final Test for deployHooks Implementation');
|
|
168
|
+
console.log('='.repeat(50));
|
|
169
|
+
|
|
170
|
+
await this.testDeployHooksFunctionality();
|
|
171
|
+
await this.testPostDeploymentConfigIntegration();
|
|
172
|
+
await this.testInstallationScriptExecutionFeasibility();
|
|
173
|
+
|
|
174
|
+
// Summary
|
|
175
|
+
console.log('\n' + '='.repeat(50));
|
|
176
|
+
console.log('Final Implementation Test Summary:');
|
|
177
|
+
console.log('='.repeat(50));
|
|
178
|
+
|
|
179
|
+
let passedTests = 0;
|
|
180
|
+
this.testResults.forEach(result => {
|
|
181
|
+
console.log(`${result.name}: ${result.passed ? '✓ PASS' : '✗ FAIL'} - ${result.details}`);
|
|
182
|
+
if (result.passed) passedTests++;
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
console.log(`\nOverall Result: ${passedTests}/${this.testResults.length} tests passed`);
|
|
186
|
+
|
|
187
|
+
if (passedTests === this.testResults.length) {
|
|
188
|
+
console.log('✓ All tests passed! deployHooks implementation is complete.');
|
|
189
|
+
} else if (passedTests > 0) {
|
|
190
|
+
console.log('⚠ Some tests failed. deployHooks implementation may need adjustments.');
|
|
191
|
+
} else {
|
|
192
|
+
console.log('✗ All tests failed. deployHooks implementation is not complete.');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
totalTests: this.testResults.length,
|
|
197
|
+
passedTests: passedTests,
|
|
198
|
+
results: this.testResults
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Run the tests
|
|
204
|
+
async function runFinalDeployTests() {
|
|
205
|
+
const tester = new FinalDeployTester();
|
|
206
|
+
const results = await tester.runAllTests();
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Export for use in other modules
|
|
211
|
+
module.exports = { FinalDeployTester };
|
|
212
|
+
|
|
213
|
+
// Run if called directly
|
|
214
|
+
if (require.main === module) {
|
|
215
|
+
runFinalDeployTests().then(results => {
|
|
216
|
+
process.exit(results.passedTests === results.totalTests ? 0 : 1);
|
|
217
|
+
}).catch(error => {
|
|
218
|
+
console.error('[Test Failed]:', error.message);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Final Test for Improved Installation Implementation
|
|
5
|
+
* This test verifies that the improved installation implementation works correctly
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs').promises;
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
class FinalInstallTest {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.testResults = [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Test 1: Verify the improved installation code was implemented correctly
|
|
17
|
+
async testImprovedInstallationCode() {
|
|
18
|
+
console.log('[TEST 1] Verifying improved installation code implementation...');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Read the main_english.js file
|
|
22
|
+
const mainFilePath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
23
|
+
const mainContent = await fs.readFile(mainFilePath, 'utf8');
|
|
24
|
+
|
|
25
|
+
// Check for key improvements
|
|
26
|
+
const hasShellTrue = mainContent.includes('shell: true');
|
|
27
|
+
const hasFallbackLogic = mainContent.includes('if (result.status !== 0 && result.status !== null)');
|
|
28
|
+
const hasDebugLogging = mainContent.includes('[DEBUG] Installing');
|
|
29
|
+
const hasErrorDetails = mainContent.includes('Installation error:');
|
|
30
|
+
|
|
31
|
+
console.log(` shell: true option: ${hasShellTrue}`);
|
|
32
|
+
console.log(` Fallback logic: ${hasFallbackLogic}`);
|
|
33
|
+
console.log(` Debug logging: ${hasDebugLogging}`);
|
|
34
|
+
console.log(` Error details: ${hasErrorDetails}`);
|
|
35
|
+
|
|
36
|
+
const allImprovementsImplemented = hasShellTrue && hasFallbackLogic && hasDebugLogging && hasErrorDetails;
|
|
37
|
+
|
|
38
|
+
this.testResults.push({
|
|
39
|
+
name: 'Improved Installation Code',
|
|
40
|
+
passed: allImprovementsImplemented,
|
|
41
|
+
details: `shell:true=${hasShellTrue}, fallback=${hasFallbackLogic}, debug=${hasDebugLogging}, error_details=${hasErrorDetails}`
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return allImprovementsImplemented;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.log(` ✗ Failed to check improved installation code: ${error.message}`);
|
|
47
|
+
this.testResults.push({
|
|
48
|
+
name: 'Improved Installation Code',
|
|
49
|
+
passed: false,
|
|
50
|
+
details: `Failed to check: ${error.message}`
|
|
51
|
+
});
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Test 2: Verify installation command format is correct
|
|
57
|
+
async testInstallationCommandFormat() {
|
|
58
|
+
console.log('\n[TEST 2] Verifying installation command format...');
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
// Read the main_english.js file
|
|
62
|
+
const mainFilePath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
63
|
+
const mainContent = await fs.readFile(mainFilePath, 'utf8');
|
|
64
|
+
|
|
65
|
+
// Check for Qoder CLI installation command
|
|
66
|
+
const hasQoderInstall = mainContent.includes('@qoder-ai/qodercli');
|
|
67
|
+
const hasNpmInstallFormat = mainContent.includes('npm install -g');
|
|
68
|
+
|
|
69
|
+
console.log(` Qoder CLI package reference: ${hasQoderInstall}`);
|
|
70
|
+
console.log(` npm install format: ${hasNpmInstallFormat}`);
|
|
71
|
+
|
|
72
|
+
const correctFormat = hasQoderInstall && hasNpmInstallFormat;
|
|
73
|
+
|
|
74
|
+
this.testResults.push({
|
|
75
|
+
name: 'Installation Command Format',
|
|
76
|
+
passed: correctFormat,
|
|
77
|
+
details: `Qoder package=${hasQoderInstall}, npm install format=${hasNpmInstallFormat}`
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return correctFormat;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.log(` ✗ Failed to check installation command format: ${error.message}`);
|
|
83
|
+
this.testResults.push({
|
|
84
|
+
name: 'Installation Command Format',
|
|
85
|
+
passed: false,
|
|
86
|
+
details: `Failed to check: ${error.message}`
|
|
87
|
+
});
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Test 3: Verify error handling improvements
|
|
93
|
+
async testErrorHandlingImprovements() {
|
|
94
|
+
console.log('\n[TEST 3] Verifying error handling improvements...');
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
// Read the main_english.js file
|
|
98
|
+
const mainFilePath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
99
|
+
const mainContent = await fs.readFile(mainFilePath, 'utf8');
|
|
100
|
+
|
|
101
|
+
// Check for improved error handling
|
|
102
|
+
const hasTryCatch = mainContent.includes('try {') && mainContent.includes('catch');
|
|
103
|
+
const hasSpecificErrorMessages = mainContent.includes('Failed to install') && mainContent.includes('Please run manually');
|
|
104
|
+
const hasExitCodeReporting = mainContent.includes('exit code');
|
|
105
|
+
|
|
106
|
+
console.log(` Try-catch blocks: ${hasTryCatch}`);
|
|
107
|
+
console.log(` Specific error messages: ${hasSpecificErrorMessages}`);
|
|
108
|
+
console.log(` Exit code reporting: ${hasExitCodeReporting}`);
|
|
109
|
+
|
|
110
|
+
const goodErrorHandling = hasTryCatch && hasSpecificErrorMessages && hasExitCodeReporting;
|
|
111
|
+
|
|
112
|
+
this.testResults.push({
|
|
113
|
+
name: 'Error Handling Improvements',
|
|
114
|
+
passed: goodErrorHandling,
|
|
115
|
+
details: `try-catch=${hasTryCatch}, specific_errors=${hasSpecificErrorMessages}, exit_code=${hasExitCodeReporting}`
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return goodErrorHandling;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.log(` ✗ Failed to check error handling improvements: ${error.message}`);
|
|
121
|
+
this.testResults.push({
|
|
122
|
+
name: 'Error Handling Improvements',
|
|
123
|
+
passed: false,
|
|
124
|
+
details: `Failed to check: ${error.message}`
|
|
125
|
+
});
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Test 4: Verify timeout and environment settings
|
|
131
|
+
async testTimeoutAndEnvironment() {
|
|
132
|
+
console.log('\n[TEST 4] Verifying timeout and environment settings...');
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// Read the main_english.js file
|
|
136
|
+
const mainFilePath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
137
|
+
const mainContent = await fs.readFile(mainFilePath, 'utf8');
|
|
138
|
+
|
|
139
|
+
// Check for timeout and environment settings
|
|
140
|
+
const hasTimeout = mainContent.includes('timeout: 300000');
|
|
141
|
+
const hasEnvironment = mainContent.includes('env: process.env');
|
|
142
|
+
const hasStdioSetting = mainContent.includes('stdio:');
|
|
143
|
+
|
|
144
|
+
console.log(` 5-minute timeout: ${hasTimeout}`);
|
|
145
|
+
console.log(` Environment passing: ${hasEnvironment}`);
|
|
146
|
+
console.log(` Stdio setting: ${hasStdioSetting}`);
|
|
147
|
+
|
|
148
|
+
const correctSettings = hasTimeout && hasEnvironment && hasStdioSetting;
|
|
149
|
+
|
|
150
|
+
this.testResults.push({
|
|
151
|
+
name: 'Timeout and Environment Settings',
|
|
152
|
+
passed: correctSettings,
|
|
153
|
+
details: `timeout=${hasTimeout}, environment=${hasEnvironment}, stdio=${hasStdioSetting}`
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return correctSettings;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.log(` ✗ Failed to check timeout and environment settings: ${error.message}`);
|
|
159
|
+
this.testResults.push({
|
|
160
|
+
name: 'Timeout and Environment Settings',
|
|
161
|
+
passed: false,
|
|
162
|
+
details: `Failed to check: ${error.message}`
|
|
163
|
+
});
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Run all tests
|
|
169
|
+
async runAllTests() {
|
|
170
|
+
console.log('Final Test for Improved Installation Implementation');
|
|
171
|
+
console.log('='.repeat(50));
|
|
172
|
+
|
|
173
|
+
await this.testImprovedInstallationCode();
|
|
174
|
+
await this.testInstallationCommandFormat();
|
|
175
|
+
await this.testErrorHandlingImprovements();
|
|
176
|
+
await this.testTimeoutAndEnvironment();
|
|
177
|
+
|
|
178
|
+
// Summary
|
|
179
|
+
console.log('\n' + '='.repeat(50));
|
|
180
|
+
console.log('Final Installation Implementation Test Summary:');
|
|
181
|
+
console.log('='.repeat(50));
|
|
182
|
+
|
|
183
|
+
let passedTests = 0;
|
|
184
|
+
this.testResults.forEach(result => {
|
|
185
|
+
console.log(`${result.name}: ${result.passed ? '✓ PASS' : '✗ FAIL'} - ${result.details}`);
|
|
186
|
+
if (result.passed) passedTests++;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log(`\nOverall Result: ${passedTests}/${this.testResults.length} tests passed`);
|
|
190
|
+
|
|
191
|
+
if (passedTests === this.testResults.length) {
|
|
192
|
+
console.log('✓ All final implementation tests passed!');
|
|
193
|
+
console.log('✓ Installation implementation has been successfully improved!');
|
|
194
|
+
} else if (passedTests > 0) {
|
|
195
|
+
console.log('⚠ Some final implementation tests passed.');
|
|
196
|
+
} else {
|
|
197
|
+
console.log('✗ All final implementation tests failed.');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
totalTests: this.testResults.length,
|
|
202
|
+
passedTests: passedTests,
|
|
203
|
+
results: this.testResults
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Run the tests
|
|
209
|
+
async function runFinalInstallTests() {
|
|
210
|
+
const tester = new FinalInstallTest();
|
|
211
|
+
const results = await tester.runAllTests();
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Export for use in other modules
|
|
216
|
+
module.exports = { FinalInstallTest };
|
|
217
|
+
|
|
218
|
+
// Run if called directly
|
|
219
|
+
if (require.main === module) {
|
|
220
|
+
runFinalInstallTests().then(results => {
|
|
221
|
+
process.exit(results.passedTests === results.totalTests ? 0 : 1);
|
|
222
|
+
}).catch(error => {
|
|
223
|
+
console.error('[Test Failed]:', error.message);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
});
|
|
226
|
+
}
|