Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
- Add 90+ test files including E2E, unit, and integration tests - Implement Page Object Model (POM) architecture - Add Docker testing environment with comprehensive services - Include modernized test framework with error recovery - Add specialized test suites for master trainer and trainer workflows - Update .gitignore to properly track test infrastructure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
816 lines
No EOL
34 KiB
JavaScript
816 lines
No EOL
34 KiB
JavaScript
/**
|
|
* Trainer Management Comprehensive E2E Test Suite
|
|
*
|
|
* Tests all trainer management functionality including:
|
|
* - Dashboard widgets and statistics
|
|
* - Profile management and editing
|
|
* - Venue management (CRUD operations if available)
|
|
* - Organizer management system (if available)
|
|
* - Training leads functionality (if available)
|
|
* - Navigation consistency across all trainer pages
|
|
* - Permission validation and access control
|
|
* - Account status handling
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @version 2.0.0
|
|
* @created 2025-08-27
|
|
* @assignment Agent A: Trainer Management (15 pages)
|
|
*/
|
|
|
|
const { test, expect } = require('@playwright/test');
|
|
const BaseTest = require('../../framework/core/BaseTest');
|
|
const TrainerDashboard = require('../../framework/page-objects/TrainerDashboard');
|
|
|
|
class TrainerManagementTestSuite extends BaseTest {
|
|
constructor() {
|
|
super();
|
|
this.testStartTime = Date.now();
|
|
this.evidenceCollection = [];
|
|
this.emptyPageDocumentation = [];
|
|
this.navigationMatrix = [];
|
|
this.testResults = {
|
|
pagesAccessible: 0,
|
|
pagesFunctional: 0,
|
|
pagesEmpty: 0,
|
|
errorsDetected: 0
|
|
};
|
|
|
|
// Complete URL matrix for all trainer pages to test
|
|
this.trainerPages = [
|
|
{ url: '/trainer/dashboard/', name: 'Dashboard', priority: 'HIGH', expectedContent: 'Dashboard', functional: true },
|
|
{ url: '/trainer/venue/list/', name: 'Venue List', priority: 'MEDIUM', expectedContent: 'Venues', functional: true },
|
|
{ url: '/trainer/venue/manage/', name: 'Venue Management', priority: 'HIGH', expectedContent: 'Manage Venues', functional: false },
|
|
{ url: '/trainer/organizer/manage/', name: 'Organizer Management', priority: 'HIGH', expectedContent: 'Manage Organizers', functional: false },
|
|
{ url: '/trainer/profile/training-leads/', name: 'Training Leads', priority: 'HIGH', expectedContent: 'Training Leads', functional: false },
|
|
{ url: '/trainer/profile/edit/', name: 'Profile Edit', priority: 'HIGH', expectedContent: 'Edit Profile', functional: true },
|
|
{ url: '/trainer/profile/view/', name: 'Profile View', priority: 'MEDIUM', expectedContent: 'Profile', functional: true },
|
|
{ url: '/trainer/announcements/', name: 'Announcements', priority: 'MEDIUM', expectedContent: 'Announcements', functional: true },
|
|
{ url: '/trainer/resources/', name: 'Resources', priority: 'LOW', expectedContent: 'Resources', functional: true },
|
|
{ url: '/trainer/documentation/', name: 'Documentation', priority: 'LOW', expectedContent: 'Documentation', functional: true },
|
|
{ url: '/trainer-account-pending/', name: 'Account Pending', priority: 'MEDIUM', expectedContent: 'Account Pending', functional: true },
|
|
{ url: '/trainer-account-disabled/', name: 'Account Disabled', priority: 'MEDIUM', expectedContent: 'Account Disabled', functional: true },
|
|
{ url: '/trainer/events/', name: 'Event Management', priority: 'HIGH', expectedContent: 'Events', functional: true },
|
|
{ url: '/trainer/create-event/', name: 'Create Event', priority: 'HIGH', expectedContent: 'Create Event', functional: true },
|
|
{ url: '/trainer/training-leads/', name: 'Training Leads Management', priority: 'MEDIUM', expectedContent: 'Training Leads', functional: true }
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Enhanced WordPress error detection using MCP browser tools
|
|
*/
|
|
async detectWordPressErrors() {
|
|
const errors = [];
|
|
|
|
try {
|
|
// Use MCP browser evaluate to check for WordPress errors
|
|
const errorResults = await this.page.evaluate(() => {
|
|
const detectedErrors = [];
|
|
|
|
// Check for PHP errors
|
|
if (document.body.innerHTML.includes('Fatal error:') ||
|
|
document.body.innerHTML.includes('Warning:') ||
|
|
document.body.innerHTML.includes('Notice:')) {
|
|
detectedErrors.push('PHP_ERROR');
|
|
}
|
|
|
|
// Check for WordPress errors
|
|
if (document.querySelector('.wp-die-message')) {
|
|
detectedErrors.push('WP_DIE');
|
|
}
|
|
|
|
// Check for plugin conflicts
|
|
if (document.querySelector('.error-message, .notice-error')) {
|
|
detectedErrors.push('PLUGIN_ERROR');
|
|
}
|
|
|
|
// Check for authentication errors
|
|
if (document.body.innerHTML.includes('You do not have permission') ||
|
|
document.body.innerHTML.includes('Access denied')) {
|
|
detectedErrors.push('ACCESS_DENIED');
|
|
}
|
|
|
|
// Check for empty/broken pages
|
|
if (document.body.innerHTML.trim().length < 100) {
|
|
detectedErrors.push('EMPTY_PAGE');
|
|
}
|
|
|
|
return detectedErrors;
|
|
});
|
|
|
|
errors.push(...errorResults);
|
|
|
|
} catch (error) {
|
|
console.warn('Error detection failed:', error.message);
|
|
}
|
|
|
|
return errors;
|
|
}
|
|
|
|
/**
|
|
* Take screenshot with MCP browser tools
|
|
*/
|
|
async captureEvidence(name, context = '') {
|
|
try {
|
|
const timestamp = Date.now();
|
|
const filename = `trainer-management-${name}-${timestamp}.png`;
|
|
|
|
// Take screenshot using page.screenshot (MCP compatible)
|
|
await this.page.screenshot({
|
|
path: `./test-results/screenshots/${filename}`,
|
|
fullPage: true
|
|
});
|
|
|
|
// Get page snapshot for additional context
|
|
const currentUrl = this.page.url();
|
|
const pageTitle = await this.page.title();
|
|
|
|
const evidence = {
|
|
filename,
|
|
context,
|
|
url: currentUrl,
|
|
title: pageTitle,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
this.evidenceCollection.push(evidence);
|
|
console.log(`📸 Evidence captured: ${filename} (${context})`);
|
|
|
|
return evidence;
|
|
|
|
} catch (error) {
|
|
console.warn('Screenshot capture failed:', error.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Navigate to page and validate with MCP browser tools
|
|
*/
|
|
async navigateAndValidate(pageInfo) {
|
|
try {
|
|
const baseUrl = 'https://upskill-staging.measurequick.com';
|
|
const fullUrl = `${baseUrl}${pageInfo.url}`;
|
|
|
|
console.log(`🔗 Testing page: ${pageInfo.name} (${fullUrl})`);
|
|
|
|
// Navigate using standard page.goto (MCP compatible)
|
|
await this.page.goto(fullUrl, { waitUntil: 'networkidle' });
|
|
|
|
// Wait for WordPress to load
|
|
await this.page.waitForLoadState('domcontentloaded');
|
|
|
|
// Detect WordPress errors
|
|
const errors = await this.detectWordPressErrors();
|
|
|
|
// Take evidence screenshot
|
|
const evidence = await this.captureEvidence(
|
|
pageInfo.name.toLowerCase().replace(/\s+/g, '-'),
|
|
`Page accessibility test for ${pageInfo.name}`
|
|
);
|
|
|
|
// Validate page accessibility
|
|
const pageTitle = await this.page.title();
|
|
const bodyText = await this.page.textContent('body');
|
|
const hasContent = bodyText && bodyText.trim().length > 100;
|
|
|
|
// Check for WordPress authentication
|
|
const isAuthenticated = await this.page.evaluate(() => {
|
|
return document.body.classList.contains('logged-in') ||
|
|
document.querySelector('#wpadminbar') !== null;
|
|
});
|
|
|
|
const result = {
|
|
page: pageInfo,
|
|
url: fullUrl,
|
|
title: pageTitle,
|
|
hasContent,
|
|
isAuthenticated,
|
|
errors,
|
|
evidence,
|
|
functional: hasContent && errors.length === 0,
|
|
isEmpty: !hasContent || errors.includes('EMPTY_PAGE'),
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Update test results
|
|
this.testResults.pagesAccessible++;
|
|
if (result.functional) {
|
|
this.testResults.pagesFunctional++;
|
|
}
|
|
if (result.isEmpty) {
|
|
this.testResults.pagesEmpty++;
|
|
this.emptyPageDocumentation.push(result);
|
|
}
|
|
if (errors.length > 0) {
|
|
this.testResults.errorsDetected += errors.length;
|
|
}
|
|
|
|
// Add to navigation matrix
|
|
this.navigationMatrix.push(result);
|
|
|
|
console.log(`${result.functional ? '✅' : '❌'} ${pageInfo.name}: ${result.functional ? 'Functional' : 'Issues detected'}`);
|
|
|
|
return result;
|
|
|
|
} catch (error) {
|
|
console.error(`❌ Navigation failed for ${pageInfo.name}:`, error.message);
|
|
|
|
const evidence = await this.captureEvidence(
|
|
`${pageInfo.name.toLowerCase().replace(/\s+/g, '-')}-error`,
|
|
`Navigation error for ${pageInfo.name}`
|
|
);
|
|
|
|
const errorResult = {
|
|
page: pageInfo,
|
|
error: error.message,
|
|
evidence,
|
|
functional: false,
|
|
isEmpty: true,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
this.testResults.errorsDetected++;
|
|
this.emptyPageDocumentation.push(errorResult);
|
|
this.navigationMatrix.push(errorResult);
|
|
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test dashboard functionality comprehensively
|
|
*/
|
|
async testDashboardFunctionality() {
|
|
const dashboardPage = new TrainerDashboard(this.page);
|
|
|
|
try {
|
|
console.log('🎯 Testing Dashboard Comprehensive Functionality');
|
|
|
|
// Navigate to dashboard
|
|
await dashboardPage.navigate();
|
|
await this.captureEvidence('dashboard-loaded', 'Dashboard initial load');
|
|
|
|
// Verify dashboard components
|
|
await dashboardPage.verifyDashboard();
|
|
|
|
// Get dashboard statistics
|
|
const stats = await dashboardPage.getDashboardStats();
|
|
console.log('📊 Dashboard Statistics:', stats);
|
|
|
|
// Test dashboard widgets
|
|
const widgets = ['eventCount', 'upcomingEvents', 'recentActivity'];
|
|
for (const widget of widgets) {
|
|
try {
|
|
await dashboardPage.waitForWidget(widget);
|
|
console.log(`✅ Widget loaded: ${widget}`);
|
|
} catch (error) {
|
|
console.log(`⚠️ Widget not available: ${widget}`);
|
|
}
|
|
}
|
|
|
|
// Test quick actions
|
|
const quickActions = ['view-profile', 'view-venues', 'view-organizers'];
|
|
for (const action of quickActions) {
|
|
try {
|
|
// Just verify the action exists, don't navigate (to avoid disrupting test flow)
|
|
console.log(`🔍 Checking quick action: ${action}`);
|
|
await this.page.waitForSelector(`[data-action="${action}"], a[href*="${action.replace('view-', '')}"]`,
|
|
{ timeout: 2000 });
|
|
console.log(`✅ Quick action available: ${action}`);
|
|
} catch (error) {
|
|
console.log(`⚠️ Quick action not found: ${action}`);
|
|
}
|
|
}
|
|
|
|
// Test mobile responsiveness
|
|
const responsiveness = await dashboardPage.checkMobileResponsiveness();
|
|
console.log('📱 Mobile responsiveness:', responsiveness.isMobileResponsive ? 'Yes' : 'No');
|
|
|
|
// Take final dashboard screenshot
|
|
await this.captureEvidence('dashboard-complete', 'Dashboard functionality testing complete');
|
|
|
|
return {
|
|
success: true,
|
|
stats,
|
|
responsiveness,
|
|
widgets: widgets.length,
|
|
quickActions: quickActions.length
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Dashboard testing failed:', error.message);
|
|
await this.captureEvidence('dashboard-error', `Dashboard testing error: ${error.message}`);
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test venue management functionality (if available)
|
|
*/
|
|
async testVenueManagement() {
|
|
try {
|
|
console.log('🏢 Testing Venue Management Functionality');
|
|
|
|
// Test venue list page
|
|
const venueListResult = await this.navigateAndValidate({
|
|
url: '/trainer/venue/list/',
|
|
name: 'Venue List',
|
|
priority: 'MEDIUM'
|
|
});
|
|
|
|
// Test venue management page (likely empty)
|
|
const venueManageResult = await this.navigateAndValidate({
|
|
url: '/trainer/venue/manage/',
|
|
name: 'Venue Management',
|
|
priority: 'HIGH'
|
|
});
|
|
|
|
// If venue management page is functional, test CRUD operations
|
|
if (venueManageResult.functional) {
|
|
console.log('✅ Venue Management page is functional - testing CRUD operations');
|
|
|
|
// Test venue form functionality
|
|
const hasCreateForm = await this.page.locator('form[data-form="venue-create"], form[action*="venue"]').count() > 0;
|
|
if (hasCreateForm) {
|
|
console.log('✅ Venue creation form found');
|
|
await this.captureEvidence('venue-create-form', 'Venue creation form available');
|
|
}
|
|
|
|
// Test venue listing functionality
|
|
const venueCount = await this.page.locator('.venue-item, .venue-row, [data-venue]').count();
|
|
console.log(`📋 Found ${venueCount} venues in listing`);
|
|
|
|
} else {
|
|
console.log('⚠️ Venue Management page is empty or non-functional');
|
|
// Document the empty page
|
|
if (venueManageResult.isEmpty) {
|
|
console.log('📝 Documenting empty Venue Management page');
|
|
}
|
|
}
|
|
|
|
return {
|
|
venueList: venueListResult,
|
|
venueManage: venueManageResult,
|
|
functional: venueListResult.functional || venueManageResult.functional
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Venue management testing failed:', error.message);
|
|
await this.captureEvidence('venue-management-error', `Venue management error: ${error.message}`);
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test organizer management functionality (if available)
|
|
*/
|
|
async testOrganizerManagement() {
|
|
try {
|
|
console.log('👥 Testing Organizer Management Functionality');
|
|
|
|
// Test organizer management page (likely empty)
|
|
const organizerResult = await this.navigateAndValidate({
|
|
url: '/trainer/organizer/manage/',
|
|
name: 'Organizer Management',
|
|
priority: 'HIGH'
|
|
});
|
|
|
|
if (organizerResult.functional) {
|
|
console.log('✅ Organizer Management page is functional - testing features');
|
|
|
|
// Test organizer form functionality
|
|
const hasCreateForm = await this.page.locator('form[data-form="organizer-create"], form[action*="organizer"]').count() > 0;
|
|
if (hasCreateForm) {
|
|
console.log('✅ Organizer creation form found');
|
|
await this.captureEvidence('organizer-create-form', 'Organizer creation form available');
|
|
}
|
|
|
|
// Test organizer listing
|
|
const organizerCount = await this.page.locator('.organizer-item, .organizer-row, [data-organizer]').count();
|
|
console.log(`📋 Found ${organizerCount} organizers in listing`);
|
|
|
|
} else {
|
|
console.log('⚠️ Organizer Management page is empty or non-functional');
|
|
}
|
|
|
|
return {
|
|
organizer: organizerResult,
|
|
functional: organizerResult.functional
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Organizer management testing failed:', error.message);
|
|
await this.captureEvidence('organizer-management-error', `Organizer management error: ${error.message}`);
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test profile management functionality
|
|
*/
|
|
async testProfileManagement() {
|
|
try {
|
|
console.log('👤 Testing Profile Management Functionality');
|
|
|
|
// Test profile view page
|
|
const profileViewResult = await this.navigateAndValidate({
|
|
url: '/trainer/profile/view/',
|
|
name: 'Profile View',
|
|
priority: 'MEDIUM'
|
|
});
|
|
|
|
// Test profile edit page
|
|
const profileEditResult = await this.navigateAndValidate({
|
|
url: '/trainer/profile/edit/',
|
|
name: 'Profile Edit',
|
|
priority: 'HIGH'
|
|
});
|
|
|
|
// Test training leads page (likely empty)
|
|
const trainingLeadsResult = await this.navigateAndValidate({
|
|
url: '/trainer/profile/training-leads/',
|
|
name: 'Training Leads Profile',
|
|
priority: 'HIGH'
|
|
});
|
|
|
|
// If profile edit is functional, test form functionality
|
|
if (profileEditResult.functional) {
|
|
console.log('✅ Profile Edit page is functional - testing form features');
|
|
|
|
// Look for profile form fields
|
|
const formFields = await this.page.locator('input, textarea, select').count();
|
|
console.log(`📝 Found ${formFields} form fields on profile edit page`);
|
|
|
|
// Check for specific trainer profile fields
|
|
const trainerFields = [
|
|
'input[name="trainer_name"], #trainer_name',
|
|
'textarea[name="trainer_bio"], #trainer_bio',
|
|
'input[name="trainer_email"], #trainer_email',
|
|
'input[name="trainer_phone"], #trainer_phone'
|
|
];
|
|
|
|
let fieldsFound = 0;
|
|
for (const fieldSelector of trainerFields) {
|
|
const fieldExists = await this.page.locator(fieldSelector).count() > 0;
|
|
if (fieldExists) {
|
|
fieldsFound++;
|
|
console.log(`✅ Profile field found: ${fieldSelector}`);
|
|
}
|
|
}
|
|
|
|
console.log(`📋 Profile form has ${fieldsFound}/${trainerFields.length} expected fields`);
|
|
await this.captureEvidence('profile-edit-form', 'Profile edit form analysis complete');
|
|
}
|
|
|
|
return {
|
|
profileView: profileViewResult,
|
|
profileEdit: profileEditResult,
|
|
trainingLeads: trainingLeadsResult,
|
|
functional: profileViewResult.functional || profileEditResult.functional
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Profile management testing failed:', error.message);
|
|
await this.captureEvidence('profile-management-error', `Profile management error: ${error.message}`);
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test navigation consistency across all trainer pages
|
|
*/
|
|
async testNavigationConsistency() {
|
|
try {
|
|
console.log('🧭 Testing Navigation Consistency');
|
|
|
|
let navigationErrors = [];
|
|
let commonNavigationElements = {};
|
|
|
|
// Analyze navigation on each functional page
|
|
for (const result of this.navigationMatrix) {
|
|
if (result.functional && !result.error) {
|
|
try {
|
|
// Navigate back to the page
|
|
await this.page.goto(`https://upskill-staging.measurequick.com${result.page.url}`);
|
|
|
|
// Check for common navigation elements
|
|
const navElements = {
|
|
breadcrumb: await this.page.locator('.hvac-breadcrumb, .breadcrumb').count() > 0,
|
|
mainNav: await this.page.locator('.hvac-trainer-nav, .trainer-nav').count() > 0,
|
|
userMenu: await this.page.locator('.user-menu, .trainer-menu').count() > 0,
|
|
logoutLink: await this.page.locator('a[href*="logout"]').count() > 0
|
|
};
|
|
|
|
// Track common elements
|
|
for (const [element, exists] of Object.entries(navElements)) {
|
|
if (!commonNavigationElements[element]) {
|
|
commonNavigationElements[element] = { count: 0, total: 0 };
|
|
}
|
|
commonNavigationElements[element].total++;
|
|
if (exists) {
|
|
commonNavigationElements[element].count++;
|
|
}
|
|
}
|
|
|
|
console.log(`🔍 Navigation analysis for ${result.page.name}: ${Object.values(navElements).filter(Boolean).length}/4 elements found`);
|
|
|
|
} catch (error) {
|
|
navigationErrors.push({
|
|
page: result.page.name,
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Calculate navigation consistency scores
|
|
const consistencyScores = {};
|
|
for (const [element, data] of Object.entries(commonNavigationElements)) {
|
|
consistencyScores[element] = data.total > 0 ? (data.count / data.total) * 100 : 0;
|
|
}
|
|
|
|
console.log('📊 Navigation Consistency Scores:');
|
|
for (const [element, score] of Object.entries(consistencyScores)) {
|
|
console.log(` ${element}: ${score.toFixed(1)}%`);
|
|
}
|
|
|
|
await this.captureEvidence('navigation-consistency', 'Navigation consistency analysis complete');
|
|
|
|
return {
|
|
consistencyScores,
|
|
navigationErrors,
|
|
elementsAnalyzed: Object.keys(commonNavigationElements).length
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Navigation consistency testing failed:', error.message);
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate comprehensive test report
|
|
*/
|
|
generateTestReport() {
|
|
const report = {
|
|
testSuite: 'Trainer Management Comprehensive E2E Tests',
|
|
execution: {
|
|
startTime: new Date(this.testStartTime).toISOString(),
|
|
endTime: new Date().toISOString(),
|
|
duration: Date.now() - this.testStartTime,
|
|
environment: 'staging'
|
|
},
|
|
results: this.testResults,
|
|
pagesTested: this.trainerPages.length,
|
|
evidenceCollected: this.evidenceCollection.length,
|
|
emptyPages: this.emptyPageDocumentation.length,
|
|
navigationMatrix: this.navigationMatrix
|
|
};
|
|
|
|
// High priority empty pages summary
|
|
const highPriorityEmpty = this.emptyPageDocumentation.filter(page =>
|
|
page.page && page.page.priority === 'HIGH'
|
|
);
|
|
|
|
if (highPriorityEmpty.length > 0) {
|
|
report.criticalFindings = {
|
|
highPriorityEmptyPages: highPriorityEmpty.map(page => ({
|
|
name: page.page?.name || 'Unknown',
|
|
url: page.page?.url || 'Unknown',
|
|
recommendation: `Implement ${page.page?.name || 'page'} functionality as specified in requirements`
|
|
}))
|
|
};
|
|
}
|
|
|
|
return report;
|
|
}
|
|
}
|
|
|
|
// Main Test Suite Implementation
|
|
test.describe('Trainer Management Comprehensive E2E Tests', () => {
|
|
let testSuite;
|
|
let page;
|
|
|
|
test.beforeAll(async () => {
|
|
console.log('🚀 Starting Trainer Management Comprehensive Test Suite');
|
|
console.log('📋 Testing Environment: https://upskill-staging.measurequick.com');
|
|
console.log('👤 Test Account: test_trainer');
|
|
});
|
|
|
|
test.beforeEach(async ({ page: testPage }, testInfo) => {
|
|
page = testPage;
|
|
testSuite = new TrainerManagementTestSuite();
|
|
|
|
// Set up test environment using base test setup
|
|
await testSuite.setup(page, testInfo);
|
|
|
|
// Authenticate as trainer
|
|
console.log('🔐 Authenticating as test trainer...');
|
|
await testSuite.authenticateAs(page, 'trainer');
|
|
|
|
// Verify authentication success
|
|
const currentUrl = page.url();
|
|
if (!currentUrl.includes('/trainer/')) {
|
|
throw new Error('Authentication failed - not redirected to trainer area');
|
|
}
|
|
|
|
console.log('✅ Authentication successful');
|
|
});
|
|
|
|
test.afterEach(async ({ page }, testInfo) => {
|
|
if (testSuite) {
|
|
await testSuite.teardown(page, testInfo);
|
|
}
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
if (testSuite) {
|
|
const report = testSuite.generateTestReport();
|
|
console.log('\n📊 TRAINER MANAGEMENT TEST SUMMARY');
|
|
console.log('=====================================');
|
|
console.log(`Pages Tested: ${report.pagesTested}`);
|
|
console.log(`Pages Accessible: ${report.results.pagesAccessible}`);
|
|
console.log(`Pages Functional: ${report.results.pagesFunctional}`);
|
|
console.log(`Pages Empty: ${report.results.pagesEmpty}`);
|
|
console.log(`Errors Detected: ${report.results.errorsDetected}`);
|
|
console.log(`Evidence Collected: ${report.evidenceCollected} screenshots`);
|
|
|
|
if (report.criticalFindings && report.criticalFindings.highPriorityEmptyPages.length > 0) {
|
|
console.log('\n🔴 HIGH PRIORITY EMPTY PAGES:');
|
|
report.criticalFindings.highPriorityEmptyPages.forEach(page => {
|
|
console.log(` - ${page.name} (${page.url})`);
|
|
console.log(` Recommendation: ${page.recommendation}`);
|
|
});
|
|
}
|
|
|
|
console.log('\n📁 Test artifacts saved in: ./test-results/screenshots/');
|
|
console.log('=====================================');
|
|
}
|
|
});
|
|
|
|
test('Phase 1: Authentication & Framework Integration', async () => {
|
|
// Framework integration is tested in beforeEach
|
|
expect(page.url()).toContain('/trainer/');
|
|
|
|
// Take evidence of successful authentication
|
|
await testSuite.captureEvidence('authentication-success', 'Trainer authentication validated');
|
|
|
|
// Verify WordPress environment
|
|
const errors = await testSuite.detectWordPressErrors();
|
|
expect(errors).toHaveLength(0);
|
|
|
|
console.log('✅ Phase 1 Complete: Authentication & Framework Integration');
|
|
});
|
|
|
|
test('Phase 2: Page Accessibility Matrix Testing', async () => {
|
|
console.log('🔍 Testing all 15 trainer pages for accessibility...');
|
|
|
|
const results = [];
|
|
|
|
// Test each page systematically
|
|
for (const pageInfo of testSuite.trainerPages) {
|
|
const result = await testSuite.navigateAndValidate(pageInfo);
|
|
results.push(result);
|
|
|
|
// Small delay to avoid overwhelming the server
|
|
await page.waitForTimeout(500);
|
|
}
|
|
|
|
// Validate results
|
|
expect(results.length).toBe(15);
|
|
|
|
const functionalPages = results.filter(r => r.functional).length;
|
|
const emptyPages = results.filter(r => r.isEmpty).length;
|
|
|
|
console.log(`📊 Page Accessibility Results: ${functionalPages} functional, ${emptyPages} empty`);
|
|
|
|
// High priority pages should be functional or properly documented if empty
|
|
const highPriorityPages = results.filter(r => r.page.priority === 'HIGH');
|
|
const highPriorityEmpty = highPriorityPages.filter(r => r.isEmpty);
|
|
|
|
if (highPriorityEmpty.length > 0) {
|
|
console.log(`⚠️ Found ${highPriorityEmpty.length} high-priority empty pages - documented for development`);
|
|
}
|
|
|
|
console.log('✅ Phase 2 Complete: Page Accessibility Matrix Testing');
|
|
});
|
|
|
|
test('Phase 3: Dashboard Comprehensive Testing', async () => {
|
|
const dashboardResults = await testSuite.testDashboardFunctionality();
|
|
|
|
expect(dashboardResults.success).toBe(true);
|
|
|
|
if (dashboardResults.stats) {
|
|
console.log('📈 Dashboard statistics captured successfully');
|
|
}
|
|
|
|
if (dashboardResults.responsiveness) {
|
|
console.log('📱 Mobile responsiveness validated');
|
|
}
|
|
|
|
console.log('✅ Phase 3 Complete: Dashboard Comprehensive Testing');
|
|
});
|
|
|
|
test('Phase 4: Venue Management Testing', async () => {
|
|
const venueResults = await testSuite.testVenueManagement();
|
|
|
|
// Venue management may be empty - document findings
|
|
if (venueResults.functional) {
|
|
console.log('✅ Venue management functionality is available');
|
|
} else {
|
|
console.log('📝 Venue management functionality documented as empty/non-functional');
|
|
}
|
|
|
|
console.log('✅ Phase 4 Complete: Venue Management Testing');
|
|
});
|
|
|
|
test('Phase 5: Organizer Management Testing', async () => {
|
|
const organizerResults = await testSuite.testOrganizerManagement();
|
|
|
|
// Organizer management may be empty - document findings
|
|
if (organizerResults.functional) {
|
|
console.log('✅ Organizer management functionality is available');
|
|
} else {
|
|
console.log('📝 Organizer management functionality documented as empty/non-functional');
|
|
}
|
|
|
|
console.log('✅ Phase 5 Complete: Organizer Management Testing');
|
|
});
|
|
|
|
test('Phase 6: Profile Management Testing', async () => {
|
|
const profileResults = await testSuite.testProfileManagement();
|
|
|
|
expect(profileResults.functional).toBe(true);
|
|
|
|
// At least one of the profile pages should be functional
|
|
const functionalProfilePages = [
|
|
profileResults.profileView?.functional,
|
|
profileResults.profileEdit?.functional
|
|
].filter(Boolean).length;
|
|
|
|
expect(functionalProfilePages).toBeGreaterThan(0);
|
|
|
|
console.log('✅ Phase 6 Complete: Profile Management Testing');
|
|
});
|
|
|
|
test('Phase 7: Navigation Consistency & Workflow Testing', async () => {
|
|
const navigationResults = await testSuite.testNavigationConsistency();
|
|
|
|
if (navigationResults.consistencyScores) {
|
|
// At least 50% consistency expected for main navigation elements
|
|
const mainNavScore = navigationResults.consistencyScores.mainNav || 0;
|
|
console.log(`🧭 Main navigation consistency: ${mainNavScore.toFixed(1)}%`);
|
|
|
|
if (mainNavScore < 50) {
|
|
console.log('⚠️ Low navigation consistency detected - documented for improvement');
|
|
}
|
|
}
|
|
|
|
if (navigationResults.navigationErrors && navigationResults.navigationErrors.length > 0) {
|
|
console.log(`⚠️ Navigation errors found: ${navigationResults.navigationErrors.length}`);
|
|
}
|
|
|
|
console.log('✅ Phase 7 Complete: Navigation Consistency & Workflow Testing');
|
|
});
|
|
|
|
test('Phase 8: Evidence Collection & Final Validation', async () => {
|
|
// Final evidence collection
|
|
await testSuite.captureEvidence('test-suite-complete', 'All trainer management tests completed');
|
|
|
|
// Generate and validate comprehensive report
|
|
const finalReport = testSuite.generateTestReport();
|
|
|
|
expect(finalReport.pagesTested).toBe(15);
|
|
expect(finalReport.evidenceCollected).toBeGreaterThan(10);
|
|
|
|
// Validate test coverage
|
|
const coveragePercentage = (finalReport.results.pagesAccessible / finalReport.pagesTested) * 100;
|
|
console.log(`📈 Test Coverage: ${coveragePercentage.toFixed(1)}%`);
|
|
|
|
expect(coveragePercentage).toBeGreaterThan(80); // At least 80% of pages should be accessible
|
|
|
|
console.log('✅ Phase 8 Complete: Evidence Collection & Final Validation');
|
|
console.log('🎉 TRAINER MANAGEMENT COMPREHENSIVE E2E TESTING COMPLETE');
|
|
});
|
|
});
|
|
|
|
module.exports = TrainerManagementTestSuite; |