upskill-event-manager/wordpress-dev/tests/e2e/debug-templates.test.ts
bengizmo a0d47b3b3e feat: Implement configurable Communication Schedule system
This commit implements Phase 1 of the Communication Schedule system, providing:

Core Infrastructure:
- HVAC_Communication_Scheduler: Main controller with cron integration and AJAX handlers
- HVAC_Communication_Schedule_Manager: CRUD operations and database interactions
- HVAC_Communication_Trigger_Engine: Automation logic and recipient management
- HVAC_Communication_Logger: Execution logging and performance tracking
- HVAC_Communication_Installer: Database table creation and management

Features:
- Event-based triggers (before/after event, on registration)
- Custom date scheduling with recurring options
- Flexible recipient targeting (all attendees, confirmed, custom lists)
- Template integration with placeholder replacement
- WordPress cron integration for automated execution
- Comprehensive AJAX API for schedule management
- Template quickstart options for common scenarios

UI Components:
- Communication Schedules page with full management interface
- Form-based schedule creation with validation
- Schedule listing with filtering and status management
- Modal recipient preview functionality
- Pre-configured schedule templates for quick setup

Database Design:
- hvac_communication_schedules: Schedule configurations
- hvac_communication_logs: Execution history and statistics
- hvac_event_communication_tracking: Individual email tracking

The system integrates with existing email templates and provides a foundation
for automated communication workflows for HVAC trainers.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-14 00:07:30 -03:00

332 lines
No EOL
12 KiB
TypeScript

