upskill-event-manager/docs/DOCKER-DEVELOPMENT-GUIDE.md
Ben c3e7fe9140 feat: comprehensive HVAC plugin development framework and modernization
## Major Enhancements

### 🏗️ Architecture & Infrastructure
- Implement comprehensive Docker testing infrastructure with hermetic environment
- Add Forgejo Actions CI/CD pipeline for automated deployments
- Create Page Object Model (POM) testing architecture reducing test duplication by 90%
- Establish security-first development patterns with input validation and output escaping

### 🧪 Testing Framework Modernization
- Migrate 146+ tests from 80 duplicate files to centralized architecture
- Add comprehensive E2E test suites for all user roles and workflows
- Implement WordPress error detection with automatic site health monitoring
- Create robust browser lifecycle management with proper cleanup

### 📚 Documentation & Guides
- Add comprehensive development best practices guide
- Create detailed administrator setup documentation
- Establish user guides for trainers and master trainers
- Document security incident reports and migration guides

### 🔧 Core Plugin Features
- Enhance trainer profile management with certification system
- Improve find trainer functionality with advanced filtering
- Strengthen master trainer area with content management
- Add comprehensive venue and organizer management

### 🛡️ Security & Reliability
- Implement security-first patterns throughout codebase
- Add comprehensive input validation and output escaping
- Create secure credential management system
- Establish proper WordPress role-based access control

### 🎯 WordPress Integration
- Strengthen singleton pattern implementation across all classes
- Enhance template hierarchy with proper WordPress integration
- Improve page manager with hierarchical URL structure
- Add comprehensive shortcode and menu system

### 🔍 Developer Experience
- Add extensive debugging and troubleshooting tools
- Create comprehensive test data seeding scripts
- Implement proper error handling and logging
- Establish consistent code patterns and standards

### 📊 Performance & Optimization
- Optimize database queries and caching strategies
- Improve asset loading and script management
- Enhance template rendering performance
- Streamline user experience across all interfaces

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

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

24 KiB

Docker Development Guide

Version: 2.0.0
Last Updated: August 28, 2025
Audience: Developers, QA Engineers
Platform: HVAC Community Events

Executive Summary

This guide provides comprehensive documentation for the Docker-based development and testing environment for the HVAC Community Events WordPress plugin. The environment includes a complete WordPress stack with testing tools, database management, and email testing capabilities.

Table of Contents

  1. Environment Overview
  2. Prerequisites
  3. Initial Setup
  4. Container Management
  5. Database Operations
  6. Test Framework Architecture
  7. Running Tests
  8. Debugging
  9. Performance Testing
  10. Troubleshooting
  11. Best Practices
  12. Advanced Configuration

Environment Overview

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│                     Host Machine                             │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Docker Compose Network                   │   │
│  │                                                       │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌───────────┐  │   │
│  │  │  WordPress   │  │    MySQL     │  │   Redis   │  │   │
│  │  │   PHP 8.2    │◄─┤    8.0       │◄─┤   Cache   │  │   │
│  │  │  Port: 8080  │  │  Port: 3307  │  │Port: 6380 │  │   │
│  │  └──────────────┘  └──────────────┘  └───────────┘  │   │
│  │                                                       │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌───────────┐  │   │
│  │  │  PhpMyAdmin  │  │   Mailhog    │  │  Selenium │  │   │
│  │  │  Port: 8081  │  │  Port: 8025  │  │ Port: 4444│  │   │
│  │  └──────────────┘  └──────────────┘  └───────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                              │
│  Test Files ◄──────► Plugin Source ◄──────► Test Results   │
└─────────────────────────────────────────────────────────────┘

Service Details

Service Image Port Purpose
WordPress wordpress:6.4-php8.2-apache 8080 Main application
MySQL mysql:8.0 3307 Database server
Redis redis:7-alpine 6380 Object caching
PhpMyAdmin phpmyadmin:5 8081 Database management
Mailhog mailhog/mailhog 8025 Email testing
Selenium selenium/standalone-chrome 4444 Browser automation

