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; |