upskill-event-manager/tests/framework/utils/WordPressUtils.js
Ben 7c9ca65cf2
Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
feat: add comprehensive test framework and test files
- Add 90+ test files including E2E, unit, and integration tests
- Implement Page Object Model (POM) architecture
- Add Docker testing environment with comprehensive services
- Include modernized test framework with error recovery
- Add specialized test suites for master trainer and trainer workflows
- Update .gitignore to properly track test infrastructure

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 23:23:26 -03:00

469 lines
No EOL
15 KiB
JavaScript

/**
* WordPress Utilities for HVAC Testing Framework
*
* Provides WordPress-specific functionality:
* - WP-CLI integration for database management
* - Cache clearing and rewrite rule flushing
* - Test data seeding and cleanup
* - User management and role assignments
*
* @package HVAC_Community_Events
* @version 2.0.0
* @created 2025-08-27
*/
const { exec } = require('child_process');
const { promisify } = require('util');
const fs = require('fs').promises;
const path = require('path');
const ConfigManager = require('../core/ConfigManager');
const execAsync = promisify(exec);
class WordPressUtils {
constructor() {
this.config = ConfigManager;
this.wpCliPath = this.config.get('wordpress.cliPath', 'wp');
this.baseUrl = this.config.get('app.baseUrl');
this.timeout = 30000; // 30 seconds for WP-CLI commands
}
/**
* Execute WP-CLI command with error handling
*/
async executeWpCli(command, options = {}) {
const fullCommand = `${this.wpCliPath} ${command} --url="${this.baseUrl}" --allow-root`;
try {
console.log(`🔧 WP-CLI: ${command}`);
const { stdout, stderr } = await execAsync(fullCommand, {
timeout: options.timeout || this.timeout,
cwd: options.cwd || process.cwd()
});
if (stderr && !options.ignoreStderr) {
console.warn(`⚠️ WP-CLI Warning: ${stderr}`);
}
return stdout.trim();
} catch (error) {
console.error(`❌ WP-CLI Error (${command}):`, error.message);
throw new Error(`WP-CLI command failed: ${command} - ${error.message}`);
}
}
/**
* Flush WordPress rewrite rules
*/
async flushRewriteRules() {
try {
await this.executeWpCli('rewrite flush');
console.log('✅ Rewrite rules flushed');
} catch (error) {
console.warn('Could not flush rewrite rules:', error.message);
}
}
/**
* Clear WordPress cache (if caching plugin is available)
*/
async clearCache() {
const cacheCommands = [
'cache flush', // Object cache
'transient delete --all', // Transients
'rewrite flush' // Rewrite rules
];
for (const command of cacheCommands) {
try {
await this.executeWpCli(command, { ignoreStderr: true });
} catch (error) {
// Cache clearing might fail if no cache plugin is installed
console.log(`Cache command skipped: ${command}`);
}
}
console.log('🗑️ WordPress cache cleared');
}
/**
* Create test user with specific role
*/
async createTestUser(username, email, role, password = null) {
// Generate password if not provided
if (!password) {
password = `Test${role}123!`;
}
try {
// Check if user already exists
const userExists = await this.executeWpCli(`user get ${username}`, { ignoreStderr: true })
.then(() => true)
.catch(() => false);
if (userExists) {
console.log(`👤 User already exists: ${username}`);
// Update user role if needed
await this.executeWpCli(`user set-role ${username} ${role}`);
return { username, email, password, existed: true };
}
// Create new user
await this.executeWpCli(`user create ${username} ${email} --role=${role} --user_pass="${password}"`);
console.log(`✅ Created test user: ${username} (${role})`);
return { username, email, password, existed: false };
} catch (error) {
throw new Error(`Failed to create test user ${username}: ${error.message}`);
}
}
/**
* Delete test user
*/
async deleteTestUser(username) {
try {
await this.executeWpCli(`user delete ${username} --yes`);
console.log(`🗑️ Deleted test user: ${username}`);
} catch (error) {
console.warn(`Could not delete user ${username}:`, error.message);
}
}
/**
* Set up test data for HVAC plugin
*/
async seedTestData(testId) {
console.log(`🌱 Seeding test data for: ${testId}`);
try {
// Create test events
await this.createTestEvents(testId);
// Create test venues
await this.createTestVenues(testId);
// Create test organizers
await this.createTestOrganizers(testId);
console.log('✅ Test data seeded successfully');
} catch (error) {
console.error('❌ Failed to seed test data:', error.message);
throw error;
}
}
/**
* Create test events
*/
async createTestEvents(testId) {
const events = [
{
title: `Test HVAC Training Event - ${testId}`,
content: 'Test event for automated testing',
status: 'publish',
meta: {
'_hvac_test_id': testId,
'_hvac_test_event': '1'
}
}
];
for (const event of events) {
try {
// Create the event post
const postCommand = `post create --post_type=tribe_events --post_title="${event.title}" --post_content="${event.content}" --post_status=${event.status} --porcelain`;
const postId = await this.executeWpCli(postCommand);
// Add meta fields
for (const [key, value] of Object.entries(event.meta)) {
await this.executeWpCli(`post meta add ${postId} ${key} "${value}"`);
}
console.log(`📅 Created test event: ${event.title} (ID: ${postId})`);
} catch (error) {
console.warn(`Could not create test event: ${event.title}`, error.message);
}
}
}
/**
* Create test venues
*/
async createTestVenues(testId) {
const venues = [
{
title: `Test Venue - ${testId}`,
content: 'Test venue for automated testing',
meta: {
'_hvac_test_id': testId,
'_VenueAddress': '123 Test Street',
'_VenueCity': 'Test City',
'_VenueState': 'Test State',
'_VenueZip': '12345'
}
}
];
for (const venue of venues) {
try {
const postCommand = `post create --post_type=tribe_venue --post_title="${venue.title}" --post_content="${venue.content}" --post_status=publish --porcelain`;
const postId = await this.executeWpCli(postCommand);
// Add meta fields
for (const [key, value] of Object.entries(venue.meta)) {
await this.executeWpCli(`post meta add ${postId} ${key} "${value}"`);
}
console.log(`🏢 Created test venue: ${venue.title} (ID: ${postId})`);
} catch (error) {
console.warn(`Could not create test venue: ${venue.title}`, error.message);
}
}
}
/**
* Create test organizers
*/
async createTestOrganizers(testId) {
const organizers = [
{
title: `Test Organizer - ${testId}`,
content: 'Test organizer for automated testing',
meta: {
'_hvac_test_id': testId,
'_OrganizerPhone': '555-123-4567',
'_OrganizerEmail': `test-organizer-${testId}@example.com`
}
}
];
for (const organizer of organizers) {
try {
const postCommand = `post create --post_type=tribe_organizer --post_title="${organizer.title}" --post_content="${organizer.content}" --post_status=publish --porcelain`;
const postId = await this.executeWpCli(postCommand);
// Add meta fields
for (const [key, value] of Object.entries(organizer.meta)) {
await this.executeWpCli(`post meta add ${postId} ${key} "${value}"`);
}
console.log(`👤 Created test organizer: ${organizer.title} (ID: ${postId})`);
} catch (error) {
console.warn(`Could not create test organizer: ${organizer.title}`, error.message);
}
}
}
/**
* Clean up test data
*/
async cleanupTestData(testId) {
console.log(`🧹 Cleaning up test data for: ${testId}`);
try {
// Find and delete test posts
const testPosts = await this.executeWpCli(`post list --meta_key=_hvac_test_id --meta_value="${testId}" --field=ID`);
if (testPosts.trim()) {
const postIds = testPosts.split('\n').filter(id => id.trim());
for (const postId of postIds) {
await this.executeWpCli(`post delete ${postId} --force`);
}
console.log(`🗑️ Deleted ${postIds.length} test posts`);
}
// Clean up orphaned meta
await this.executeWpCli(`db query "DELETE FROM wp_postmeta WHERE meta_key = '_hvac_test_id' AND meta_value = '${testId}'"`);
} catch (error) {
console.warn('Could not fully clean up test data:', error.message);
}
}
/**
* Check if plugin is active
*/
async isPluginActive(pluginName) {
try {
const activePlugins = await this.executeWpCli('plugin list --status=active --field=name');
return activePlugins.includes(pluginName);
} catch (error) {
console.warn(`Could not check plugin status for ${pluginName}:`, error.message);
return false;
}
}
/**
* Activate plugin
*/
async activatePlugin(pluginName) {
try {
await this.executeWpCli(`plugin activate ${pluginName}`);
console.log(`✅ Activated plugin: ${pluginName}`);
} catch (error) {
throw new Error(`Failed to activate plugin ${pluginName}: ${error.message}`);
}
}
/**
* Get WordPress version
*/
async getWordPressVersion() {
try {
const version = await this.executeWpCli('core version');
return version.trim();
} catch (error) {
console.warn('Could not get WordPress version:', error.message);
return 'unknown';
}
}
/**
* Update database after schema changes
*/
async updateDatabase() {
try {
await this.executeWpCli('core update-db');
console.log('✅ Database updated');
} catch (error) {
console.warn('Could not update database:', error.message);
}
}
/**
* Import test data from SQL file
*/
async importDatabase(sqlFilePath) {
try {
const absolutePath = path.resolve(sqlFilePath);
await this.executeWpCli(`db import "${absolutePath}"`);
console.log(`✅ Imported database from: ${sqlFilePath}`);
} catch (error) {
throw new Error(`Failed to import database: ${error.message}`);
}
}
/**
* Export database to SQL file
*/
async exportDatabase(outputPath) {
try {
const absolutePath = path.resolve(outputPath);
await this.executeWpCli(`db export "${absolutePath}"`);
console.log(`✅ Exported database to: ${outputPath}`);
return absolutePath;
} catch (error) {
throw new Error(`Failed to export database: ${error.message}`);
}
}
/**
* Reset database to clean state
*/
async resetDatabase() {
try {
await this.executeWpCli('db reset --yes');
console.log('✅ Database reset to clean state');
} catch (error) {
throw new Error(`Failed to reset database: ${error.message}`);
}
}
/**
* Get site URL
*/
async getSiteUrl() {
try {
return await this.executeWpCli('option get siteurl');
} catch (error) {
console.warn('Could not get site URL:', error.message);
return this.baseUrl;
}
}
/**
* Set WordPress option
*/
async setOption(optionName, optionValue) {
try {
await this.executeWpCli(`option update ${optionName} "${optionValue}"`);
console.log(`✅ Set option: ${optionName} = ${optionValue}`);
} catch (error) {
console.warn(`Could not set option ${optionName}:`, error.message);
}
}
/**
* Get WordPress option
*/
async getOption(optionName) {
try {
return await this.executeWpCli(`option get ${optionName}`);
} catch (error) {
console.warn(`Could not get option ${optionName}:`, error.message);
return null;
}
}
/**
* Run WordPress cron
*/
async runCron() {
try {
await this.executeWpCli('cron event run --due-now');
console.log('✅ WordPress cron executed');
} catch (error) {
console.warn('Could not run cron:', error.message);
}
}
/**
* Check WordPress environment health
*/
async checkHealth() {
const health = {
wpVersion: 'unknown',
pluginsActive: false,
databaseConnected: false,
writableUploads: false
};
try {
// Check WordPress version
health.wpVersion = await this.getWordPressVersion();
// Check if HVAC plugin is active
health.pluginsActive = await this.isPluginActive('hvac-community-events');
// Check database connection
try {
await this.executeWpCli('db check');
health.databaseConnected = true;
} catch (error) {
health.databaseConnected = false;
}
// Check uploads directory
try {
await this.executeWpCli('eval "wp_upload_dir();"');
health.writableUploads = true;
} catch (error) {
health.writableUploads = false;
}
} catch (error) {
console.warn('Health check incomplete:', error.message);
}
console.log('🏥 WordPress Health Check:', health);
return health;
}
}
module.exports = WordPressUtils;