## Major Enhancements ### 🏗️ Architecture & Infrastructure - Implement comprehensive Docker testing infrastructure with hermetic environment - Add Forgejo Actions CI/CD pipeline for automated deployments - Create Page Object Model (POM) testing architecture reducing test duplication by 90% - Establish security-first development patterns with input validation and output escaping ### 🧪 Testing Framework Modernization - Migrate 146+ tests from 80 duplicate files to centralized architecture - Add comprehensive E2E test suites for all user roles and workflows - Implement WordPress error detection with automatic site health monitoring - Create robust browser lifecycle management with proper cleanup ### 📚 Documentation & Guides - Add comprehensive development best practices guide - Create detailed administrator setup documentation - Establish user guides for trainers and master trainers - Document security incident reports and migration guides ### 🔧 Core Plugin Features - Enhance trainer profile management with certification system - Improve find trainer functionality with advanced filtering - Strengthen master trainer area with content management - Add comprehensive venue and organizer management ### 🛡️ Security & Reliability - Implement security-first patterns throughout codebase - Add comprehensive input validation and output escaping - Create secure credential management system - Establish proper WordPress role-based access control ### 🎯 WordPress Integration - Strengthen singleton pattern implementation across all classes - Enhance template hierarchy with proper WordPress integration - Improve page manager with hierarchical URL structure - Add comprehensive shortcode and menu system ### 🔍 Developer Experience - Add extensive debugging and troubleshooting tools - Create comprehensive test data seeding scripts - Implement proper error handling and logging - Establish consistent code patterns and standards ### 📊 Performance & Optimization - Optimize database queries and caching strategies - Improve asset loading and script management - Enhance template rendering performance - Streamline user experience across all interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
118 lines
No EOL
4.1 KiB
JavaScript
118 lines
No EOL
4.1 KiB
JavaScript
const { chromium } = require('playwright');
|
||
|
||
console.log('🎯 TRAINER CARD CLICK TEST');
|
||
console.log('=========================');
|
||
|
||
const BASE_URL = process.env.BASE_URL || 'https://upskill-staging.measurequick.com';
|
||
|
||
(async () => {
|
||
let browser;
|
||
|
||
try {
|
||
browser = await chromium.launch({
|
||
headless: process.env.HEADLESS !== 'false',
|
||
timeout: 30000
|
||
});
|
||
|
||
const page = await browser.newPage();
|
||
|
||
console.log('🌐 Loading Find a Trainer page...');
|
||
await page.goto(`${BASE_URL}/find-a-trainer/`);
|
||
await page.waitForLoadState('networkidle', { timeout: 20000 });
|
||
|
||
// Check for trainer cards with the hvac-open-profile class
|
||
console.log('\n🃏 Checking trainer cards...');
|
||
const clickableCards = await page.locator('.hvac-trainer-card.hvac-open-profile').count();
|
||
console.log(`Clickable trainer cards found: ${clickableCards}`);
|
||
|
||
if (clickableCards > 0) {
|
||
// Test clicking on the first card
|
||
console.log('\n🖱️ Testing card click functionality...');
|
||
|
||
// Get the first card's data
|
||
const firstCard = page.locator('.hvac-trainer-card.hvac-open-profile').first();
|
||
const cardData = await firstCard.evaluate(el => ({
|
||
profileId: el.getAttribute('data-profile-id'),
|
||
hasHoverCursor: window.getComputedStyle(el).cursor === 'pointer'
|
||
}));
|
||
|
||
console.log(`First card profile ID: ${cardData.profileId}`);
|
||
console.log(`Card has pointer cursor: ${cardData.hasHoverCursor}`);
|
||
|
||
// Check if modal exists
|
||
const modalExists = await page.locator('#hvac-trainer-modal').count();
|
||
console.log(`Trainer modal container exists: ${modalExists > 0}`);
|
||
|
||
// Click the card (not just the name)
|
||
await firstCard.click();
|
||
|
||
// Wait for modal to potentially open
|
||
await page.waitForTimeout(2000);
|
||
|
||
// Check if modal opened
|
||
const modalVisible = await page.locator('#hvac-trainer-modal').isVisible();
|
||
console.log(`Modal opened after card click: ${modalVisible}`);
|
||
|
||
if (modalVisible) {
|
||
console.log('✅ SUCCESS: Entire card is clickable and opens profile modal');
|
||
|
||
// Check modal content
|
||
const modalTitle = await page.locator('.hvac-modal-title').textContent();
|
||
console.log(`Modal title: "${modalTitle}"`);
|
||
|
||
// Close modal for cleanup
|
||
const closeBtn = page.locator('.hvac-modal-close');
|
||
if (await closeBtn.count() > 0) {
|
||
await closeBtn.click();
|
||
}
|
||
} else {
|
||
console.log('❌ FAILED: Card click did not open modal');
|
||
|
||
// Check if there were any console errors
|
||
page.on('console', msg => {
|
||
if (msg.type() === 'error') {
|
||
console.log(` JS Error: ${msg.text()}`);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Test hover effects
|
||
console.log('\n🎨 Testing hover effects...');
|
||
await firstCard.hover();
|
||
await page.waitForTimeout(500);
|
||
|
||
const hoverStyles = await firstCard.evaluate(el => {
|
||
const computed = window.getComputedStyle(el);
|
||
return {
|
||
transform: computed.transform,
|
||
boxShadow: computed.boxShadow
|
||
};
|
||
});
|
||
|
||
console.log(`Hover transform applied: ${hoverStyles.transform !== 'none'}`);
|
||
console.log(`Hover shadow applied: ${hoverStyles.boxShadow !== 'none'}`);
|
||
|
||
} else {
|
||
console.log('❌ No clickable trainer cards found on page');
|
||
}
|
||
|
||
// Check champion cards (should not be clickable)
|
||
const championCards = await page.locator('.hvac-trainer-card.hvac-champion-card:not(.hvac-open-profile)').count();
|
||
console.log(`\n👑 Champion cards (non-clickable): ${championCards}`);
|
||
|
||
// Final results
|
||
console.log('\n📊 TEST RESULTS');
|
||
console.log('===============');
|
||
|
||
const success = clickableCards > 0;
|
||
console.log(`Clickable Cards: ${clickableCards}`);
|
||
console.log(`Implementation: ${success ? '✅ SUCCESS' : '❌ FAILED'}`);
|
||
|
||
} catch (error) {
|
||
console.error('\n💥 Error:', error.message);
|
||
} finally {
|
||
if (browser) {
|
||
await browser.close();
|
||
}
|
||
}
|
||
})(); |