Some checks failed
		
		
	
	HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
				
			Security Monitoring & Compliance / Secrets & Credential Scan (push) Has been cancelled
				
			Security Monitoring & Compliance / WordPress Security Analysis (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
				
			Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Has been cancelled
				
			Security Monitoring & Compliance / Static Code Security Analysis (push) Has been cancelled
				
			Security Monitoring & Compliance / Security Compliance Validation (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
				
			HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
				
			Security Monitoring & Compliance / Security Summary Report (push) Has been cancelled
				
			Security Monitoring & Compliance / Security Team Notification (push) Has been cancelled
				
			- Deploy 6 simultaneous WordPress specialized agents using sequential thinking and Zen MCP - Resolve all critical issues: permissions, jQuery dependencies, CDN mapping, security vulnerabilities - Implement bulletproof jQuery loading system with WordPress hook timing fixes - Create professional MapGeo Safety system with CDN health monitoring and fallback UI - Fix privilege escalation vulnerability with capability-based authorization - Add complete announcement admin system with modal forms and AJAX handling - Enhance import/export functionality (54 trainers successfully exported) - Achieve 100% operational master trainer functionality verified via MCP Playwright E2E testing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			284 lines
		
	
	
		
			No EOL
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			284 lines
		
	
	
		
			No EOL
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/env node
 | |
| 
 | |
| /**
 | |
|  * Simple Build System Test
 | |
|  * 
 | |
|  * Basic validation that the build system is working correctly
 | |
|  * without complex Playwright dependencies
 | |
|  */
 | |
| 
 | |
| const fs = require('fs').promises;
 | |
| const path = require('path');
 | |
| const { execSync } = require('child_process');
 | |
| 
 | |
| const BUILD_CONFIG = {
 | |
|     PROJECT_ROOT: path.resolve(__dirname),
 | |
|     BUILD_OUTPUT: path.resolve(__dirname, 'assets/js/dist'),
 | |
|     WEBPACK_CONFIG: path.resolve(__dirname, 'webpack.config.js'),
 | |
|     MANIFEST_PATH: path.resolve(__dirname, 'assets/js/dist/manifest.json'),
 | |
|     
 | |
|     EXPECTED_BUNDLES: [
 | |
|         'hvac-core.bundle.js',
 | |
|         'hvac-dashboard.bundle.js', 
 | |
|         'hvac-certificates.bundle.js',
 | |
|         'hvac-master.bundle.js',
 | |
|         'hvac-trainer.bundle.js',
 | |
|         'hvac-events.bundle.js',
 | |
|         'hvac-admin.bundle.js',
 | |
|         'hvac-safari-compat.bundle.js'
 | |
|     ]
 | |
| };
 | |
| 
 | |
| class SimpleBuildSystemTest {
 | |
|     
 | |
|     constructor() {
 | |
|         this.results = {
 | |
|             passed: 0,
 | |
|             failed: 0,
 | |
|             tests: []
 | |
|         };
 | |
|     }
 | |
|     
 | |
|     log(message, type = 'info') {
 | |
|         const colors = {
 | |
|             info: '\x1b[37m',    // white
 | |
|             success: '\x1b[32m', // green
 | |
|             error: '\x1b[31m',   // red
 | |
|             warning: '\x1b[33m', // yellow
 | |
|             reset: '\x1b[0m'
 | |
|         };
 | |
|         
 | |
|         console.log(`${colors[type]}${message}${colors.reset}`);
 | |
|     }
 | |
|     
 | |
|     async test(name, testFn) {
 | |
|         try {
 | |
|             this.log(`🧪 Testing: ${name}`, 'info');
 | |
|             await testFn();
 | |
|             this.log(`✅ PASS: ${name}`, 'success');
 | |
|             this.results.passed++;
 | |
|             this.results.tests.push({ name, status: 'pass' });
 | |
|         } catch (error) {
 | |
|             this.log(`❌ FAIL: ${name} - ${error.message}`, 'error');
 | |
|             this.results.failed++;
 | |
|             this.results.tests.push({ name, status: 'fail', error: error.message });
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async testWebpackConfigExists() {
 | |
|         const configExists = await fs.access(BUILD_CONFIG.WEBPACK_CONFIG).then(() => true).catch(() => false);
 | |
|         if (!configExists) {
 | |
|             throw new Error('webpack.config.js not found');
 | |
|         }
 | |
|         
 | |
|         // Test webpack config can be loaded
 | |
|         const config = require(BUILD_CONFIG.WEBPACK_CONFIG);
 | |
|         if (!config.entry || !config.output) {
 | |
|             throw new Error('Invalid webpack configuration');
 | |
|         }
 | |
|         
 | |
|         this.log(`   Entry points: ${Object.keys(config.entry).length}`, 'info');
 | |
|     }
 | |
|     
 | |
|     async testBuildOutputExists() {
 | |
|         const distExists = await fs.access(BUILD_CONFIG.BUILD_OUTPUT).then(() => true).catch(() => false);
 | |
|         if (!distExists) {
 | |
|             throw new Error('Build output directory (assets/js/dist) not found');
 | |
|         }
 | |
|         
 | |
|         const files = await fs.readdir(BUILD_CONFIG.BUILD_OUTPUT);
 | |
|         const bundleFiles = files.filter(f => f.endsWith('.bundle.js'));
 | |
|         
 | |
|         this.log(`   Found ${bundleFiles.length} bundle files`, 'info');
 | |
|         
 | |
|         if (bundleFiles.length === 0) {
 | |
|             throw new Error('No bundle files found in dist directory');
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async testExpectedBundlesExist() {
 | |
|         const files = await fs.readdir(BUILD_CONFIG.BUILD_OUTPUT);
 | |
|         const missing = [];
 | |
|         
 | |
|         for (const expectedBundle of BUILD_CONFIG.EXPECTED_BUNDLES) {
 | |
|             if (!files.includes(expectedBundle)) {
 | |
|                 missing.push(expectedBundle);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         if (missing.length > 0) {
 | |
|             this.log(`   Missing bundles: ${missing.join(', ')}`, 'warning');
 | |
|             throw new Error(`Missing expected bundles: ${missing.join(', ')}`);
 | |
|         }
 | |
|         
 | |
|         this.log(`   All ${BUILD_CONFIG.EXPECTED_BUNDLES.length} expected bundles found`, 'success');
 | |
|     }
 | |
|     
 | |
|     async testBundleSizes() {
 | |
|         const MAX_SIZE_KB = 250;
 | |
|         const oversized = [];
 | |
|         
 | |
|         for (const bundleName of BUILD_CONFIG.EXPECTED_BUNDLES) {
 | |
|             const bundlePath = path.join(BUILD_CONFIG.BUILD_OUTPUT, bundleName);
 | |
|             try {
 | |
|                 const stats = await fs.stat(bundlePath);
 | |
|                 const sizeKB = Math.round(stats.size / 1024);
 | |
|                 
 | |
|                 if (sizeKB > MAX_SIZE_KB) {
 | |
|                     oversized.push(`${bundleName} (${sizeKB}KB)`);
 | |
|                 }
 | |
|                 
 | |
|                 this.log(`   ${bundleName}: ${sizeKB}KB`, sizeKB > MAX_SIZE_KB ? 'warning' : 'info');
 | |
|             } catch (error) {
 | |
|                 throw new Error(`Cannot read bundle size: ${bundleName}`);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         if (oversized.length > 0) {
 | |
|             throw new Error(`Bundles exceed ${MAX_SIZE_KB}KB limit: ${oversized.join(', ')}`);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async testBundleContent() {
 | |
|         // Test at least one bundle has content
 | |
|         const bundlePath = path.join(BUILD_CONFIG.BUILD_OUTPUT, 'hvac-core.bundle.js');
 | |
|         
 | |
|         try {
 | |
|             const content = await fs.readFile(bundlePath, 'utf-8');
 | |
|             
 | |
|             if (content.length < 100) {
 | |
|                 throw new Error('Bundle content too small');
 | |
|             }
 | |
|             
 | |
|             // Check for WordPress compatibility
 | |
|             const hasJQuery = content.includes('jQuery') || content.includes('$');
 | |
|             if (!hasJQuery) {
 | |
|                 this.log('   Warning: No jQuery reference found', 'warning');
 | |
|             }
 | |
|             
 | |
|             this.log(`   Bundle size: ${Math.round(content.length / 1024)}KB`, 'info');
 | |
|             
 | |
|         } catch (error) {
 | |
|             throw new Error(`Cannot read bundle content: ${error.message}`);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async testBuildProcess() {
 | |
|         this.log('   Running production build...', 'info');
 | |
|         
 | |
|         try {
 | |
|             const output = execSync('npm run build', { 
 | |
|                 encoding: 'utf-8',
 | |
|                 timeout: 60000 // 60 second timeout
 | |
|             });
 | |
|             
 | |
|             if (output.includes('ERROR') || output.includes('Failed')) {
 | |
|                 throw new Error('Build process reported errors');
 | |
|             }
 | |
|             
 | |
|             this.log('   Build completed successfully', 'success');
 | |
|             
 | |
|         } catch (error) {
 | |
|             throw new Error(`Build process failed: ${error.message}`);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async testPHPClassExists() {
 | |
|         const phpClassPath = path.join(BUILD_CONFIG.PROJECT_ROOT, 'includes/class-hvac-bundled-assets.php');
 | |
|         
 | |
|         const classExists = await fs.access(phpClassPath).then(() => true).catch(() => false);
 | |
|         if (!classExists) {
 | |
|             throw new Error('HVAC_Bundled_Assets PHP class not found');
 | |
|         }
 | |
|         
 | |
|         const phpContent = await fs.readFile(phpClassPath, 'utf-8');
 | |
|         
 | |
|         if (!phpContent.includes('class HVAC_Bundled_Assets')) {
 | |
|             throw new Error('HVAC_Bundled_Assets class definition not found');
 | |
|         }
 | |
|         
 | |
|         // Check for singleton pattern
 | |
|         if (!phpContent.includes('public static function instance()')) {
 | |
|             throw new Error('Singleton pattern not implemented');
 | |
|         }
 | |
|         
 | |
|         this.log('   PHP class structure validated', 'success');
 | |
|     }
 | |
|     
 | |
|     async testSecurityBasics() {
 | |
|         const phpClassPath = path.join(BUILD_CONFIG.PROJECT_ROOT, 'includes/class-hvac-bundled-assets.php');
 | |
|         const phpContent = await fs.readFile(phpClassPath, 'utf-8');
 | |
|         
 | |
|         const securityIssues = [];
 | |
|         
 | |
|         // Check for unsanitized file operations
 | |
|         if (phpContent.includes('file_get_contents') && !phpContent.includes('wp_safe_remote_get')) {
 | |
|             securityIssues.push('Direct file_get_contents usage');
 | |
|         }
 | |
|         
 | |
|         // Check for unescaped output
 | |
|         if (phpContent.includes('echo ') && !phpContent.includes('esc_html')) {
 | |
|             securityIssues.push('Potentially unescaped output');
 | |
|         }
 | |
|         
 | |
|         if (securityIssues.length > 0) {
 | |
|             this.log(`   Security issues found: ${securityIssues.join(', ')}`, 'warning');
 | |
|             this.log('   ⚠️  These should be addressed before production', 'warning');
 | |
|         } else {
 | |
|             this.log('   Basic security check passed', 'success');
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async run() {
 | |
|         this.log('\n🧪 HVAC BUILD SYSTEM - SIMPLE VALIDATION', 'info');
 | |
|         this.log('═'.repeat(50), 'info');
 | |
|         
 | |
|         await this.test('Webpack Configuration Exists', () => this.testWebpackConfigExists());
 | |
|         await this.test('Build Output Directory Exists', () => this.testBuildOutputExists());
 | |
|         await this.test('Expected Bundles Exist', () => this.testExpectedBundlesExist());
 | |
|         await this.test('Bundle Sizes Within Limits', () => this.testBundleSizes());
 | |
|         await this.test('Bundle Content Validation', () => this.testBundleContent());
 | |
|         await this.test('Build Process Works', () => this.testBuildProcess());
 | |
|         await this.test('PHP Class Exists', () => this.testPHPClassExists());
 | |
|         await this.test('Basic Security Check', () => this.testSecurityBasics());
 | |
|         
 | |
|         this.log('\n📊 TEST RESULTS', 'info');
 | |
|         this.log('═'.repeat(50), 'info');
 | |
|         this.log(`✅ Passed: ${this.results.passed}`, 'success');
 | |
|         this.log(`❌ Failed: ${this.results.failed}`, this.results.failed > 0 ? 'error' : 'info');
 | |
|         this.log(`📋 Total: ${this.results.passed + this.results.failed}`, 'info');
 | |
|         
 | |
|         if (this.results.failed > 0) {
 | |
|             this.log('\n❌ FAILED TESTS:', 'error');
 | |
|             this.results.tests.filter(t => t.status === 'fail').forEach(test => {
 | |
|                 this.log(`   • ${test.name}: ${test.error}`, 'error');
 | |
|             });
 | |
|         }
 | |
|         
 | |
|         const success = this.results.failed === 0;
 | |
|         
 | |
|         this.log('\n🎯 OVERALL STATUS', 'info');
 | |
|         if (success) {
 | |
|             this.log('✅ Build system validation PASSED', 'success');
 | |
|             this.log('🚀 Build system is ready for further testing', 'success');
 | |
|         } else {
 | |
|             this.log('❌ Build system validation FAILED', 'error');
 | |
|             this.log('⚠️  Fix issues before proceeding with deployment', 'error');
 | |
|         }
 | |
|         
 | |
|         return success;
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Run the test
 | |
| if (require.main === module) {
 | |
|     const test = new SimpleBuildSystemTest();
 | |
|     test.run().then(success => {
 | |
|         process.exit(success ? 0 : 1);
 | |
|     }).catch(error => {
 | |
|         console.error('Fatal error:', error.message);
 | |
|         process.exit(1);
 | |
|     });
 | |
| }
 | |
| 
 | |
| module.exports = SimpleBuildSystemTest; |