Prerequisites

System Requirements

Operating System:
  - Linux (Ubuntu 20.04+, Debian 11+)
  - macOS (11.0+)
  - Windows 10/11 with WSL2

Docker:
  version: "20.10+"
  compose: "2.0+"

Resources:
  RAM: "8GB minimum, 16GB recommended"
  CPU: "4 cores minimum"
  Disk: "20GB free space"
  
Development Tools:
  - Node.js 16+
  - npm or yarn
  - Git
  - Visual Studio Code (recommended)

Installation

Linux/macOS

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker --version
docker compose version

Windows (WSL2)

# Install WSL2
wsl --install

# Install Docker Desktop
# Download from https://docker.com/products/docker-desktop

# Enable WSL2 integration in Docker Desktop settings

Initial Setup

1. Clone Repository

# Clone the repository
git clone https://github.com/your-org/upskill-event-manager.git
cd upskill-event-manager

# Checkout development branch
git checkout development

2. Environment Configuration

# Copy environment template
cp tests/.env.template tests/.env

# Edit environment variables
nano tests/.env

Environment Variables

# WordPress Configuration
WORDPRESS_DB_HOST=mysql-test
WORDPRESS_DB_USER=hvac_test_user
WORDPRESS_DB_PASSWORD=hvac_test_password
WORDPRESS_DB_NAME=hvac_test_db
WORDPRESS_DEBUG=1
WORDPRESS_DEBUG_LOG=1
WORDPRESS_DEBUG_DISPLAY=0

# Test Configuration
HVAC_TEST_MODE=true
HVAC_TEST_DATA_ISOLATION=true
HVAC_TEST_EMAIL=test@example.com

# Service Ports
WORDPRESS_PORT=8080
MYSQL_PORT=3307
REDIS_PORT=6380
PHPMYADMIN_PORT=8081
MAILHOG_PORT=8025
SELENIUM_PORT=4444

# Volumes
WORDPRESS_VOLUME=wordpress_test_data
MYSQL_VOLUME=mysql_test_data
REDIS_VOLUME=redis_test_data

3. Build and Start Containers

# Navigate to tests directory
cd tests

# Build and start all services
docker compose -f docker-compose.test.yml up -d --build

# Wait for services to be healthy
docker compose -f docker-compose.test.yml ps

# Check logs
docker compose -f docker-compose.test.yml logs -f

4. Initialize WordPress

# Install WordPress
docker compose exec wordpress-test wp core install \
  --url="http://localhost:8080" \
  --title="HVAC Test Site" \
  --admin_user="admin" \
  --admin_password="admin123" \
  --admin_email="admin@test.local"

# Activate plugin
docker compose exec wordpress-test wp plugin activate hvac-community-events

# Install The Events Calendar
docker compose exec wordpress-test wp plugin install the-events-calendar --activate

# Create test pages
docker compose exec wordpress-test wp eval 'HVAC_Page_Manager::create_required_pages();'

# Flush permalinks
docker compose exec wordpress-test wp rewrite flush

5. Seed Test Data

# Create test users
./scripts/seed-test-users.sh

# Create test events
./scripts/seed-test-events.sh

# Import sample venues
docker compose exec wordpress-test wp import fixtures/venues.xml --authors=create

# Generate test certificates
docker compose exec wordpress-test wp eval 'HVAC_Test_Data::generate_certificates(50);'

Container Management

Starting and Stopping

# Start all containers
docker compose -f docker-compose.test.yml up -d

# Stop all containers (preserves data)
docker compose -f docker-compose.test.yml stop

# Stop and remove containers (preserves volumes)
docker compose -f docker-compose.test.yml down

# Stop and remove everything (including volumes)
docker compose -f docker-compose.test.yml down -v

