- Add hvac_master_trainer role with enhanced capabilities including view_master_dashboard, view_all_trainer_data, manage_google_sheets_integration - Create HVAC_Master_Dashboard_Data class for system-wide analytics aggregating data across all trainers - Implement Master Dashboard template using existing harmonized CSS framework showing total events, revenue, trainer performance - Add hvac_master_dashboard shortcode with proper authentication and permission checks - Update plugin activation to create master trainer role and master dashboard page - Grant administrators access to all master trainer capabilities - Add template routing and authentication checks for master dashboard access - Extend asset loading to include master dashboard styling using existing dashboard CSS - Create trainer performance analytics table and system overview statistics - Structure data for future Google Sheets integration compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
25 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
HVAC Community Events is a WordPress plugin system that enables independent trainers to manage their own events, sell tickets, and track performance without accessing the WordPress admin panel. It extends The Events Calendar (TEC) plugin suite with custom functionality for the HVAC training industry.
The system uses a Cloudways staging environment for development and testing, with comprehensive Playwright E2E tests and PHPUnit tests. The project has migrated from Docker-based local development to a staging-only workflow.
Key Commands
Testing
E2E Test Structure (Consolidated 2025-05-23)
The E2E test suite has been completely consolidated from 85+ files to a focused, maintainable structure. ALWAYS use the consolidated tests - the old duplicate tests have been removed.
Primary Test Command (RECOMMENDED)
# Run the main working test suite (RECOMMENDED FOR ALL TESTING)
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=line
# This single command tests:
# ✅ Dashboard and basic navigation
# ✅ Create Event page accessibility (14 form elements)
# ✅ Certificate Reports page (79+ data elements)
# ✅ Generate Certificates functionality (17 events available)
# ✅ Trainer Profile page (/trainer-profile/)
# ✅ Complete page navigation flow
# ✅ Error monitoring (0 PHP errors expected)
Test Suite Organization
tests/e2e/
├── fixtures/
│ └── auth.ts # Shared authentication utilities
├── utils/
│ └── common-actions.ts # Reusable test actions and helpers
├── final-working-tests.test.ts # 🎯 MAIN TEST SUITE (USE THIS)
├── trainer-journey-optimized.test.ts # Optimized trainer workflow tests
├── certificate-optimized.test.ts # Optimized certificate tests
├── trainer-journey-final.test.ts # Legacy comprehensive journey
├── trainer-journey-harmonized.test.ts # Page Object Model approach
├── certificate-core.test.ts # Certificate generation/viewing
├── certificate-management.test.ts # Bulk operations/reporting
├── certificate-edge-cases.test.ts # Error handling/validation
├── help-system-*.test.ts # Help system components (4 files)
└── [Legacy tests still available but consolidated ones are preferred]
Running Tests
# RECOMMENDED: Run main comprehensive test suite
npx playwright test tests/e2e/final-working-tests.test.ts
# Run with browser visible for debugging
npx playwright test tests/e2e/final-working-tests.test.ts --headed
# Run with Playwright inspector for debugging
npx playwright test tests/e2e/final-working-tests.test.ts --debug
# Run specific optimized test suites
npx playwright test tests/e2e/trainer-journey-optimized.test.ts # 4 trainer workflow tests
npx playwright test tests/e2e/certificate-optimized.test.ts # 4 certificate tests
# Run legacy consolidated tests (if needed)
npx playwright test tests/e2e/trainer-journey-final.test.ts # Comprehensive journey
npx playwright test tests/e2e/certificate-core.test.ts # Core certificate functionality
# Run help system tests (well-organized, no changes needed)
npx playwright test tests/e2e/help-system-*.test.ts
# Run specific test by name pattern
npx playwright test --grep "Dashboard and basic navigation"
npx playwright test --grep "Certificate Reports"
npx playwright test --grep "Create Event"
# Run with different reporters
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=html # HTML report
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=json # JSON output
Test Development Setup
# 1. Always set up test environment first
./bin/create-test-users.sh # Create test_trainer user
./bin/create-test-events-admin.sh # Create test events (if needed)
# 2. Verify staging environment
./bin/verify-staging.sh # Check staging is accessible
# 3. Run tests
npx playwright test tests/e2e/final-working-tests.test.ts
PHPUnit Tests
# Run PHPUnit tests on staging
./bin/run-staging-unit-tests.sh
./bin/run-staging-unit-tests.sh --testsuite unit
./bin/run-staging-unit-tests.sh --coverage-html ./coverage-report
./bin/run-staging-unit-tests.sh --filter=test_get_total_events_count
Legacy Test Commands (Use only if needed)
# These are kept for reference but use consolidated tests above
./bin/run-tests.sh --e2e # Old test runner
./bin/run-tests.sh --e2e --grep @certificate # Old pattern-based running
Common Issues & Solutions
# Issue: Tests timing out
# Solution: Use final-working-tests.test.ts which has optimized timeouts
# Issue: Profile page not found
# Solution: Correct URL is /trainer-profile/ not /community-profile/
# Issue: Create Event form fields not found
# Solution: Use #event_title not #post_title for title field
# Issue: Certificate attendee selection hanging
# Solution: Use optimized tests that don't interact with problematic elements
# Issue: Navigation elements not found
# Solution: Use .first() for elements that may have duplicates
# Issue: CSS selector syntax errors
# Solution: Avoid regex in selectors, use text content matching instead
Deployment & Staging
# Deploy plugin to staging (MAIN DEPLOYMENT COMMAND)
./wordpress-dev/bin/deploy-plugin.sh --config ./wordpress-dev/bin/deploy-config-staging.sh
# Verify staging environment
./wordpress-dev/bin/verify-staging.sh
# Deploy config to staging
./wordpress-dev/bin/deploy-config-staging.sh
# Run PHPUnit tests on staging
./wordpress-dev/bin/run-staging-unit-tests.sh
# Create test users for E2E testing
./wordpress-dev/bin/create-test-users.sh
# Create test events for E2E testing
./wordpress-dev/bin/create-test-events-admin.sh
# Complete staging workflow sequence
./wordpress-dev/bin/deploy-plugin.sh --config ./wordpress-dev/bin/deploy-config-staging.sh
./wordpress-dev/bin/verify-staging.sh
./wordpress-dev/bin/create-test-users.sh
./wordpress-dev/bin/create-test-events-admin.sh
npx playwright test tests/e2e/final-working-tests.test.ts
Build and Lint Commands
# Run PHPUnit tests with coverage
composer test
composer test:verbose
composer test:coverage
# Manual PHPUnit execution
phpunit --bootstrap tests/bootstrap-staging.php --testdox --colors=always
# Install/update Composer dependencies
composer install
composer update
Memory Entries
- Do not make standalone 'fixes' which upload separate from the plugin deployment. Instead, always redeploy the whole plugin with your fixes. Before deploying, always remove the old versions of the plugin. Always activate and verify after plugin upload
- The deployment process now automatically clears Breeze cache after plugin activation through wp-cli. This ensures proper cache invalidation and prevents stale content issues.
Help System Implementation
The HVAC Community Events plugin includes a comprehensive help system with three main components:
Features
- Interactive Welcome Guide: Modal with 4 cards that appears on first login, includes navigation controls and cookie-based dismissal
- Tooltips System: Contextual help throughout custom pages with hover activation and positioning
- Documentation Page: Complete step-by-step directions and FAQs accessible via dashboard navigation
Files
includes/class-hvac-help-system.php: Core help system functionalityassets/css/hvac-help-system.css: Styling for modals, tooltips, and documentationassets/js/hvac-help-system.js: JavaScript for interactive elements and navigationtests/e2e/help-system-*.test.ts: Comprehensive E2E test suite (40+ test cases)
Recent Fixes (2025-05-22)
- Removed duplicate 'My Events' button from dashboard navigation
- Removed duplicate 'Help' link while maintaining tooltip functionality
- Fixed 'Create Event' page showing shortcode instead of form by implementing custom shortcode handler
- Fixed 'Certificate Reports' critical error by removing problematic debug statements
- Enhanced dashboard with proper tooltips and contextual help
How to Write and Modify E2E Tests
When to Modify Tests
Use final-working-tests.test.ts for most modifications - this is the main comprehensive test suite that covers all functionality.
Adding New Test Cases
// Add to tests/e2e/final-working-tests.test.ts
test('Your new test description', async ({ authenticatedPage: page }) => {
test.setTimeout(20000); // Set appropriate timeout
const actions = new CommonActions(page);
// Your test logic here
await actions.navigateAndWait('/your-page/');
await expect(page.locator('h1')).toBeVisible();
await actions.screenshot('your-test-step');
});
Modifying Existing Tests
- Identify the test in
final-working-tests.test.ts - Update the test logic while maintaining the same structure
- Run the test to verify it works:
npx playwright test tests/e2e/final-working-tests.test.ts --grep "test name" - Update expectations if functionality has changed
Creating New Test Files (Only if needed)
// Pattern: tests/e2e/feature-name.test.ts
import { test, expect } from './fixtures/auth';
import { CommonActions } from './utils/common-actions';
test.describe('Feature Name Tests', () => {
test('Specific functionality test', async ({ authenticatedPage: page }) => {
test.setTimeout(25000);
const actions = new CommonActions(page);
// Test implementation
});
});
Essential Patterns and Utilities
Using Shared Authentication
// ALWAYS use this pattern for authenticated tests
import { test, expect } from './fixtures/auth';
test('My test', async ({ authenticatedPage: page }) => {
// Page is already logged in as test_trainer
await expect(page).toHaveURL(/hvac-dashboard/);
});
Using Common Actions
import { CommonActions } from './utils/common-actions';
test('My test', async ({ authenticatedPage: page }) => {
const actions = new CommonActions(page);
// Navigate safely with wait
await actions.navigateAndWait('/target-page/');
// Take screenshots for debugging
await actions.screenshot('test-step-name');
// Verify navigation elements
await actions.verifyNavigation();
// Wait for complex AJAX operations
await actions.waitForComplexAjax();
// Generate unique test data
const testData = actions.generateTestData('Event');
await page.fill('#event_title', testData.title);
});
Safe Element Selection Patterns
// ✅ GOOD: Handle multiple headings safely
await expect(page.locator('h1, h2').filter({ hasText: /pattern/i }).first()).toBeVisible();
// ✅ GOOD: Use flexible selectors for form fields
const titleField = page.locator('#event_title, #post_title, input[name="post_title"]');
await expect(titleField.first()).toBeVisible();
// ✅ GOOD: Check for elements before interacting
const submitButton = page.locator('button[type="submit"]');
if (await submitButton.count() > 0) {
await expect(submitButton.first()).toBeVisible();
}
// ❌ AVOID: Brittle single selectors
await page.locator('#specific-id'); // May break if ID changes
// ❌ AVOID: Regex in CSS selectors
await page.locator('span:text(/^\d+$/)'); // Causes syntax errors
Form Interaction Patterns
// ✅ GOOD: Event title field (correct selector)
await page.fill('#event_title', 'My Event Title');
// ✅ GOOD: Flexible description field handling
try {
// Try TinyMCE first
const frame = page.frameLocator('iframe[id*="_ifr"]');
await frame.locator('body').fill('Description text');
} catch {
// Fallback to textarea
await page.fill('#event_content, textarea[name="content"]', 'Description text');
}
// ✅ GOOD: Event selection with AJAX wait
await page.selectOption('select[name="event_id"]', { index: 1 });
await actions.waitForComplexAjax(); // Wait for attendees to load
Error Handling Patterns
// ✅ GOOD: Monitor for PHP errors
const phpErrors = [];
page.on('console', (msg) => {
if (msg.type() === 'error' && msg.text().includes('PHP')) {
phpErrors.push(msg.text());
}
});
// Test pages...
expect(phpErrors.length).toBe(0); // Fail on PHP errors
Key URLs and Selectors
Correct Page URLs
Dashboard: /hvac-dashboard/
Create Event: /manage-event/
Certificate Reports: /certificate-reports/
Generate Certs: /generate-certificates/
Trainer Profile: /trainer-profile/ # NOT /community-profile/
Key Form Selectors
// Event Creation Form
'#event_title' // Event title field
'#event_content' // Event description
'select[name="event_id"]' // Event selection dropdown
'iframe[id*="_ifr"]' // TinyMCE editor frame
// Navigation Elements
'a[href*="hvac-dashboard"]' // Dashboard links
'text=Generate Certificates' // Navigation buttons
'text=Create Event' // Navigation buttons
// Statistics and Data
'.stat-value' // Statistics displays
'.stat-number' // Numeric statistics
'.dashboard-stat' // Dashboard statistics
Test Performance Guidelines
Timeout Management
// ✅ GOOD: Set appropriate timeouts
test.setTimeout(20000); // 20 seconds for simple tests
test.setTimeout(30000); // 30 seconds for complex workflows
test.setTimeout(45000); // 45 seconds for comprehensive journeys
// ✅ GOOD: Use built-in waits
await page.waitForLoadState('networkidle');
await actions.waitForComplexAjax();
// ❌ AVOID: Arbitrary timeouts
await page.waitForTimeout(5000); // Use sparingly
Screenshot Strategy
// ✅ GOOD: Meaningful screenshot names
await actions.screenshot('login-completed');
await actions.screenshot('event-form-filled');
await actions.screenshot('certificate-generated');
// ✅ GOOD: Screenshots at verification points
await actions.screenshot('page-loaded');
await expect(page.locator('h1')).toBeVisible();
await actions.screenshot('heading-verified');
Debugging Failed Tests
Common Debugging Commands
# Run with visual browser to see what's happening
npx playwright test tests/e2e/final-working-tests.test.ts --headed
# Run with debugger to step through
npx playwright test tests/e2e/final-working-tests.test.ts --debug
# Run specific failing test
npx playwright test --grep "Create Event page accessibility"
# Generate HTML report with screenshots
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=html
npx playwright show-report
Reading Test Failures
# Timeout errors: Increase test timeout or fix selectors
# Element not found: Check if selectors are correct
# Navigation failed: Verify URLs and page structure
# PHP errors: Check staging environment and plugin status
Test Maintenance Checklist
Before Modifying Tests
- ✅ Run existing tests to ensure they pass
- ✅ Understand what functionality the test covers
- ✅ Check if changes affect other tests
- ✅ Use existing patterns and utilities
After Modifying Tests
- ✅ Run the modified test to ensure it passes
- ✅ Run the full test suite to check for regressions
- ✅ Update documentation if test structure changes
- ✅ Commit changes with descriptive messages
When Tests Start Failing
- ✅ Check if staging environment is accessible
- ✅ Verify test user (test_trainer) exists and works
- ✅ Check for WordPress/plugin updates that changed UI
- ✅ Look for PHP errors in console output
- ✅ Update selectors if page structure changed
Quick Reference Commands
Most Common Commands (Copy-Paste Ready)
# Run main test suite (MOST COMMON)
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=line
# Debug with visual browser
npx playwright test tests/e2e/final-working-tests.test.ts --headed
# Run specific test
npx playwright test --grep "Dashboard and basic navigation"
# Generate HTML report
npx playwright test tests/e2e/final-working-tests.test.ts --reporter=html
npx playwright show-report
# Set up test environment
./bin/create-test-users.sh && ./bin/verify-staging.sh
File Locations Quick Reference
Main Test Suite: tests/e2e/final-working-tests.test.ts
Auth Fixture: tests/e2e/fixtures/auth.ts
Common Actions: tests/e2e/utils/common-actions.ts
Test Screenshots: test-results/screenshots/
Test Reports: playwright-report/
Essential Test Patterns (Copy-Paste Ready)
// Basic test structure
test('Test name', async ({ authenticatedPage: page }) => {
test.setTimeout(20000);
const actions = new CommonActions(page);
await actions.navigateAndWait('/page-url/');
await expect(page.locator('h1').first()).toBeVisible();
await actions.screenshot('test-completed');
});
// Form interaction
await page.fill('#event_title', 'Test Event');
const value = await page.locator('#event_title').inputValue();
expect(value).toBe('Test Event');
// Navigation verification
await actions.verifyNavigation();
await expect(page).toHaveURL(/hvac-dashboard/);
E2E Testing Best Practices
Test Structure and Organization (Consolidated 2025-05-23)
The E2E test suite has been consolidated from 85+ files to a focused, maintainable structure:
Core Test Suites
tests/e2e/
├── fixtures/
│ └── auth.ts # Shared authentication utilities
├── utils/
│ └── common-actions.ts # Reusable test actions and helpers
├── config/
│ └── staging-config.ts # Test configuration
├── pages/ # Page Object Models (where used)
├── trainer-journey-final.test.ts # Comprehensive user journey (direct approach)
├── trainer-journey-harmonized.test.ts # User journey with Page Objects
├── certificate-core.test.ts # Certificate generation and viewing
├── certificate-management.test.ts # Bulk operations and reporting
├── certificate-edge-cases.test.ts # Error handling and validation
├── certificates.test.ts # Legacy comprehensive certificate suite
├── dashboard.test.ts # Dashboard functionality
├── help-system-*.test.ts # Help system components (4 files)
└── login.test.ts # Authentication testing
Writing New E2E Tests
1. Use Shared Utilities:
import { test, expect } from './fixtures/auth';
import { CommonActions } from './utils/common-actions';
test('My test', async ({ authenticatedPage: page }) => {
const actions = new CommonActions(page);
await actions.navigateAndWait('/my-page/');
await actions.screenshot('test-step');
});
2. Test Categories and Tags:
- Use
@tagcomments for test organization - Core functionality:
@login,@dashboard,@certificates,@events - Help system:
@help-system,@tooltips,@documentation - Edge cases:
@edge-cases,@error-handling,@validation
3. Test Independence:
- Each test should be self-contained
- Use unique test data with timestamps
- Clean up test data when possible
- Don't rely on other tests' side effects
4. Error Handling:
- Always check for PHP errors in console
- Use explicit waits (
waitForLoadState('networkidle')) - Handle missing elements gracefully
- Test both success and failure scenarios
5. Performance Guidelines:
- Page load should complete within 10 seconds
- Use
actions.waitForAjax()after AJAX operations - Take screenshots at key verification points
- Batch similar operations when possible
Running Tests Efficiently
# Run specific test categories
npx playwright test --grep @certificates
npx playwright test --grep @help-system
# Run single test file with debugging
npx playwright test certificate-core.test.ts --headed
# Run tests in parallel (default)
npx playwright test tests/e2e/ --workers=3
# Generate test report
npx playwright show-report
Common Test Patterns
Navigation and Verification:
await actions.navigateAndWait('/target-page/');
await actions.verifyNavigation();
await expect(page.locator('h1')).toBeVisible();
Form Testing:
const testData = actions.generateTestData('Event');
await page.fill('#title', testData.title);
await actions.fillTinyMCE('#description', testData.description);
AJAX Testing:
await page.selectOption('select[name="event_id"]', { index: 1 });
await actions.waitForAjax();
await expect(page.locator('input[name="attendee_ids[]"]')).toBeVisible();
Maintenance Guidelines
-
Before Adding New Tests:
- Check if functionality is already covered
- Use existing test files when appropriate
- Consider consolidating related tests
-
File Naming Convention:
feature-core.test.tsfor main functionalityfeature-management.test.tsfor admin/bulk operationsfeature-edge-cases.test.tsfor error handlingfeature-integration.test.tsfor cross-feature testing
-
Test Data Management:
- Use
actions.generateTestData()for unique names - Avoid hardcoded test data that may conflict
- Clean up created test data when possible
- Use
-
Screenshot Strategy:
- Take screenshots at verification points
- Use descriptive names with timestamps
- Organize in
test-results/screenshots/
Troubleshooting Common Issues
-
Flaky Tests:
- Add explicit waits after navigation
- Use
waitForLoadState('networkidle') - Check for race conditions in AJAX calls
-
Selector Issues:
- Use stable selectors (IDs over classes)
- Prefer text content when selectors change
- Test selectors in browser console first
-
Authentication Issues:
- Use
authenticatedPagefixture for most tests - Verify login redirect works properly
- Check test user exists and has correct permissions
- Use
-
Page Load Issues:
- Ensure staging environment is accessible
- Check for JavaScript errors in console
- Verify plugin is activated and functioning
Architecture Overview
Plugin Architecture: Singleton-Based Modular WordPress Plugin
The HVAC Community Events plugin follows a traditional WordPress plugin architecture with modern organizational patterns:
Core Structure
- Entry Point:
hvac-community-events.phpwith standard WordPress plugin headers - Main Class:
HVAC_Community_Events(singleton pattern) - Central orchestrator - Modular Organization: Feature-based class organization in
includes/directory - Shortcode-Driven Frontend: All user-facing functionality via WordPress shortcodes
Key Subsystems
Core Systems (includes/):
- Authentication & Roles: Custom
hvac_trainerrole with capabilities - Dashboard Data:
class-hvac-dashboard-data.php- Event analytics and reporting - Event Handling:
class-event-form-handler.php,class-event-author-fixer.php - Help System:
class-hvac-help-system.php- Interactive user guidance - Logging:
class-hvac-logger.php- Centralized debug logging
Feature Modules (includes/community/):
- Login/Registration flow
- Event management (CRUD operations)
- Email communication with attendees
- Event summary and analytics
Third-Party Integration (includes/zoho/):
- Zoho CRM OAuth integration with staging/production modes
- Automated contact synchronization
Deployment Architecture
Cloudways-Only Workflow: No local development environment
- Staging Server:
146.190.76.204(Cloudways) - Deployment Method: SSH + WP-CLI automation
- Cache Management: Automated Breeze cache clearing
- Plugin Structure: Deployed to
wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/
Integration Points
The Events Calendar (TEC) Suite Integration:
- Extends Community Events plugin functionality
- Custom shortcode:
[tribe_community_events view="submission_form"] - Event post type integration with trainer capabilities
- Template override system via WordPress
template_includefilter
WordPress Standards:
- Hook-based architecture (actions/filters)
- Custom post types and capabilities
- Proper nonce verification and sanitization
- Role-based access control
Testing Strategy
Multi-Layer Approach:
- PHPUnit: Unit tests with staging environment integration
- Playwright E2E: Browser automation with consolidated test suite
- Test Data Management: Automated test user and event creation
- Performance Testing: Page load and AJAX operation verification
Key Design Patterns
- Singleton Pattern: Core classes for centralized control
- Template Override: Custom frontend without theme dependency
- Progressive Enhancement: Help system with guided workflows
- Environment Awareness: Staging/production configuration switching
- Modular Loading: Conditional asset loading for performance