upskill-event-manager/CLAUDE.md
bengizmo dea1200efb feat: Add comprehensive UX enhancements for mobile and desktop
- Create modern toast notification system replacing browser alerts
- Add mobile-responsive layouts with touch-friendly elements
- Implement loading states and progress indicators for all AJAX operations
- Add mobile navigation with collapsible menus
- Create enhanced form validation with inline error messages
- Add accessibility features (keyboard navigation, ARIA labels)
- Build comprehensive mobile testing suite
- Optimize for 320px to 1024px+ screen sizes
- Include progressive enhancement and fallback support

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-23 16:41:01 -03:00

22 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.

# 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
./bin/deploy-plugin.sh

# Deploy to production
./deploy.sh --config deploy-config.sh

# Deploy and run tests
./deploy.sh --config deploy-config.sh --run-tests

# Verify staging environment
./bin/verify-staging.sh

# Deploy config to staging
./bin/deploy-config-staging.sh

# Sync data from staging
./bin/sync-staging.sh

# Staging workflow sequence
deploy-config-staging.sh → configure-staging-tests.sh → run-staging-tests.sh

Memory Management System

# Update knowledge graph after deployment
./deploy.sh --config deploy-config.sh --update-memory

# Generate action items after testing
cd tests && ./run-tests.sh --generate-action-items

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

  1. Interactive Welcome Guide: Modal with 4 cards that appears on first login, includes navigation controls and cookie-based dismissal
  2. Tooltips System: Contextual help throughout custom pages with hover activation and positioning
  3. Documentation Page: Complete step-by-step directions and FAQs accessible via dashboard navigation

Files

  • includes/class-hvac-help-system.php: Core help system functionality
  • assets/css/hvac-help-system.css: Styling for modals, tooltips, and documentation
  • assets/js/hvac-help-system.js: JavaScript for interactive elements and navigation
  • tests/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

  1. Identify the test in final-working-tests.test.ts
  2. Update the test logic while maintaining the same structure
  3. Run the test to verify it works: npx playwright test tests/e2e/final-working-tests.test.ts --grep "test name"
  4. 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

  1. Run existing tests to ensure they pass
  2. Understand what functionality the test covers
  3. Check if changes affect other tests
  4. Use existing patterns and utilities

After Modifying Tests

  1. Run the modified test to ensure it passes
  2. Run the full test suite to check for regressions
  3. Update documentation if test structure changes
  4. Commit changes with descriptive messages

When Tests Start Failing

  1. Check if staging environment is accessible
  2. Verify test user (test_trainer) exists and works
  3. Check for WordPress/plugin updates that changed UI
  4. Look for PHP errors in console output
  5. 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 @tag comments 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

  1. Before Adding New Tests:

    • Check if functionality is already covered
    • Use existing test files when appropriate
    • Consider consolidating related tests
  2. File Naming Convention:

    • feature-core.test.ts for main functionality
    • feature-management.test.ts for admin/bulk operations
    • feature-edge-cases.test.ts for error handling
    • feature-integration.test.ts for cross-feature testing
  3. Test Data Management:

    • Use actions.generateTestData() for unique names
    • Avoid hardcoded test data that may conflict
    • Clean up created test data when possible
  4. Screenshot Strategy:

    • Take screenshots at verification points
    • Use descriptive names with timestamps
    • Organize in test-results/screenshots/

Troubleshooting Common Issues

  1. Flaky Tests:

    • Add explicit waits after navigation
    • Use waitForLoadState('networkidle')
    • Check for race conditions in AJAX calls
  2. Selector Issues:

    • Use stable selectors (IDs over classes)
    • Prefer text content when selectors change
    • Test selectors in browser console first
  3. Authentication Issues:

    • Use authenticatedPage fixture for most tests
    • Verify login redirect works properly
    • Check test user exists and has correct permissions
  4. Page Load Issues:

    • Ensure staging environment is accessible
    • Check for JavaScript errors in console
    • Verify plugin is activated and functioning

Architecture Overview

[... rest of the file remains unchanged ...]