# Restart specific service
docker compose -f docker-compose.test.yml restart wordpress-test

Accessing Services

# WordPress site
open http://localhost:8080

# WordPress admin
open http://localhost:8080/wp-admin
# Username: admin
# Password: admin123

# PhpMyAdmin
open http://localhost:8081
# Username: hvac_test_user
# Password: hvac_test_password

# Mailhog (email testing)
open http://localhost:8025

# Redis Commander (if installed)
docker run -d --name redis-commander \
  --network hvac-test-network \
  -p 8082:8081 \
  rediscommander/redis-commander \
  --redis-host redis-test

Executing Commands

# WordPress CLI
docker compose exec wordpress-test wp [command]

# MySQL CLI
docker compose exec mysql-test mysql -u root -p

# Redis CLI
docker compose exec redis-test redis-cli

# PHP commands
docker compose exec wordpress-test php [script.php]

# Bash shell
docker compose exec wordpress-test bash

Database Operations

Backup and Restore

# Backup database
docker compose exec mysql-test mysqldump \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db > backup-$(date +%Y%m%d).sql

# Restore database
docker compose exec -T mysql-test mysql \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db < backup-20250828.sql

# Export specific tables
docker compose exec mysql-test mysqldump \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db wp_posts wp_postmeta > posts-backup.sql

Database Management

# Connect to MySQL
docker compose exec mysql-test mysql -u root -p

# Common queries
SHOW DATABASES;
USE hvac_test_db;
SHOW TABLES;
DESCRIBE wp_users;

# Check plugin tables
SHOW TABLES LIKE 'wp_hvac%';

# Query examples
SELECT * FROM wp_users WHERE user_login LIKE 'hvac_%';
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'tribe_events';

Reset Database

#!/bin/bash
# reset-database.sh

# Drop and recreate database
docker compose exec mysql-test mysql -u root -p -e "
  DROP DATABASE IF EXISTS hvac_test_db;
  CREATE DATABASE hvac_test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  GRANT ALL ON hvac_test_db.* TO 'hvac_test_user'@'%';
  FLUSH PRIVILEGES;
"

# Reinstall WordPress
docker compose exec wordpress-test wp core install \
  --url="http://localhost:8080" \
  --title="HVAC Test Site" \
  --admin_user="admin" \
  --admin_password="admin123" \
  --admin_email="admin@test.local"

# Reactivate plugins and recreate pages
docker compose exec wordpress-test wp plugin activate hvac-community-events
docker compose exec wordpress-test wp eval 'HVAC_Page_Manager::create_required_pages();'

Test Framework Architecture

Page Object Model (POM)

The test framework uses the Page Object Model pattern for maintainability and reusability:

// Structure
tests/
├── e2e/
   ├── page-objects/
      ├── BasePage.js
      ├── LoginPage.js
      ├── DashboardPage.js
      ├── EventPage.js
      └── VenuePage.js
   ├── fixtures/
      ├── users.json
      ├── events.json
      └── venues.json
   ├── helpers/
      ├── BrowserManager.js
      ├── TestData.js
      └── Utilities.js
   └── tests/
       ├── authentication.test.js
       ├── event-management.test.js
       └── venue-management.test.js

Browser Manager (Singleton)

// BrowserManager.js
const { chromium, firefox, webkit } = require('playwright');

class BrowserManager {
  constructor() {
    if (BrowserManager.instance) {
      return BrowserManager.instance;
    }
    
    this.browser = null;
    this.context = null;
    this.page = null;
    BrowserManager.instance = this;
  }

  async initialize(options = {}) {
    const browserType = options.browser || 'chromium';
    const headless = options.headless !== false;
    
    this.browser = await chromium.launch({
      headless,
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
    });
    
    this.context = await this.browser.newContext({
      viewport: { width: 1920, height: 1080 },
      ignoreHTTPSErrors: true,
      ...options.context,
    });
    
    this.page = await this.context.newPage();
    
    // Set up error handling
    this.page.on('pageerror', error => {
      console.error('Page error:', error.message);
    });
    
    return this.page;
  }