import { test, expect } from './fixtures/auth';
import { CommonActions } from './utils/common-actions';
/**
* Debug Tests for Communication Templates
*
* Comprehensive debugging to identify why features aren't working
*/
test.describe('Debug Communication Templates', () => {
test('Debug page source and JavaScript loading', async ({ authenticatedPage: page }) => {
test.setTimeout(30000);
const actions = new CommonActions(page);
// Capture all console messages
const consoleMessages: { type: string, text: string }[] = [];
page.on('console', (msg) => {
consoleMessages.push({ type: msg.type(), text: msg.text() });
});
// Navigate to templates page
await actions.navigateAndWait('/communication-templates/');
await actions.screenshot('debug-templates-page');
// Get page source
const pageSource = await page.content();
// Check if shortcode was processed
const hasShortcode = pageSource.includes('[hvac_communication_templates]');
const hasTemplateWrapper = pageSource.includes('hvac-templates-wrapper');
console.log('=== Page Debug Info ===');
console.log('Raw shortcode visible:', hasShortcode);
console.log('Template wrapper present:', hasTemplateWrapper);
// Check for PHP errors in source
const phpErrors = pageSource.match(/Fatal error:|Warning:|Notice:|Parse error:/gi);
if (phpErrors) {
console.log('PHP Errors found:', phpErrors);
}
// Check if CSS is loaded
const cssLoaded = await page.evaluate(() => {
const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]'));
return links.some(link => link.href.includes('communication-templates.css'));
});
console.log('CSS loaded:', cssLoaded);
// Check if JavaScript is loaded
const jsLoaded = await page.evaluate(() => {
const scripts = Array.from(document.querySelectorAll('script'));
return scripts.some(script => script.src && script.src.includes('communication-templates.js'));
});
console.log('JavaScript loaded:', jsLoaded);
// Check JavaScript objects
const jsObjects = await page.evaluate(() => {
return {
jQuery: typeof jQuery !== 'undefined',
hvacTemplates: typeof hvacTemplates !== 'undefined',
HVACTemplates: typeof HVACTemplates !== 'undefined',
ajaxUrl: typeof hvacTemplates !== 'undefined' ? hvacTemplates.ajaxUrl : 'not found'
};
});
console.log('JavaScript objects:', jsObjects);
// Log all console messages
console.log('\n=== Console Messages ===');
consoleMessages.forEach(msg => {
console.log(`[${msg.type}] ${msg.text}`);
});
// Check page title to verify we're on the right page
const pageTitle = await page.title();
console.log('\nPage title:', pageTitle);
// Save page source for analysis
const fs = require('fs');
fs.writeFileSync('test-results/debug-page-source.html', pageSource);
console.log('\nPage source saved to test-results/debug-page-source.html');
});
test('Test AJAX endpoints directly', async ({ authenticatedPage: page }) => {
test.setTimeout(20000);
// Test get templates endpoint
const getTemplatesResponse = await page.evaluate(async () => {
if (typeof jQuery === 'undefined') return { error: 'jQuery not loaded' };
if (typeof hvacTemplates === 'undefined') return { error: 'hvacTemplates not defined' };
return new Promise((resolve) => {
jQuery.ajax({
url: hvacTemplates.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_get_templates',
nonce: hvacTemplates.nonce
},
success: function(response) {
resolve({ success: true, data: response });
},
error: function(xhr, status, error) {
resolve({ success: false, error: error, status: xhr.status });
}
});
});
});
console.log('Get Templates Response:', JSON.stringify(getTemplatesResponse, null, 2));
// Test save template endpoint
const saveTemplateResponse = await page.evaluate(async () => {
if (typeof jQuery === 'undefined') return { error: 'jQuery not loaded' };
if (typeof hvacTemplates === 'undefined') return { error: 'hvacTemplates not defined' };
return new Promise((resolve) => {
jQuery.ajax({
url: hvacTemplates.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_save_template',
nonce: hvacTemplates.nonce,
title: 'Test Template',
content: 'This is a test template content with {attendee_name} placeholder.',
category: 'general',
description: 'Test template created by E2E test'
},
success: function(response) {
resolve({ success: true, data: response });
},
error: function(xhr, status, error) {
resolve({ success: false, error: error, status: xhr.status, responseText: xhr.responseText });
}
});
});
});
console.log('Save Template Response:', JSON.stringify(saveTemplateResponse, null, 2));
});
test('Check template post type registration', async ({ authenticatedPage: page }) => {
test.setTimeout(20000);
// Check if post type exists via REST API
const postTypeExists = await page.evaluate(async () => {
try {
const response = await fetch('/wp-json/wp/v2/types/hvac_email_template');
return {
exists: response.ok,
status: response.status,
data: response.ok ? await response.json() : null
};
} catch (error) {
return { exists: false, error: error.message };
}
});
console.log('Post Type Check:', JSON.stringify(postTypeExists, null, 2));
// Try to access templates via REST API
const templatesViaRest = await page.evaluate(async () => {
try {
const response = await fetch('/wp-json/wp/v2/hvac_email_template');
return {
success: response.ok,
status: response.status,
data: response.ok ? await response.json() : await response.text()
};
} catch (error) {
return { success: false, error: error.message };
}
});
console.log('Templates via REST:', JSON.stringify(templatesViaRest, null, 2));
});
test('Test template widget in email attendees page', async ({ authenticatedPage: page }) => {
test.setTimeout(30000);
const actions = new CommonActions(page);
// First, create a test event with attendees
await actions.navigateAndWait('/manage-event/');
// Fill in basic event details
const eventTitle = `Test Event ${Date.now()}`;
await page.fill('#event_title', eventTitle);
// Fill description
const descFrame = page.frameLocator('iframe[id*="_ifr"]').first();
await descFrame.locator('body').fill('Test event for template validation');
// Set date/time (tomorrow)
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const dateStr = tomorrow.toISOString().split('T')[0];
await page.fill('input[name="EventStartDate"]', dateStr);
await page.fill('input[name="EventStartTime"]', '10:00');
await page.fill('input[name="EventEndDate"]', dateStr);
await page.fill('input[name="EventEndTime"]', '12:00');
// Submit
await page.click('button[type="submit"]');
await page.waitForLoadState('networkidle');
// Now navigate to dashboard to find the event
await actions.navigateAndWait('/hvac-dashboard/');
// Look for email attendees link for our event
const emailLink = page.locator(`a[href*="email-attendees"]:has-text("${eventTitle}")`).first();
if (await emailLink.isVisible()) {
await emailLink.click();
await page.waitForLoadState('networkidle');
await actions.screenshot('email-attendees-with-widget');
// Check for template manager elements
const widgetExists = await page.locator('.hvac-template-manager').count() > 0;
const toggleExists = await page.locator('.hvac-template-toggle').count() > 0;
console.log('Template widget exists:', widgetExists);
console.log('Template toggle exists:', toggleExists);
// Check if scripts are loaded on this page
const scriptsOnEmailPage = await page.evaluate(() => {
return {
jQuery: typeof jQuery !== 'undefined',
hvacTemplates: typeof hvacTemplates !== 'undefined',
HVACTemplates: typeof HVACTemplates !== 'undefined'
};
});
console.log('Scripts on email page:', scriptsOnEmailPage);
} else {
console.log('Could not find email attendees link for test event');
}
});
test('Test user capabilities and permissions', async ({ authenticatedPage: page }) => {
test.setTimeout(20000);
// Check current user capabilities
const userInfo = await page.evaluate(async () => {
try {
const response = await fetch('/wp-json/wp/v2/users/me', {
credentials: 'include'
});
if (response.ok) {
const data = await response.json();
return {
id: data.id,
name: data.name,
roles: data.roles,
capabilities: data.capabilities
};
}
return { error: 'Failed to get user info', status: response.status };
} catch (error) {
return { error: error.message };
}
});
console.log('Current User Info:', JSON.stringify(userInfo, null, 2));
// Check if user can create posts
const canCreatePosts = await page.evaluate(() => {
// This would need to be exposed by WordPress
return typeof wp !== 'undefined' && wp.data ?
wp.data.select('core').canUser('create', 'posts') :
'WordPress data not available';
});
console.log('Can create posts:', canCreatePosts);
});
test('Manually test template creation flow', async ({ authenticatedPage: page }) => {
test.setTimeout(30000);
const actions = new CommonActions(page);
// Navigate to templates page
await actions.navigateAndWait('/communication-templates/');
// Try clicking the create button if it exists
const createButton = page.locator('button:has-text("Create New Template")');
if (await createButton.isVisible()) {
await createButton.click();
await page.waitForTimeout(2000);
await actions.screenshot('after-create-click');
// Check what happened
const modalVisible = await page.locator('.hvac-template-form-overlay').isVisible();
const formVisible = await page.locator('.hvac-template-form').isVisible();
console.log('Modal visible after click:', modalVisible);
console.log('Form visible after click:', formVisible);
// Try to fill the form if visible
if (modalVisible || formVisible) {
const titleInput = page.locator('#hvac_template_title');
if (await titleInput.isVisible()) {
await titleInput.fill('E2E Test Template');
await page.locator('#hvac_template_content').fill('Test content with {attendee_name}');
await page.selectOption('#hvac_template_category', 'general');
await actions.screenshot('form-filled');
// Try to save
const saveButton = page.locator('.hvac-template-form-save');
if (await saveButton.isVisible()) {
await saveButton.click();
await page.waitForTimeout(3000);
await actions.screenshot('after-save-attempt');
// Check for success/error messages
const messages = await page.locator('.hvac-template-message').allTextContents();
console.log('Messages after save:', messages);
}
}
}
} else {
console.log('Create button not found - checking page structure');
// Get all visible text on page
const visibleText = await page.locator('body').innerText();
console.log('Page text preview:', visibleText.substring(0, 500));
}
});
});