## 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>
207 lines
No EOL
8.5 KiB
JavaScript
207 lines
No EOL
8.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Organizer Authentication Debug Test
|
|
*/
|
|
|
|
const { chromium } = require('playwright');
|
|
|
|
const config = {
|
|
BASE_URL: process.env.BASE_URL || 'http://localhost:8080',
|
|
HEADLESS: process.env.HEADLESS !== 'false',
|
|
USERNAME: 'testtrainer',
|
|
PASSWORD: 'TestPass123!'
|
|
};
|
|
|
|
async function debugAuthTest() {
|
|
console.log('🔍 Debugging Authentication for Organizer Pages');
|
|
console.log('===============================================\n');
|
|
|
|
const browser = await chromium.launch({
|
|
headless: config.HEADLESS,
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
});
|
|
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
|
|
try {
|
|
// Step 1: Go to login page and check form
|
|
console.log('1. Testing login page access...');
|
|
await page.goto(`${config.BASE_URL}/community-login/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const hasLoginForm = await page.locator('#loginform').isVisible();
|
|
console.log(` Login form visible: ${hasLoginForm ? 'Yes' : 'No'}`);
|
|
|
|
if (hasLoginForm) {
|
|
console.log('\n2. Logging in...');
|
|
|
|
// Clear any existing values
|
|
await page.fill('#user_login', '');
|
|
await page.fill('#user_pass', '');
|
|
|
|
// Fill login form
|
|
await page.fill('#user_login', config.USERNAME);
|
|
await page.fill('#user_pass', config.PASSWORD);
|
|
|
|
// Submit form
|
|
await page.click('#wp-submit');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const postLoginUrl = page.url();
|
|
console.log(` URL after login: ${postLoginUrl}`);
|
|
|
|
// Check for login errors
|
|
const loginError = await page.locator('.login_error, .message.error').textContent().catch(() => '');
|
|
if (loginError) {
|
|
console.log(` Login error: ${loginError}`);
|
|
}
|
|
|
|
// Check if redirected to dashboard
|
|
if (postLoginUrl.includes('/trainer/dashboard/')) {
|
|
console.log(' ✅ Redirected to trainer dashboard');
|
|
} else if (postLoginUrl.includes('/community-login/') || postLoginUrl.includes('wp-login.php')) {
|
|
console.log(' ❌ Still on login page - authentication failed');
|
|
return;
|
|
} else {
|
|
console.log(` ⚠️ Redirected to unexpected page: ${postLoginUrl}`);
|
|
}
|
|
|
|
// Wait a moment for any JavaScript to execute
|
|
await page.waitForTimeout(2000);
|
|
|
|
} else {
|
|
console.log('\n2. No login form found - may already be logged in');
|
|
}
|
|
|
|
// Step 3: Check authentication status
|
|
console.log('\n3. Checking authentication status...');
|
|
|
|
// Go to dashboard first to verify authentication
|
|
await page.goto(`${config.BASE_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const dashboardUrl = page.url();
|
|
const dashboardTitle = await page.title();
|
|
console.log(` Dashboard URL: ${dashboardUrl}`);
|
|
console.log(` Dashboard title: "${dashboardTitle}"`);
|
|
|
|
if (dashboardUrl.includes('/trainer/dashboard/') && !dashboardTitle.includes('Login')) {
|
|
console.log(' ✅ Successfully authenticated - on trainer dashboard');
|
|
} else {
|
|
console.log(' ❌ Not properly authenticated');
|
|
return;
|
|
}
|
|
|
|
// Step 4: Test organizer pages with authenticated session
|
|
console.log('\n4. Testing organizer pages with authenticated session...');
|
|
|
|
// Test organizer list
|
|
console.log('\n a) Testing organizer list...');
|
|
const listResponse = await page.goto(`${config.BASE_URL}/trainer/organizer/list/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const listTitle = await page.title();
|
|
const listUrl = page.url();
|
|
console.log(` Status: ${listResponse.status()}`);
|
|
console.log(` URL: ${listUrl}`);
|
|
console.log(` Title: "${listTitle}"`);
|
|
|
|
if (!listTitle.includes('Login') && listResponse.status() === 200) {
|
|
console.log(' ✅ Organizer list accessible');
|
|
|
|
const content = await page.content();
|
|
const hasContainer = content.includes('hvac-organizers-list');
|
|
const hasTable = content.includes('hvac-organizers-table');
|
|
const hasShortcode = content.includes('[hvac_trainer_organizers_list]');
|
|
|
|
console.log(` Has container: ${hasContainer ? 'Yes ✅' : 'No ❌'}`);
|
|
console.log(` Has table: ${hasTable ? 'Yes ✅' : 'No ❌'}`);
|
|
console.log(` Unprocessed shortcode: ${hasShortcode ? 'Yes ❌' : 'No ✅'}`);
|
|
|
|
} else {
|
|
console.log(' ❌ Organizer list not accessible or redirected to login');
|
|
}
|
|
|
|
// Test organizer manage
|
|
console.log('\n b) Testing organizer manage...');
|
|
const manageResponse = await page.goto(`${config.BASE_URL}/trainer/organizer/manage/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const manageTitle = await page.title();
|
|
const manageUrl = page.url();
|
|
console.log(` Status: ${manageResponse.status()}`);
|
|
console.log(` URL: ${manageUrl}`);
|
|
console.log(` Title: "${manageTitle}"`);
|
|
|
|
if (!manageTitle.includes('Login') && manageResponse.status() === 200) {
|
|
console.log(' ✅ Organizer manage accessible');
|
|
|
|
const content = await page.content();
|
|
const hasContainer = content.includes('hvac-organizer-manage');
|
|
const hasForm = content.includes('hvac-organizer-form');
|
|
const hasShortcode = content.includes('[hvac_trainer_organizer_manage]');
|
|
|
|
console.log(` Has container: ${hasContainer ? 'Yes ✅' : 'No ❌'}`);
|
|
console.log(` Has form: ${hasForm ? 'Yes ✅' : 'No ❌'}`);
|
|
console.log(` Unprocessed shortcode: ${hasShortcode ? 'Yes ❌' : 'No ✅'}`);
|
|
|
|
// Check for form fields
|
|
const formVisible = await page.locator('#hvac-organizer-form').isVisible();
|
|
console.log(` Form visible: ${formVisible ? 'Yes ✅' : 'No ❌'}`);
|
|
|
|
if (formVisible) {
|
|
const nameField = await page.locator('#org_name').isVisible();
|
|
console.log(` Name field visible: ${nameField ? 'Yes ✅' : 'No ❌'}`);
|
|
}
|
|
|
|
} else {
|
|
console.log(' ❌ Organizer manage not accessible or redirected to login');
|
|
}
|
|
|
|
// Step 5: Debug user roles
|
|
console.log('\n5. Checking user information...');
|
|
|
|
// Get current user info via REST API
|
|
try {
|
|
const userResponse = await page.evaluate(async () => {
|
|
const response = await fetch('/wp-json/wp/v2/users/me', {
|
|
credentials: 'same-origin'
|
|
});
|
|
if (response.ok) {
|
|
const user = await response.json();
|
|
return {
|
|
id: user.id,
|
|
name: user.name,
|
|
slug: user.slug,
|
|
roles: user.roles
|
|
};
|
|
} else {
|
|
return { error: 'Not authenticated' };
|
|
}
|
|
});
|
|
|
|
if (userResponse.error) {
|
|
console.log(` ❌ ${userResponse.error}`);
|
|
} else {
|
|
console.log(` User ID: ${userResponse.id}`);
|
|
console.log(` Username: ${userResponse.slug}`);
|
|
console.log(` Display Name: ${userResponse.name}`);
|
|
console.log(` Roles: ${JSON.stringify(userResponse.roles)}`);
|
|
|
|
const hasTrainerRole = userResponse.roles.includes('hvac_trainer');
|
|
console.log(` Has HVAC Trainer role: ${hasTrainerRole ? 'Yes ✅' : 'No ❌'}`);
|
|
}
|
|
} catch (error) {
|
|
console.log(` Error checking user: ${error.message}`);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(`❌ Test error: ${error.message}`);
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
debugAuthTest(); |