  async cleanup() {
    if (this.page) await this.page.close();
    if (this.context) await this.context.close();
    if (this.browser) await this.browser.close();
  }
}

module.exports = new BrowserManager();

Test Configuration

// test.config.js
module.exports = {
  baseURL: process.env.BASE_URL || 'http://localhost:8080',
  timeout: 30000,
  retries: 2,
  workers: 4,
  
  use: {
    headless: process.env.HEADLESS === 'true',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    trace: 'on-first-retry',
  },
  
  projects: [
    {
      name: 'Chrome',
      use: { browserName: 'chromium' },
    },
    {
      name: 'Firefox',
      use: { browserName: 'firefox' },
    },
    {
      name: 'Safari',
      use: { browserName: 'webkit' },
    },
  ],
  
  reporter: [
    ['html', { outputFolder: 'test-results/html' }],
    ['json', { outputFile: 'test-results/results.json' }],
    ['junit', { outputFile: 'test-results/junit.xml' }],
  ],
};

Running Tests

E2E Test Execution

# Run all tests (headless)
HEADLESS=true BASE_URL=http://localhost:8080 npm test

# Run specific test file
HEADLESS=true npm test -- test-master-trainer-e2e.js

# Run with visible browser
HEADLESS=false npm test

# Run specific test suite
npm test -- --grep "Event Management"

# Run in parallel
npm test -- --workers=4

# Generate HTML report
npm test -- --reporter=html
open test-results/index.html

Test Categories

# Authentication tests
node tests/e2e/auth.test.js

# Event management tests
node tests/e2e/events.test.js

# Venue management tests
node tests/e2e/venues.test.js

# Certificate generation tests
node tests/e2e/certificates.test.js

# Master trainer features
node tests/e2e/master-trainer.test.js

# Performance tests
node tests/performance/load-test.js

Cross-Browser Testing

# Chrome
BROWSER=chromium npm test

# Firefox
BROWSER=firefox npm test

# Safari (WebKit)
BROWSER=webkit npm test

# All browsers sequentially
npm run test:cross-browser

# All browsers in parallel
npm run test:cross-browser:parallel

Visual Regression Testing

# Capture baseline screenshots
npm run test:visual:baseline

# Run visual comparison tests
npm run test:visual:compare

# Update baseline images
npm run test:visual:update

# View diff report
open test-results/visual-diff/index.html

Debugging

Debug Mode

// Enable debug mode in tests
const DEBUG = process.env.DEBUG === 'true';

if (DEBUG) {
  // Slow down actions
  page.setDefaultTimeout(60000);
  
  // Pause on failures
  page.on('pageerror', async () => {
    await page.pause();
  });
  
  // Take screenshots at each step
  afterEach(async () => {
    await page.screenshot({ 
      path: `debug/step-${Date.now()}.png` 
    });
  });
}

Interactive Debugging

# Launch browser with DevTools
PWDEBUG=1 node test-file.js

# Use Playwright Inspector
npx playwright test --debug

# Pause at specific point
await page.pause(); // Add in test code

Container Debugging

# View container logs
docker compose logs -f wordpress-test

# Access container shell
docker compose exec wordpress-test bash

# Check PHP errors
docker compose exec wordpress-test tail -f /var/log/apache2/error.log

# Monitor MySQL queries
docker compose exec mysql-test tail -f /var/log/mysql/query.log

# Debug WordPress
docker compose exec wordpress-test wp shell

Network Debugging

# Monitor network traffic
docker compose exec wordpress-test tcpdump -i any -w traffic.pcap

# Check container connectivity
docker compose exec wordpress-test ping mysql-test

# Inspect Docker network
docker network inspect hvac-test-network

# Port forwarding issues
netstat -tuln | grep 8080

