upskill-event-manager/tests/build-system-validation.test.js
ben 054639c95c
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
feat: complete master trainer system transformation from 0% to 100% success
- 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>
2025-09-02 16:41:51 -03:00

892 lines
No EOL
33 KiB
JavaScript

/**
* HVAC Community Events - Build System Validation Tests
*
* Comprehensive test suite for the JavaScript build pipeline including:
* - Webpack build process validation
* - Bundle generation verification
* - Security vulnerability testing
* - WordPress integration testing
* - Performance and compatibility validation
*
* @package HVAC_Community_Events
* @since 2.0.0
*/
const fs = require('fs').promises;
const path = require('path');
const { execSync, spawn } = require('child_process');
const { test, expect } = require('@playwright/test');
const BasePage = require('./page-objects/base/BasePage');
// Configuration
const BUILD_CONFIG = {
PROJECT_ROOT: path.resolve(__dirname, '..'),
BUILD_OUTPUT: path.resolve(__dirname, '../assets/js/dist'),
SOURCE_DIR: path.resolve(__dirname, '../src/js'),
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'
],
// Security test payloads
SECURITY_PAYLOADS: {
XSS_MANIFEST: '{"hvac-core.js": "<script>alert(\'XSS\')</script>"}',
MALICIOUS_USER_AGENT: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"; maliciousScript();',
PATH_TRAVERSAL: '../../../../etc/passwd',
SQL_INJECTION: "'; DROP TABLE wp_users; --"
}
};
/**
* Build System Test Utilities
*/
class BuildSystemTestUtils {
/**
* Run webpack build command
* @param {string} mode - 'development' or 'production'
* @returns {Promise<{success: boolean, output: string, error?: string}>}
*/
static async runWebpackBuild(mode = 'production') {
return new Promise((resolve) => {
const buildCommand = mode === 'production' ? 'npm run build' : 'npm run build:dev';
const process = spawn('bash', ['-c', buildCommand], {
cwd: BUILD_CONFIG.PROJECT_ROOT,
stdio: ['pipe', 'pipe', 'pipe']
});
let output = '';
let errorOutput = '';
process.stdout.on('data', (data) => {
output += data.toString();
});
process.stderr.on('data', (data) => {
errorOutput += data.toString();
});
process.on('close', (code) => {
resolve({
success: code === 0,
output,
error: code !== 0 ? errorOutput : undefined
});
});
// Timeout after 60 seconds
setTimeout(() => {
process.kill('SIGTERM');
resolve({
success: false,
output,
error: 'Build process timed out after 60 seconds'
});
}, 60000);
});
}
/**
* Analyze bundle sizes
* @returns {Promise<Object>}
*/
static async analyzeBundleSizes() {
const bundles = {};
for (const bundleName of BUILD_CONFIG.EXPECTED_BUNDLES) {
const bundlePath = path.join(BUILD_CONFIG.BUILD_OUTPUT, bundleName);
try {
const stats = await fs.stat(bundlePath);
bundles[bundleName] = {
size: stats.size,
sizeKB: Math.round(stats.size / 1024),
exists: true
};
} catch (error) {
bundles[bundleName] = {
size: 0,
sizeKB: 0,
exists: false,
error: error.message
};
}
}
return bundles;
}
/**
* Validate bundle contents
* @param {string} bundleName
* @returns {Promise<{isValid: boolean, hasWordPressCompat: boolean, hasErrors: boolean, content?: string}>}
*/
static async validateBundleContent(bundleName) {
const bundlePath = path.join(BUILD_CONFIG.BUILD_OUTPUT, bundleName);
try {
const content = await fs.readFile(bundlePath, 'utf-8');
return {
isValid: content.length > 0,
hasWordPressCompat: content.includes('jQuery') || content.includes('wp.'),
hasErrors: content.includes('Error:') || content.includes('TypeError:'),
hasSourceMap: content.includes('//# sourceMappingURL='),
content: content.substring(0, 500) // First 500 chars for inspection
};
} catch (error) {
return {
isValid: false,
hasWordPressCompat: false,
hasErrors: true,
error: error.message
};
}
}
/**
* Create malicious manifest for security testing
* @param {string} payload
*/
static async createMaliciousManifest(payload) {
const backupPath = BUILD_CONFIG.MANIFEST_PATH + '.backup';
// Backup original manifest
try {
await fs.copyFile(BUILD_CONFIG.MANIFEST_PATH, backupPath);
} catch (error) {
// Manifest might not exist
}
// Write malicious manifest
await fs.writeFile(BUILD_CONFIG.MANIFEST_PATH, payload);
}
/**
* Restore manifest from backup
*/
static async restoreManifest() {
const backupPath = BUILD_CONFIG.MANIFEST_PATH + '.backup';
try {
await fs.copyFile(backupPath, BUILD_CONFIG.MANIFEST_PATH);
await fs.unlink(backupPath);
} catch (error) {
// Remove malicious manifest if backup doesn't exist
try {
await fs.unlink(BUILD_CONFIG.MANIFEST_PATH);
} catch (e) {
// Ignore cleanup errors
}
}
}
/**
* Simulate missing bundle files
* @param {string[]} bundleNames
*/
static async removeBundles(bundleNames) {
const backups = [];
for (const bundleName of bundleNames) {
const bundlePath = path.join(BUILD_CONFIG.BUILD_OUTPUT, bundleName);
const backupPath = bundlePath + '.backup';
try {
await fs.copyFile(bundlePath, backupPath);
await fs.unlink(bundlePath);
backups.push({ original: bundlePath, backup: backupPath });
} catch (error) {
console.warn(`Could not backup ${bundleName}:`, error.message);
}
}
return backups;
}
/**
* Restore backed up bundles
* @param {Array} backups
*/
static async restoreBundles(backups) {
for (const { original, backup } of backups) {
try {
await fs.copyFile(backup, original);
await fs.unlink(backup);
} catch (error) {
console.warn(`Could not restore bundle:`, error.message);
}
}
}
}
/**
* WordPress Bundled Assets Test Page
*/
class WordPressBundledAssetsPage extends BasePage {
constructor(page) {
super(page);
this.bundledAssets = [];
this.loadErrors = [];
}
/**
* Monitor asset loading
*/
async monitorAssetLoading() {
// Monitor network requests
this.page.on('response', async (response) => {
const url = response.url();
if (url.includes('/assets/js/dist/') && url.includes('.bundle.js')) {
this.bundledAssets.push({
url,
status: response.status(),
success: response.ok()
});
}
});
// Monitor console errors
this.page.on('console', (message) => {
if (message.type() === 'error') {
this.loadErrors.push(message.text());
}
});
// Monitor JavaScript errors
this.page.on('pageerror', (error) => {
this.loadErrors.push(`JavaScript Error: ${error.message}`);
});
}
/**
* Get loaded bundles information
*/
getLoadedBundles() {
return this.bundledAssets;
}
/**
* Get loading errors
*/
getLoadingErrors() {
return this.loadErrors;
}
/**
* Check if specific bundle is loaded
* @param {string} bundleName
*/
isBundleLoaded(bundleName) {
return this.bundledAssets.some(asset =>
asset.url.includes(bundleName) && asset.success
);
}
/**
* Validate bundle loading on WordPress page
* @param {string} pageUrl
*/
async validateBundleLoadingOnPage(pageUrl) {
await this.monitorAssetLoading();
await this.page.goto(pageUrl);
await this.page.waitForLoadState('networkidle');
// Wait a bit for assets to load
await this.page.waitForTimeout(2000);
return {
loadedBundles: this.getLoadedBundles(),
loadingErrors: this.getLoadingErrors(),
pageTitle: await this.page.title()
};
}
}
// ==============================================================================
// BUILD SYSTEM VALIDATION TESTS
// ==============================================================================
test.describe('Build System Validation', () => {
test('Webpack configuration is valid', async () => {
// Test webpack config file exists and is readable
const configExists = await fs.access(BUILD_CONFIG.WEBPACK_CONFIG).then(() => true).catch(() => false);
expect(configExists).toBe(true);
// Test webpack config can be loaded
const webpack = require('webpack');
const config = require(BUILD_CONFIG.WEBPACK_CONFIG);
expect(config).toBeTruthy();
expect(config.entry).toBeTruthy();
expect(config.output).toBeTruthy();
expect(config.output.path).toBe(BUILD_CONFIG.BUILD_OUTPUT);
// Validate entry points
const expectedEntries = [
'hvac-core', 'hvac-dashboard', 'hvac-certificates',
'hvac-master', 'hvac-trainer', 'hvac-events',
'hvac-admin', 'hvac-safari-compat'
];
for (const entry of expectedEntries) {
expect(config.entry[entry]).toBeTruthy();
}
});
test('Production build generates all expected bundles', async () => {
console.log('Running production build...');
const buildResult = await BuildSystemTestUtils.runWebpackBuild('production');
expect(buildResult.success).toBe(true);
if (!buildResult.success) {
console.error('Build failed:', buildResult.error);
console.log('Build output:', buildResult.output);
}
// Check all expected bundles exist
const bundleAnalysis = await BuildSystemTestUtils.analyzeBundleSizes();
for (const bundleName of BUILD_CONFIG.EXPECTED_BUNDLES) {
expect(bundleAnalysis[bundleName].exists).toBe(true);
expect(bundleAnalysis[bundleName].size).toBeGreaterThan(0);
console.log(`${bundleName}: ${bundleAnalysis[bundleName].sizeKB}KB`);
}
});
test('Development build generates readable bundles', async () => {
console.log('Running development build...');
const buildResult = await BuildSystemTestUtils.runWebpackBuild('development');
expect(buildResult.success).toBe(true);
// Check bundles are readable and have source maps
for (const bundleName of BUILD_CONFIG.EXPECTED_BUNDLES) {
const validation = await BuildSystemTestUtils.validateBundleContent(bundleName);
expect(validation.isValid).toBe(true);
expect(validation.hasErrors).toBe(false);
// Development builds should have source maps
expect(validation.hasSourceMap).toBe(true);
}
});
test('Bundle sizes are within performance limits', async () => {
const bundleAnalysis = await BuildSystemTestUtils.analyzeBundleSizes();
// Each bundle should be under 250KB as per webpack config
const MAX_BUNDLE_SIZE_KB = 250;
for (const [bundleName, info] of Object.entries(bundleAnalysis)) {
if (info.exists) {
expect(info.sizeKB).toBeLessThanOrEqual(MAX_BUNDLE_SIZE_KB);
console.log(`📊 ${bundleName}: ${info.sizeKB}KB (limit: ${MAX_BUNDLE_SIZE_KB}KB)`);
}
}
});
test('Bundles contain WordPress-compatible code', async () => {
for (const bundleName of BUILD_CONFIG.EXPECTED_BUNDLES) {
const validation = await BuildSystemTestUtils.validateBundleContent(bundleName);
if (validation.isValid) {
// Core bundle should definitely have WordPress compatibility
if (bundleName.includes('core')) {
expect(validation.hasWordPressCompat).toBe(true);
}
// No bundles should have build errors
expect(validation.hasErrors).toBe(false);
console.log(`${bundleName}: WordPress compatible: ${validation.hasWordPressCompat}`);
}
}
});
});
// ==============================================================================
// SECURITY VULNERABILITY TESTS
// ==============================================================================
test.describe('Security Vulnerability Tests', () => {
test('Manifest integrity vulnerability - XSS payload injection', async ({ page }) => {
console.log('🔒 Testing manifest integrity vulnerability...');
// Create malicious manifest with XSS payload
await BuildSystemTestUtils.createMaliciousManifest(BUILD_CONFIG.SECURITY_PAYLOADS.XSS_MANIFEST);
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
try {
// Navigate to trainer dashboard which should load bundles
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Check if XSS payload was executed or sanitized
const pageContent = await page.content();
const hasXSSExecuted = pageContent.includes('<script>alert(') ||
result.loadingErrors.some(err => err.includes('alert'));
// VULNERABILITY: XSS payload should NOT execute
expect(hasXSSExecuted).toBe(false);
console.log('Loaded bundles:', result.loadedBundles.length);
console.log('Loading errors:', result.loadingErrors.length);
// Should gracefully handle invalid manifest
expect(result.loadingErrors).not.toContain(expect.stringMatching(/XSS|alert|script/i));
} finally {
// Always restore manifest
await BuildSystemTestUtils.restoreManifest();
}
});
test('User agent security vulnerability - injection attack', async ({ page }) => {
console.log('🔒 Testing user agent injection vulnerability...');
// Set malicious user agent
await page.setExtraHTTPHeaders({
'User-Agent': BUILD_CONFIG.SECURITY_PAYLOADS.MALICIOUS_USER_AGENT
});
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Check for signs of code injection
const pageContent = await page.content();
const hasCodeInjection = pageContent.includes('maliciousScript()') ||
result.loadingErrors.some(err => err.includes('maliciousScript'));
// VULNERABILITY: Malicious code should NOT execute
expect(hasCodeInjection).toBe(false);
// Should not crash the page
expect(result.pageTitle).toBeTruthy();
console.log(`Page loaded successfully with suspicious user agent`);
});
test('Missing bundle validation - file not found handling', async ({ page }) => {
console.log('🔒 Testing missing bundle validation...');
// Remove critical core bundle
const backups = await BuildSystemTestUtils.removeBundles(['hvac-core.bundle.js']);
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
try {
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// VULNERABILITY: Should gracefully handle missing bundles
// Page should still load (potentially with degraded functionality)
expect(result.pageTitle).toBeTruthy();
// Should have loading errors but not crash
const has404Errors = result.loadedBundles.some(bundle => bundle.status === 404);
if (has404Errors) {
console.log('Expected 404 errors for missing bundles detected');
}
// Check if page has fallback functionality
const pageContent = await page.content();
const hasBasicContent = pageContent.includes('trainer') || pageContent.includes('dashboard');
expect(hasBasicContent).toBe(true);
console.log('Page survived missing core bundle');
} finally {
// Restore removed bundles
await BuildSystemTestUtils.restoreBundles(backups);
}
});
test('Manifest tampering - path traversal attack', async ({ page }) => {
console.log('🔒 Testing manifest path traversal vulnerability...');
// Create manifest with path traversal payload
const traversalManifest = JSON.stringify({
'hvac-core.js': BUILD_CONFIG.SECURITY_PAYLOADS.PATH_TRAVERSAL + '/malicious.js'
});
await BuildSystemTestUtils.createMaliciousManifest(traversalManifest);
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
try {
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Check if path traversal was attempted
const suspiciousRequests = result.loadedBundles.filter(bundle =>
bundle.url.includes('../') || bundle.url.includes('/etc/')
);
// VULNERABILITY: Path traversal should be blocked
expect(suspiciousRequests.length).toBe(0);
// Page should still load safely
expect(result.pageTitle).toBeTruthy();
console.log('Path traversal attack blocked successfully');
} finally {
await BuildSystemTestUtils.restoreManifest();
}
});
});
// ==============================================================================
// WORDPRESS INTEGRATION TESTS
// ==============================================================================
test.describe('WordPress Integration Tests', () => {
test('HVAC_Bundled_Assets class loads correct bundles for trainer dashboard', async ({ page }) => {
console.log('🔧 Testing bundle loading on trainer dashboard...');
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Should load core bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-core.bundle.js')).toBe(true);
// Should load dashboard bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-dashboard.bundle.js')).toBe(true);
// Should load trainer bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-trainer.bundle.js')).toBe(true);
console.log(`✅ Loaded ${result.loadedBundles.length} bundles successfully`);
console.log('Bundle URLs:', result.loadedBundles.map(b => b.url.split('/').pop()));
// No loading errors
expect(result.loadingErrors.length).toBe(0);
});
test('HVAC_Bundled_Assets class loads correct bundles for master trainer pages', async ({ page }) => {
console.log('🔧 Testing bundle loading on master trainer dashboard...');
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/master-trainer/master-dashboard/`
);
// Should load core bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-core.bundle.js')).toBe(true);
// Should load master bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-master.bundle.js')).toBe(true);
console.log(`✅ Master trainer loaded ${result.loadedBundles.length} bundles`);
// No loading errors
expect(result.loadingErrors.length).toBe(0);
});
test('Safari compatibility bundle loads for Safari browsers', async ({ page, browserName }) => {
if (browserName !== 'webkit') {
test.skip('Safari compatibility test only runs on WebKit/Safari');
}
console.log('🦎 Testing Safari compatibility bundle loading...');
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Should load Safari compatibility bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-safari-compat.bundle.js')).toBe(true);
console.log('✅ Safari compatibility bundle loaded');
});
test('Bundle localization data is properly injected', async ({ page }) => {
console.log('🌐 Testing bundle localization...');
await page.goto(`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`);
await page.waitForLoadState('networkidle');
// Check if hvacBundleData is available
const localizationData = await page.evaluate(() => {
return window.hvacBundleData || null;
});
expect(localizationData).toBeTruthy();
expect(localizationData.ajax_url).toBeTruthy();
expect(localizationData.nonce).toBeTruthy();
expect(localizationData.rest_url).toBeTruthy();
console.log('✅ Localization data:', Object.keys(localizationData));
});
});
// ==============================================================================
// PERFORMANCE & COMPATIBILITY TESTS
// ==============================================================================
test.describe('Performance & Compatibility Tests', () => {
test('Bundle loading performance benchmarks', async ({ page }) => {
console.log('⚡ Testing bundle loading performance...');
const startTime = Date.now();
await page.goto(`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`);
await page.waitForLoadState('networkidle');
const loadTime = Date.now() - startTime;
console.log(`Page loaded in ${loadTime}ms`);
// Should load within reasonable time (adjust based on environment)
expect(loadTime).toBeLessThan(10000); // 10 seconds max
// Check bundle sizes loaded
const bundleRequests = await page.evaluate(() => {
return performance.getEntriesByType('resource')
.filter(entry => entry.name.includes('.bundle.js'))
.map(entry => ({
name: entry.name.split('/').pop(),
size: entry.transferSize,
loadTime: entry.duration
}));
});
console.log('Bundle performance:', bundleRequests);
// Each bundle should load reasonably fast
bundleRequests.forEach(bundle => {
expect(bundle.loadTime).toBeLessThan(3000); // 3 seconds per bundle
});
});
test('Cross-browser bundle compatibility', async ({ page, browserName }) => {
console.log(`🌐 Testing bundle compatibility on ${browserName}...`);
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Should load without JavaScript errors
expect(result.loadingErrors.length).toBe(0);
// Should load at least core bundle
expect(bundledAssetsPage.isBundleLoaded('hvac-core.bundle.js')).toBe(true);
// Test basic JavaScript functionality
const jsWorking = await page.evaluate(() => {
return typeof jQuery !== 'undefined' && typeof $ !== 'undefined';
});
expect(jsWorking).toBe(true);
console.log(`${browserName} compatibility confirmed`);
});
test('Bundle caching behavior', async ({ page }) => {
console.log('💾 Testing bundle caching...');
// First load
await page.goto(`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`);
await page.waitForLoadState('networkidle');
const firstLoadRequests = await page.evaluate(() => {
return performance.getEntriesByType('resource')
.filter(entry => entry.name.includes('.bundle.js'))
.length;
});
// Reload page
await page.reload();
await page.waitForLoadState('networkidle');
const reloadRequests = await page.evaluate(() => {
return performance.getEntriesByType('resource')
.filter(entry => entry.name.includes('.bundle.js'))
.length;
});
console.log(`First load: ${firstLoadRequests} requests, Reload: ${reloadRequests} requests`);
// Should have bundle requests on both loads (caching depends on server config)
expect(firstLoadRequests).toBeGreaterThan(0);
expect(reloadRequests).toBeGreaterThan(0);
});
});
// ==============================================================================
// ERROR SCENARIO TESTS
// ==============================================================================
test.describe('Error Scenario & Graceful Degradation Tests', () => {
test('Handles corrupted manifest.json gracefully', async ({ page }) => {
console.log('🚨 Testing corrupted manifest handling...');
// Create corrupted manifest
await BuildSystemTestUtils.createMaliciousManifest('corrupted-json{invalid');
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
try {
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Page should still load (fallback to expected filenames)
expect(result.pageTitle).toBeTruthy();
// Should attempt to load bundles with fallback naming
const loadAttempts = result.loadedBundles.length +
result.loadingErrors.filter(err => err.includes('bundle')).length;
expect(loadAttempts).toBeGreaterThan(0);
console.log('✅ Gracefully handled corrupted manifest');
} finally {
await BuildSystemTestUtils.restoreManifest();
}
});
test('Handles missing dist directory', async ({ page }) => {
console.log('🚨 Testing missing dist directory...');
// Rename dist directory temporarily
const distBackupPath = BUILD_CONFIG.BUILD_OUTPUT + '.backup';
try {
await fs.rename(BUILD_CONFIG.BUILD_OUTPUT, distBackupPath);
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Page should still load with graceful degradation
expect(result.pageTitle).toBeTruthy();
// Should have 404 errors for missing bundles
const has404s = result.loadedBundles.some(bundle => bundle.status === 404);
console.log('404 errors detected:', has404s);
// Basic page content should still be accessible
const pageContent = await page.content();
expect(pageContent.length).toBeGreaterThan(100);
console.log('✅ Page survived missing dist directory');
} finally {
// Restore dist directory
try {
await fs.rename(distBackupPath, BUILD_CONFIG.BUILD_OUTPUT);
} catch (error) {
console.warn('Could not restore dist directory:', error.message);
}
}
});
test('Handles JavaScript errors in bundles', async ({ page }) => {
console.log('🚨 Testing JavaScript error handling...');
// Monitor for JavaScript errors
const jsErrors = [];
page.on('pageerror', (error) => {
jsErrors.push(error.message);
});
await page.goto(`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`);
await page.waitForLoadState('networkidle');
// Inject a JavaScript error to test error handling
await page.evaluate(() => {
if (window.hvacBundleData) {
try {
// This should cause an error but not crash the page
throw new Error('Test bundle error');
} catch (e) {
console.error('Bundle error caught:', e.message);
}
}
});
await page.waitForTimeout(1000);
// Page should still be functional despite errors
const pageTitle = await page.title();
expect(pageTitle).toBeTruthy();
// Basic navigation should work
const navigationExists = await page.locator('nav, .navigation, .menu').count();
expect(navigationExists).toBeGreaterThan(0);
console.log(`✅ Page remained functional with ${jsErrors.length} JS errors`);
});
test('Network failure during bundle loading', async ({ page }) => {
console.log('🚨 Testing network failure during bundle loading...');
// Simulate network failure for bundle requests
await page.route('**/assets/js/dist/*.bundle.js', (route) => {
// Fail 50% of bundle requests to simulate network issues
if (Math.random() < 0.5) {
route.abort('failed');
} else {
route.continue();
}
});
const bundledAssetsPage = new WordPressBundledAssetsPage(page);
const result = await bundledAssetsPage.validateBundleLoadingOnPage(
`${process.env.BASE_URL || 'http://localhost:8080'}/trainer/dashboard/`
);
// Some bundles should fail, some should succeed
const failedBundles = result.loadedBundles.filter(b => !b.success);
const successBundles = result.loadedBundles.filter(b => b.success);
console.log(`Failed: ${failedBundles.length}, Succeeded: ${successBundles.length}`);
// Page should still load with partial functionality
expect(result.pageTitle).toBeTruthy();
// Should have some loading errors but not completely crash
expect(result.loadingErrors.length).toBeGreaterThan(0);
console.log('✅ Partial network failure handled gracefully');
// Clean up route override
await page.unroute('**/assets/js/dist/*.bundle.js');
});
});
console.log('🧪 HVAC Build System Test Suite Loaded');
console.log('📊 Test Coverage:');
console.log(' ✅ Build system validation (webpack, bundles, sizes)');
console.log(' 🔒 Security vulnerability testing (manifest, user agent, path traversal)');
console.log(' 🔧 WordPress integration (bundle loading, localization)');
console.log(' ⚡ Performance & compatibility (loading times, cross-browser)');
console.log(' 🚨 Error scenarios (corruption, missing files, network failures)');