diff --git a/wordpress-dev/tests/e2e/plugin-functionality-comprehensive.test.ts b/wordpress-dev/tests/e2e/plugin-functionality-comprehensive.test.ts new file mode 100644 index 00000000..126d2436 --- /dev/null +++ b/wordpress-dev/tests/e2e/plugin-functionality-comprehensive.test.ts @@ -0,0 +1,390 @@ +/** + * Comprehensive E2E Tests for HVAC Plugin Functionality + * + * Tests all recent fixes and enhancements: + * 1. Certificate Reports page functionality + * 2. Generate Certificates page functionality + * 3. Navigation updates (no My Events links) + * 4. Create Event page behavior + * 5. PHP error monitoring + */ + +import { test, expect } from './fixtures/auth'; +import { CommonActions } from './utils/common-actions'; + +test.describe('HVAC Plugin Comprehensive Functionality Tests', () => { + test.beforeEach(async ({ page }) => { + // Monitor for PHP errors throughout all tests + page.on('console', (msg) => { + if (msg.type() === 'error' && msg.text().includes('PHP')) { + console.error('PHP Error detected:', msg.text()); + } + }); + }); + + test('Dashboard Navigation - Verify correct links and no My Events', async ({ authenticatedPage: page }) => { + test.setTimeout(30000); + const actions = new CommonActions(page); + + await actions.navigateAndWait('/hvac-dashboard/'); + await actions.screenshot('dashboard-navigation'); + + // Check that My Events links are removed + const myEventsLinks = await page.locator('a[href*="my-events"]').count(); + expect(myEventsLinks).toBe(0); + console.log('✅ No My Events links found on dashboard'); + + // Verify all navigation buttons are present + const navButtons = [ + { text: 'Create Event', exists: true }, + { text: 'Certificate Reports', exists: true }, + { text: 'Generate Certificates', exists: true }, + { text: 'View Profile', exists: true }, + { text: 'Help', exists: true }, + { text: 'My Events', exists: false } // Should NOT exist + ]; + + for (const button of navButtons) { + const count = await page.locator(`.hvac-dashboard-nav a:has-text("${button.text}")`).count(); + if (button.exists) { + expect(count).toBeGreaterThan(0); + console.log(`✅ ${button.text} button found`); + } else { + expect(count).toBe(0); + console.log(`✅ ${button.text} button correctly absent`); + } + } + }); + + test('Certificate Reports - Full functionality test', async ({ authenticatedPage: page }) => { + test.setTimeout(45000); + const actions = new CommonActions(page); + + await actions.navigateAndWait('/certificate-reports/'); + await actions.screenshot('certificate-reports-loaded'); + + // Check page elements + await expect(page.locator('h1').first()).toContainText('Certificate Reports'); + + // Verify statistics section + const statsSection = page.locator('.hvac-certificate-stats'); + await expect(statsSection).toBeVisible(); + + const statCards = await page.locator('.hvac-stat-card').count(); + expect(statCards).toBe(4); // Total, Active, Revoked, Emailed + console.log('✅ All 4 statistics cards present'); + + // Check each stat card has a value + const statValues = await page.locator('.hvac-stat-value').allTextContents(); + expect(statValues.length).toBe(4); + statValues.forEach((value, index) => { + expect(value).toMatch(/^\d+$/); // Should be a number + }); + console.log(`✅ Statistics values: Total=${statValues[0]}, Active=${statValues[1]}, Revoked=${statValues[2]}, Emailed=${statValues[3]}`); + + // Verify filters section + const filtersSection = page.locator('.hvac-filters-section'); + await expect(filtersSection).toBeVisible(); + + // Check event filter + const eventFilter = page.locator('#filter_event'); + await expect(eventFilter).toBeVisible(); + const eventOptions = await eventFilter.locator('option').count(); + expect(eventOptions).toBeGreaterThan(0); + console.log(`✅ Event filter has ${eventOptions} options`); + + // Check status filter + const statusFilter = page.locator('#filter_status'); + await expect(statusFilter).toBeVisible(); + const statusOptions = await statusFilter.locator('option').count(); + expect(statusOptions).toBe(3); // All, Active, Revoked + console.log('✅ Status filter has correct options'); + + // Test filter functionality + if (eventOptions > 1) { + await eventFilter.selectOption({ index: 1 }); + await page.click('button:has-text("Apply Filters")'); + await page.waitForLoadState('networkidle'); + await actions.screenshot('certificate-reports-filtered'); + console.log('✅ Filter functionality working'); + } + + // Check certificate display area + const hasTable = await page.locator('.hvac-certificate-table').isVisible().catch(() => false); + const hasNoResults = await page.locator('.hvac-no-certificates').isVisible().catch(() => false); + expect(hasTable || hasNoResults).toBe(true); + console.log(`✅ Certificate display area present (table: ${hasTable}, no results: ${hasNoResults})`); + }); + + test('Generate Certificates - Complete workflow test', async ({ authenticatedPage: page }) => { + test.setTimeout(60000); + const actions = new CommonActions(page); + + await actions.navigateAndWait('/generate-certificates/'); + await actions.screenshot('generate-certificates-initial'); + + // Verify page structure + await expect(page.locator('h1').first()).toContainText('Generate Certificates'); + + // Step 1: Event Selection + const eventSelect = page.locator('#event_id'); + await expect(eventSelect).toBeVisible(); + const eventOptions = await eventSelect.locator('option').count(); + expect(eventOptions).toBeGreaterThan(1); + console.log(`✅ Event dropdown has ${eventOptions} options`); + + // Select first real event + const firstEventValue = await eventSelect.locator('option').nth(1).getAttribute('value'); + await eventSelect.selectOption({ value: firstEventValue! }); + console.log(`✅ Selected event ID: ${firstEventValue}`); + + // Wait for page reload with event parameter + await page.waitForURL(/event_id=/); + await page.waitForLoadState('networkidle'); + await actions.screenshot('generate-certificates-event-selected'); + + // Step 2: Verify attendees section + const attendeesSection = page.locator('#step-select-attendees'); + await expect(attendeesSection).toBeVisible(); + console.log('✅ Attendees section visible'); + + // Check form elements + const certificateForm = page.locator('#generate-certificates-form'); + await expect(certificateForm).toBeVisible(); + + // Verify nonce field exists (security) + const nonceField = await page.locator('input[name="hvac_certificate_nonce"]').count(); + expect(nonceField).toBe(1); + console.log('✅ Security nonce field present'); + + // Check attendee display + const hasAttendeesTable = await page.locator('.hvac-attendees-table').isVisible().catch(() => false); + const hasEmptyMessage = await page.locator('.hvac-empty-state').isVisible().catch(() => false); + expect(hasAttendeesTable || hasEmptyMessage).toBe(true); + console.log(`✅ Attendee display present (table: ${hasAttendeesTable}, empty: ${hasEmptyMessage})`); + + if (hasAttendeesTable) { + // Verify table structure + await expect(page.locator('.hvac-attendees-table thead')).toBeVisible(); + await expect(page.locator('.hvac-attendees-table tbody')).toBeVisible(); + + // Check action buttons + const actionButtons = [ + '#select-all-attendees', + '#select-checked-in', + '#deselect-all-attendees' + ]; + + for (const button of actionButtons) { + await expect(page.locator(button)).toBeVisible(); + } + console.log('✅ All attendee action buttons present'); + + // Test select all functionality + await page.click('#select-all-attendees'); + const checkedCount = await page.locator('.attendee-checkbox:checked').count(); + expect(checkedCount).toBeGreaterThan(0); + console.log(`✅ Select all functionality working (${checkedCount} selected)`); + + // Check generate button + const generateButton = page.locator('button[name="generate_certificates"]'); + await expect(generateButton).toBeVisible(); + await expect(generateButton).toHaveText('Generate Certificates'); + console.log('✅ Generate certificates button present'); + } + + // Verify certificate preview section + const previewSection = page.locator('.hvac-certificate-preview'); + await expect(previewSection).toBeVisible(); + console.log('✅ Certificate preview section present'); + }); + + test('Create Event page - Verify shortcode handling', async ({ authenticatedPage: page }) => { + test.setTimeout(30000); + const actions = new CommonActions(page); + + await actions.navigateAndWait('/manage-event/'); + await actions.screenshot('create-event-page'); + + // Check page title + await expect(page.locator('h1').first()).toContainText(/Create.*Event|Manage.*Event/i); + + // Get page content + const bodyText = await page.locator('body').textContent(); + + // Check for shortcode or form + if (bodyText?.includes('[tribe_community_events')) { + console.log('✅ Page shows TEC shortcode (Community Events not active)'); + expect(bodyText).toContain('[tribe_community_events'); + + // Verify it's displayed as content, not an error + const hasError = await page.locator('.error, .hvac-error').count(); + expect(hasError).toBe(0); + console.log('✅ No error messages displayed'); + } else { + // Check for any form that would allow event creation + const forms = await page.locator('form').count(); + const hasEventFields = await page.locator('input[name*="event"], input[name*="Event"], #event_title, #post_title').count(); + + console.log(`✅ Page has ${forms} forms and ${hasEventFields} event-related fields`); + + if (forms > 0) { + expect(hasEventFields).toBeGreaterThan(0); + console.log('✅ Event creation form detected'); + } + } + }); + + test('Trainer Profile - Verify navigation updates', async ({ authenticatedPage: page }) => { + test.setTimeout(30000); + const actions = new CommonActions(page); + + await actions.navigateAndWait('/trainer-profile/'); + await actions.screenshot('trainer-profile-navigation'); + + // Check no My Events links + const myEventsLinks = await page.locator('a[href*="my-events"]').count(); + expect(myEventsLinks).toBe(0); + console.log('✅ No My Events links on trainer profile'); + + // Verify Certificate Reports link exists + const certReportsLink = await page.locator('a:has-text("Certificate Reports")').count(); + expect(certReportsLink).toBeGreaterThan(0); + console.log('✅ Certificate Reports link present on trainer profile'); + + // Check other navigation elements + const expectedLinks = ['Dashboard', 'Create Event', 'Certificate Reports', 'Help', 'Logout']; + for (const linkText of expectedLinks) { + const linkExists = await page.locator(`.hvac-dashboard-nav a:has-text("${linkText}")`).count() > 0; + if (linkExists) { + console.log(`✅ ${linkText} link found`); + } + } + }); + + test('My Events page removal verification', async ({ authenticatedPage: page }) => { + test.setTimeout(20000); + const actions = new CommonActions(page); + + // Attempt to navigate to my-events + const response = await page.goto('/my-events/', { waitUntil: 'networkidle' }); + const status = response?.status() || 0; + const finalUrl = page.url(); + + console.log(`My Events page status: ${status}`); + console.log(`Final URL: ${finalUrl}`); + + // The page might still exist but should not be linked anywhere + if (status === 200 && finalUrl.includes('/my-events/')) { + console.log('⚠️ My Events page still exists but is not linked in navigation'); + + // Verify it's not linked from any main pages + const pagesToCheck = ['/hvac-dashboard/', '/trainer-profile/']; + for (const pageUrl of pagesToCheck) { + await actions.navigateAndWait(pageUrl); + const myEventsLinksOnPage = await page.locator('a[href*="my-events"]').count(); + expect(myEventsLinksOnPage).toBe(0); + console.log(`✅ No My Events links on ${pageUrl}`); + } + } else { + console.log('✅ My Events page not accessible or redirects'); + } + }); + + test('PHP Error Monitoring - No errors across all pages', async ({ authenticatedPage: page }) => { + test.setTimeout(45000); + const actions = new CommonActions(page); + const phpErrors: string[] = []; + + // Enhanced error monitoring + page.on('console', (msg) => { + if (msg.type() === 'error') { + const text = msg.text(); + if (text.includes('PHP') || text.includes('Fatal') || text.includes('Warning') || text.includes('Notice')) { + phpErrors.push(`[${msg.type()}] ${text}`); + } + } + }); + + // Test all main pages + const pagesToTest = [ + { url: '/hvac-dashboard/', name: 'Dashboard' }, + { url: '/certificate-reports/', name: 'Certificate Reports' }, + { url: '/generate-certificates/', name: 'Generate Certificates' }, + { url: '/manage-event/', name: 'Create Event' }, + { url: '/trainer-profile/', name: 'Trainer Profile' } + ]; + + for (const pageInfo of pagesToTest) { + console.log(`Testing ${pageInfo.name}...`); + await actions.navigateAndWait(pageInfo.url); + await page.waitForTimeout(1000); // Give time for any errors to appear + + // Additional test for Generate Certificates with event selection + if (pageInfo.url === '/generate-certificates/') { + const eventOptions = await page.locator('#event_id option').count(); + if (eventOptions > 1) { + await page.selectOption('#event_id', { index: 1 }); + await page.waitForTimeout(2000); + } + } + } + + // Report results + if (phpErrors.length > 0) { + console.error('❌ PHP Errors detected:'); + phpErrors.forEach(error => console.error(error)); + expect(phpErrors.length).toBe(0); + } else { + console.log('✅ No PHP errors detected across all pages'); + } + }); + + test('Complete User Journey - Event to Certificate', async ({ authenticatedPage: page }) => { + test.setTimeout(60000); + const actions = new CommonActions(page); + + console.log('Starting complete user journey test...'); + + // 1. Dashboard + await actions.navigateAndWait('/hvac-dashboard/'); + await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible(); + console.log('✅ Step 1: Dashboard loaded'); + + // 2. Navigate to Certificate Reports + await page.click('a:has-text("Certificate Reports")'); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1:has-text("Certificate Reports")')).toBeVisible(); + const initialStats = await page.locator('.hvac-stat-value').first().textContent(); + console.log(`✅ Step 2: Certificate Reports loaded (Total certificates: ${initialStats})`); + + // 3. Navigate to Generate Certificates + await page.click('a:has-text("Generate Certificates")'); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1:has-text("Generate Certificates")')).toBeVisible(); + console.log('✅ Step 3: Generate Certificates loaded'); + + // 4. Select an event + const eventOptions = await page.locator('#event_id option').count(); + if (eventOptions > 1) { + await page.selectOption('#event_id', { index: 1 }); + await page.waitForURL(/event_id=/); + await expect(page.locator('#step-select-attendees')).toBeVisible(); + console.log('✅ Step 4: Event selected and attendees loaded'); + } + + // 5. Return to dashboard + await page.click('a[href*="hvac-dashboard"]').first(); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible(); + console.log('✅ Step 5: Returned to dashboard'); + + // 6. Check Create Event + await page.click('a:has-text("Create Event")'); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1').first()).toContainText(/Event/i); + console.log('✅ Step 6: Create Event page accessed'); + + console.log('✅ Complete user journey test passed!'); + }); +}); \ No newline at end of file diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-community-events.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-community-events.php index df095354..9c6845e4 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-community-events.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-community-events.php @@ -51,10 +51,6 @@ function hvac_ce_create_required_pages() { 'title' => 'Manage Event', 'content' => '[tribe_community_events view="submission_form"]', ], - 'my-events' => [ // New page for TEC CE event list shortcode - 'title' => 'My Events', - 'content' => '[tribe_community_events view="my_events"]', - ], 'trainer-profile' => [ // Add trainer profile page 'title' => 'Trainer Profile', 'content' => '[hvac_trainer_profile]', diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-fixed-activation.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-fixed-activation.php index ca96bd3a..e4718e67 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-fixed-activation.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/hvac-fixed-activation.php @@ -157,10 +157,6 @@ function create_hvac_required_pages() { 'title' => 'Manage Event', 'content' => '[tribe_community_events view="submission_form"]', ], - 'my-events' => [ - 'title' => 'My Events', - 'content' => '[tribe_community_events view="my_events"]', - ], 'trainer-profile' => [ 'title' => 'Trainer Profile', 'content' => '[hvac_trainer_profile]', diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-community-events.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-community-events.php index d0f9be23..320da117 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-community-events.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-community-events.php @@ -550,10 +550,6 @@ class HVAC_Community_Events { $custom_template = HVAC_CE_PLUGIN_DIR . 'templates/page-community-login.php'; } - // Check for my-events page - if (is_page('my-events')) { - $custom_template = HVAC_CE_PLUGIN_DIR . 'templates/page-my-events.php'; - } // Check for trainer-profile page if (is_page('trainer-profile')) { @@ -640,9 +636,25 @@ class HVAC_Community_Events { } // Check if TEC Community Events is active and working - if (function_exists('tribe_community_events_form')) { - // Let TEC handle it natively - don't override - return ''; + if (class_exists('Tribe__Events__Community__Main')) { + // Check if we're not in an infinite loop + global $shortcode_tags; + $original_handler = isset($shortcode_tags['tribe_community_events']) ? $shortcode_tags['tribe_community_events'] : null; + + // Temporarily remove our handler to let TEC's handler run + if ($original_handler === array($this, 'render_tribe_community_events')) { + remove_shortcode('tribe_community_events'); + + // Let TEC process the shortcode + $output = do_shortcode('[tribe_community_events view="' . esc_attr($atts['view']) . '"]'); + + // Re-add our handler + add_shortcode('tribe_community_events', array($this, 'render_tribe_community_events')); + + if (!empty($output)) { + return $output; + } + } } // Handle different views @@ -668,8 +680,8 @@ class HVAC_Community_Events {