Performance Testing

Load Testing Setup

// load-test.js
const { chromium } = require('playwright');
const { performance } = require('perf_hooks');

async function loadTest(config) {
  const { concurrent = 10, iterations = 100 } = config;
  const results = [];
  
  const runTest = async () => {
    const start = performance.now();
    const browser = await chromium.launch({ headless: true });
    const page = await browser.newPage();
    
    await page.goto('http://localhost:8080/trainer/dashboard/');
    await page.waitForSelector('.hvac-dashboard');
    
    const end = performance.now();
    await browser.close();
    
    return end - start;
  };
  
  // Run concurrent tests
  for (let i = 0; i < iterations; i += concurrent) {
    const batch = Array(concurrent).fill().map(() => runTest());
    const times = await Promise.all(batch);
    results.push(...times);
  }
  
  // Calculate statistics
  const avg = results.reduce((a, b) => a + b, 0) / results.length;
  const max = Math.max(...results);
  const min = Math.min(...results);
  
  console.log(`Average: ${avg}ms, Max: ${max}ms, Min: ${min}ms`);
}

// Run load test
loadTest({ concurrent: 20, iterations: 200 });

Performance Metrics

# Monitor container resources
docker stats

# MySQL performance
docker compose exec mysql-test mysqladmin -u root -p status

# Redis performance
docker compose exec redis-test redis-cli INFO stats

# Apache performance
docker compose exec wordpress-test apache2ctl -S

Troubleshooting

Common Issues

Container won't start

# Check for port conflicts
lsof -i :8080
lsof -i :3307

# Kill conflicting processes
kill -9 $(lsof -t -i:8080)

# Reset Docker
docker system prune -a
docker volume prune

Database connection errors

# Verify MySQL is running
docker compose ps mysql-test

# Check MySQL logs
docker compose logs mysql-test

# Test connection
docker compose exec wordpress-test wp db check

# Reset MySQL password
docker compose exec mysql-test mysql -u root -e "
  ALTER USER 'hvac_test_user'@'%' IDENTIFIED BY 'hvac_test_password';
  FLUSH PRIVILEGES;
"

Plugin activation fails

# Check PHP errors
docker compose exec wordpress-test tail -f /var/log/apache2/error.log

# Verify plugin files
docker compose exec wordpress-test ls -la /var/www/html/wp-content/plugins/hvac-community-events/

# Debug plugin activation
docker compose exec wordpress-test wp plugin activate hvac-community-events --debug

Tests timing out

// Increase timeout in test
test.setTimeout(60000);

// Or globally
module.exports = {
  timeout: 60000,
  // ...
};

// Debug slow operations
console.time('operation');
await slowOperation();
console.timeEnd('operation');

Reset Everything

#!/bin/bash
# full-reset.sh

# Stop and remove all containers
docker compose -f docker-compose.test.yml down -v

# Remove all test data
rm -rf wordpress_test_data/
rm -rf mysql_test_data/
rm -rf redis_test_data/

# Clean Docker system
docker system prune -a --volumes

# Rebuild and start fresh
docker compose -f docker-compose.test.yml up -d --build

# Wait for healthy state
sleep 30

# Initialize WordPress
./scripts/init-wordpress.sh

# Seed test data
./scripts/seed-all-data.sh

Best Practices

Development Workflow

  1. Branch Strategy

    # Create feature branch
    git checkout -b feature/new-venue-system
    
    # Make changes and test locally
    docker compose up -d
    npm test
    
    # Commit with conventional commits
    git commit -m "feat: implement new venue management system"
    
  2. Test-Driven Development

    // Write test first
    test('should create new venue', async () => {
      await venuePage.createVenue({
        name: 'Test Venue',
        address: '123 Test St',
      });
    
      expect(await venuePage.venueExists('Test Venue')).toBe(true);
    });
    
    // Then implement feature
    
  3. Data Isolation

    // Use unique test data
    const testId = Date.now();
    const venueName = `Venue_${testId}`;
    
    // Clean up after tests
    afterEach(async () => {
      await cleanup(testId);
    });
    

