- Implement full CRUD operations for email template management - Create modal-based interface with form validation and category organization - Add dynamic placeholder system for personalizing emails with attendee/event data - Integrate AJAX handlers for real-time save/load operations without page refresh - Fix JavaScript conflicts by implementing override system after wp_footer() - Add comprehensive E2E test coverage with Playwright validation - Support default template installation for new trainers - Enable REST API access for template post type - Include extensive debugging and validation testing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
279 lines
No EOL
10 KiB
TypeScript
279 lines
No EOL
10 KiB
TypeScript
import { test, expect } from './fixtures/auth';
|
|
import { CommonActions } from './utils/common-actions';
|
|
|
|
/**
|
|
* Communication Templates Working Tests
|
|
*
|
|
* Focused tests that actually work with the template system
|
|
*/
|
|
|
|
test.describe('Communication Templates Working Tests', () => {
|
|
|
|
test('Navigate to templates page and verify basic functionality', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(45000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page (critical for script loading)
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
await actions.screenshot('templates-page-loaded');
|
|
|
|
// Verify page title
|
|
await expect(page.locator('h1')).toContainText('Communication Templates');
|
|
|
|
// Check if scripts loaded correctly
|
|
const scriptsLoaded = await page.evaluate(() => {
|
|
return {
|
|
jQuery: typeof jQuery !== 'undefined',
|
|
hvacTemplates: typeof hvacTemplates !== 'undefined',
|
|
HVACTemplates: typeof HVACTemplates !== 'undefined',
|
|
ajaxUrl: typeof hvacTemplates !== 'undefined' ? hvacTemplates.ajaxUrl : null
|
|
};
|
|
});
|
|
|
|
console.log('Scripts loaded:', scriptsLoaded);
|
|
expect(scriptsLoaded.jQuery).toBe(true);
|
|
expect(scriptsLoaded.hvacTemplates).toBe(true);
|
|
expect(scriptsLoaded.HVACTemplates).toBe(true);
|
|
expect(scriptsLoaded.ajaxUrl).toContain('admin-ajax.php');
|
|
|
|
// Look for key elements
|
|
const createButton = page.locator('button:has-text("Create New Template")');
|
|
await expect(createButton).toBeVisible();
|
|
|
|
await actions.screenshot('scripts-verified');
|
|
});
|
|
|
|
test('Test AJAX endpoints on templates page', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page first (critical!)
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
|
|
// Wait for scripts to load
|
|
await page.waitForFunction(() => typeof HVACTemplates !== 'undefined');
|
|
|
|
// Test get templates endpoint
|
|
const getTemplatesResult = await page.evaluate(async () => {
|
|
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 result:', JSON.stringify(getTemplatesResult, null, 2));
|
|
expect(getTemplatesResult.success).toBe(true);
|
|
|
|
await actions.screenshot('ajax-get-templates-test');
|
|
});
|
|
|
|
test('Create new template using modal interface', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(60000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
|
|
// Wait for scripts
|
|
await page.waitForFunction(() => typeof HVACTemplates !== 'undefined');
|
|
|
|
// Click create button
|
|
const createButton = page.locator('button:has-text("Create New Template")');
|
|
await expect(createButton).toBeVisible();
|
|
await createButton.click();
|
|
|
|
// Wait for modal to appear
|
|
const modal = page.locator('#template-form-overlay');
|
|
await expect(modal).toBeVisible();
|
|
await actions.screenshot('modal-opened');
|
|
|
|
// Fill in the form
|
|
const templateTitle = `Test Template ${Date.now()}`;
|
|
await page.fill('#hvac_template_title', templateTitle);
|
|
await page.selectOption('#hvac_template_category', 'general');
|
|
await page.fill('#hvac_template_description', 'E2E test template');
|
|
await page.fill('#hvac_template_content', 'Hello {attendee_name}, this is a test template for {event_title}.');
|
|
|
|
await actions.screenshot('modal-form-filled');
|
|
|
|
// Submit the form
|
|
const saveButton = page.locator('.hvac-template-form-save');
|
|
await saveButton.click();
|
|
|
|
// Wait for success (page should reload)
|
|
await page.waitForLoadState('networkidle', { timeout: 30000 });
|
|
await actions.screenshot('template-created');
|
|
|
|
// Verify the template appears on the page
|
|
await expect(page.locator('.hvac-template-card')).toBeVisible();
|
|
await expect(page.locator(`.hvac-template-card:has-text("${templateTitle}")`)).toBeVisible();
|
|
|
|
console.log(`Successfully created template: ${templateTitle}`);
|
|
});
|
|
|
|
test('Edit existing template', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(45000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
|
|
// Wait for scripts
|
|
await page.waitForFunction(() => typeof HVACTemplates !== 'undefined');
|
|
|
|
// Look for an existing template to edit
|
|
const editButton = page.locator('.hvac-btn-edit').first();
|
|
|
|
if (await editButton.count() > 0) {
|
|
await editButton.click();
|
|
|
|
// Wait for modal
|
|
const modal = page.locator('#template-form-overlay');
|
|
await expect(modal).toBeVisible();
|
|
await actions.screenshot('edit-modal-opened');
|
|
|
|
// Modify the title
|
|
const titleField = page.locator('#hvac_template_title');
|
|
const currentTitle = await titleField.inputValue();
|
|
const newTitle = `${currentTitle} - Edited`;
|
|
|
|
await titleField.fill(newTitle);
|
|
await actions.screenshot('edit-modal-modified');
|
|
|
|
// Save
|
|
await page.locator('.hvac-template-form-save').click();
|
|
|
|
// Wait for page reload
|
|
await page.waitForLoadState('networkidle', { timeout: 30000 });
|
|
await actions.screenshot('template-edited');
|
|
|
|
// Verify the edit
|
|
await expect(page.locator(`.hvac-template-card:has-text("${newTitle}")`)).toBeVisible();
|
|
|
|
console.log(`Successfully edited template to: ${newTitle}`);
|
|
} else {
|
|
console.log('No existing templates found to edit');
|
|
}
|
|
});
|
|
|
|
test('Test default template installation', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
await actions.screenshot('checking-for-defaults');
|
|
|
|
// Check if "Install Default Templates" button exists
|
|
const installDefaultsButton = page.locator('a:has-text("Install Default Templates")');
|
|
|
|
if (await installDefaultsButton.count() > 0) {
|
|
await installDefaultsButton.click();
|
|
|
|
// Wait for page reload after installation
|
|
await page.waitForLoadState('networkidle', { timeout: 30000 });
|
|
await actions.screenshot('defaults-installed');
|
|
|
|
// Verify default templates were created
|
|
const templateCards = page.locator('.hvac-template-card');
|
|
const cardCount = await templateCards.count();
|
|
|
|
expect(cardCount).toBeGreaterThan(0);
|
|
console.log(`Installed ${cardCount} default templates`);
|
|
|
|
// Check for specific default templates
|
|
await expect(page.locator('.hvac-template-card:has-text("Event Reminder")')).toBeVisible();
|
|
await expect(page.locator('.hvac-template-card:has-text("Welcome")')).toBeVisible();
|
|
} else {
|
|
console.log('Default templates already installed or not available');
|
|
}
|
|
});
|
|
|
|
test('Test placeholder functionality', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(45000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
|
|
// Wait for scripts
|
|
await page.waitForFunction(() => typeof HVACTemplates !== 'undefined');
|
|
|
|
// Open create template modal
|
|
await page.locator('button:has-text("Create New Template")').click();
|
|
|
|
// Wait for modal
|
|
await expect(page.locator('#template-form-overlay')).toBeVisible();
|
|
await actions.screenshot('modal-for-placeholder-test');
|
|
|
|
// Check that placeholder helper is visible
|
|
const placeholderHelper = page.locator('.hvac-placeholder-helper');
|
|
await expect(placeholderHelper).toBeVisible();
|
|
|
|
// Check for specific placeholders
|
|
const attendeeNamePlaceholder = page.locator('.hvac-placeholder-item:has-text("{attendee_name}")');
|
|
const eventTitlePlaceholder = page.locator('.hvac-placeholder-item:has-text("{event_title}")');
|
|
|
|
await expect(attendeeNamePlaceholder).toBeVisible();
|
|
await expect(eventTitlePlaceholder).toBeVisible();
|
|
|
|
// Test clicking a placeholder to insert it
|
|
const contentTextarea = page.locator('#hvac_template_content');
|
|
await contentTextarea.focus();
|
|
|
|
// Click the attendee name placeholder
|
|
await attendeeNamePlaceholder.click();
|
|
|
|
// Verify the placeholder was inserted
|
|
const textareaValue = await contentTextarea.inputValue();
|
|
expect(textareaValue).toContain('{attendee_name}');
|
|
|
|
await actions.screenshot('placeholder-inserted');
|
|
console.log('Placeholder functionality verified');
|
|
|
|
// Close modal
|
|
await page.locator('.hvac-template-form-cancel').click();
|
|
});
|
|
|
|
test('Test category filtering', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Navigate to templates page
|
|
await actions.navigateAndWait('/communication-templates/');
|
|
await actions.screenshot('category-filter-test');
|
|
|
|
// Check if category tabs exist (only if templates exist)
|
|
const categoryTabs = page.locator('.hvac-category-tab');
|
|
const tabCount = await categoryTabs.count();
|
|
|
|
if (tabCount > 1) {
|
|
// Test clicking different category tabs
|
|
for (let i = 0; i < Math.min(tabCount, 3); i++) {
|
|
const tab = categoryTabs.nth(i);
|
|
const tabText = await tab.textContent();
|
|
|
|
await tab.click();
|
|
await page.waitForTimeout(500); // Brief wait for filtering
|
|
|
|
await actions.screenshot(`category-${i}-selected`);
|
|
console.log(`Clicked category tab: ${tabText}`);
|
|
}
|
|
} else {
|
|
console.log('No category tabs found - may not have enough templates');
|
|
}
|
|
});
|
|
|
|
}); |