Code Quality

  1. Linting

    # JavaScript
    npm run lint
    
    # PHP
    docker compose exec wordpress-test ./vendor/bin/phpcs
    
    # Fix automatically
    npm run lint:fix
    
  2. Code Coverage

    # Generate coverage report
    npm run test:coverage
    
    # View report
    open coverage/index.html
    
  3. Security Scanning

    # Scan for vulnerabilities
    npm audit
    
    # PHP dependencies
    docker compose exec wordpress-test ./vendor/bin/security-checker security:check
    

Performance Optimization

  1. Container Resources

    # docker-compose.yml
    services:
      wordpress-test:
        deploy:
          resources:
            limits:
              cpus: '2'
              memory: 2G
            reservations:
              cpus: '1'
              memory: 1G
    
  2. Caching Strategy

    # Enable Redis object cache
    docker compose exec wordpress-test wp plugin install redis-cache --activate
    docker compose exec wordpress-test wp redis enable
    
  3. Database Optimization

    -- Add indexes
    ALTER TABLE wp_posts ADD INDEX idx_type_status (post_type, post_status);
    ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key);
    
    -- Optimize tables
    OPTIMIZE TABLE wp_posts;
    OPTIMIZE TABLE wp_postmeta;
    

Advanced Configuration

Custom Docker Network

# docker-compose.override.yml
networks:
  hvac-test-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

SSL Configuration

# Generate self-signed certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout nginx/ssl/private.key \
  -out nginx/ssl/certificate.crt

# Add nginx proxy container
services:
  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl

Multi-Site Testing

# Enable WordPress Multisite
environment:
  WORDPRESS_CONFIG_EXTRA: |
    define('WP_ALLOW_MULTISITE', true);
    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', false);
    define('DOMAIN_CURRENT_SITE', 'localhost');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE', 1);    

CI/CD Integration

# .github/workflows/test.yml
name: E2E Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Start Docker Compose
        run: |
          docker compose -f tests/docker-compose.test.yml up -d
          sleep 30          
      
      - name: Initialize WordPress
        run: |
          docker compose exec -T wordpress-test wp core install \
            --url="http://localhost:8080" \
            --title="Test" \
            --admin_user="admin" \
            --admin_password="admin123" \
            --admin_email="test@test.com"          
      
      - name: Run Tests
        run: |
          npm ci
          npm test          
      
      - name: Upload Results
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-results
          path: test-results/

Quick Reference

Essential Commands

# Start environment
docker compose -f tests/docker-compose.test.yml up -d

# Stop environment
docker compose -f tests/docker-compose.test.yml down

# View logs
docker compose -f tests/docker-compose.test.yml logs -f

# Run tests
HEADLESS=true npm test

# Access WordPress
open http://localhost:8080

# Access database
open http://localhost:8081

# View emails
open http://localhost:8025

# Shell access
docker compose exec wordpress-test bash

# WP-CLI
docker compose exec wordpress-test wp [command]

Service URLs

Service URL Credentials
WordPress http://localhost:8080 admin / admin123
WordPress Admin http://localhost:8080/wp-admin admin / admin123
PhpMyAdmin http://localhost:8081 hvac_test_user / hvac_test_password
Mailhog http://localhost:8025 No auth required
Redis Commander http://localhost:8082 No auth required

File Locations

# Plugin source
./

# Test files
./tests/

# Docker config
./tests/docker-compose.test.yml

# Test results
./test-results/

# Screenshots
./screenshots/

# Fixtures
./tests/fixtures/

This guide is maintained by the HVAC Community Events development team. For updates or issues, please submit a pull request or open an issue in the repository.

Document Version: 2.0.0
Last Updated: August 28, 2025
Next Review: September 28, 2025