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>
353 lines
No EOL
14 KiB
JavaScript
353 lines
No EOL
14 KiB
JavaScript
/**
|
|
* Core HVAC Trainer Events Test Suite
|
|
*
|
|
* This simplified test suite focuses on core functionality:
|
|
* - Event creation with minimal and full fields
|
|
* - Form validation
|
|
* - Data persistence
|
|
* - Mobile responsiveness
|
|
*
|
|
* Test Environment: https://upskill-staging.measurequick.com
|
|
* Test User: test_trainer / TestTrainer123!
|
|
*/
|
|
|
|
const { test, expect } = require('@playwright/test');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Test configuration
|
|
const STAGING_URL = 'https://upskill-staging.measurequick.com';
|
|
const TEST_USER = 'test_trainer';
|
|
const TEST_PASSWORD = 'TestTrainer123!';
|
|
|
|
// Test results tracking
|
|
const testResults = {
|
|
timestamp: new Date().toISOString(),
|
|
totalTests: 0,
|
|
passedTests: 0,
|
|
failedTests: 0,
|
|
testMatrix: {},
|
|
recommendations: []
|
|
};
|
|
|
|
// Utility functions
|
|
async function login(page) {
|
|
await page.goto(`${STAGING_URL}/wp-admin`);
|
|
await page.fill('#user_login', TEST_USER);
|
|
await page.fill('#user_pass', TEST_PASSWORD);
|
|
await page.click('#wp-submit');
|
|
await page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
async function recordTestResult(testName, passed, error = null) {
|
|
testResults.totalTests++;
|
|
if (passed) {
|
|
testResults.passedTests++;
|
|
} else {
|
|
testResults.failedTests++;
|
|
}
|
|
|
|
testResults.testMatrix[testName] = {
|
|
passed,
|
|
error: error?.message,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
}
|
|
|
|
test.describe('Core HVAC Trainer Events System Tests', () => {
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await login(page);
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
// Generate test report
|
|
const successRate = (testResults.passedTests / testResults.totalTests * 100).toFixed(2) + '%';
|
|
const reportData = {
|
|
...testResults,
|
|
successRate,
|
|
duration: new Date().toISOString()
|
|
};
|
|
|
|
const reportPath = path.join(__dirname, '../../reports/core-test-report.json');
|
|
if (!fs.existsSync(path.dirname(reportPath))) {
|
|
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
|
|
}
|
|
|
|
fs.writeFileSync(reportPath, JSON.stringify(reportData, null, 2));
|
|
console.log('\n📊 Core Test Results Summary:');
|
|
console.log(` Total Tests: ${testResults.totalTests}`);
|
|
console.log(` Passed: ${testResults.passedTests}`);
|
|
console.log(` Failed: ${testResults.failedTests}`);
|
|
console.log(` Success Rate: ${successRate}`);
|
|
console.log(` Report: ${reportPath}`);
|
|
});
|
|
|
|
test('Event Creation - Minimal Required Fields', async ({ page }) => {
|
|
const testName = 'Event Creation - Minimal Required Fields';
|
|
let passed = false;
|
|
|
|
try {
|
|
// Navigate to dashboard
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Look for Create Event button or link
|
|
const createEventButton = await page.locator('text=Create Event, a[href*="event"], .event-create, #create-event').first();
|
|
|
|
if (await createEventButton.count() > 0) {
|
|
await createEventButton.click();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Fill minimal required fields
|
|
const timestamp = Date.now();
|
|
const eventTitle = `Minimal Test Event ${timestamp}`;
|
|
|
|
// Look for title field
|
|
const titleField = await page.locator('#post_title, input[name*="title"], .event-title').first();
|
|
if (await titleField.count() > 0) {
|
|
await titleField.fill(eventTitle);
|
|
|
|
// Look for date fields
|
|
const startDateField = await page.locator('#EventStartDate, input[name*="start"], input[type="date"]').first();
|
|
if (await startDateField.count() > 0) {
|
|
await startDateField.fill('2025-12-01');
|
|
|
|
// Try to submit
|
|
const submitButton = await page.locator('text=Publish, text=Save, input[type="submit"], .submit-button').first();
|
|
if (await submitButton.count() > 0) {
|
|
await submitButton.click();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check for success indicators
|
|
const successMessage = await page.locator('.notice-success, .success, .saved, text=published, text=saved').count();
|
|
if (successMessage > 0) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('No clear success feedback after event creation');
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Submit button not found on event creation page');
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Date field not found on event creation page');
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Title field not found on event creation page');
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Create Event button not found on dashboard');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Dashboard Navigation and Access', async ({ page }) => {
|
|
const testName = 'Dashboard Navigation and Access';
|
|
let passed = false;
|
|
|
|
try {
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check if dashboard loads properly
|
|
const pageTitle = await page.locator('h1, .page-title, title').first();
|
|
const navigationMenu = await page.locator('nav, .menu, .navigation').count();
|
|
const mainContent = await page.locator('main, .content, .dashboard-content').count();
|
|
|
|
if (await pageTitle.count() > 0 && navigationMenu > 0 && mainContent > 0) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('Dashboard page structure may be incomplete');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Event List Access', async ({ page }) => {
|
|
const testName = 'Event List Access';
|
|
let passed = false;
|
|
|
|
try {
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Look for events list or My Events link
|
|
const eventsLink = await page.locator('text=My Events, text=Events, a[href*="event"]').first();
|
|
|
|
if (await eventsLink.count() > 0) {
|
|
await eventsLink.click();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check if events page loads
|
|
const eventsPage = await page.locator('.events-list, .event-item, table, .wp-list-table').count();
|
|
if (eventsPage > 0) {
|
|
passed = true;
|
|
} else {
|
|
// Even empty state is acceptable
|
|
const emptyState = await page.locator('text=No events, .empty, .no-results').count();
|
|
if (emptyState > 0) {
|
|
passed = true;
|
|
}
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Events list link not found');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Mobile Responsiveness - Basic', async ({ page }) => {
|
|
const testName = 'Mobile Responsiveness - Basic';
|
|
let passed = false;
|
|
|
|
try {
|
|
// Test mobile viewport
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check if page is responsive
|
|
const navigationVisible = await page.locator('nav, .menu, .navigation').isVisible();
|
|
const contentVisible = await page.locator('main, .content').isVisible();
|
|
|
|
if (navigationVisible && contentVisible) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('Mobile layout may have visibility issues');
|
|
}
|
|
|
|
// Reset viewport
|
|
await page.setViewportSize({ width: 1920, height: 1080 });
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('User Authentication State', async ({ page }) => {
|
|
const testName = 'User Authentication State';
|
|
let passed = false;
|
|
|
|
try {
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check for authenticated user indicators
|
|
const userProfile = await page.locator('text=Profile, .user-info, .user-name, .logged-in').count();
|
|
const logoutLink = await page.locator('text=Logout, .logout').count();
|
|
const adminBar = await page.locator('#wpadminbar, .admin-bar').count();
|
|
|
|
if (userProfile > 0 || logoutLink > 0 || adminBar > 0) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('User authentication state indicators not clear');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Page Load Performance', async ({ page }) => {
|
|
const testName = 'Page Load Performance';
|
|
let passed = false;
|
|
|
|
try {
|
|
const startTime = Date.now();
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
const loadTime = Date.now() - startTime;
|
|
|
|
// Page should load within reasonable time (15 seconds)
|
|
if (loadTime < 15000) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push(`Page load time (${loadTime}ms) exceeds 15 seconds`);
|
|
}
|
|
|
|
console.log(`Dashboard load time: ${loadTime}ms`);
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Basic Form Elements Present', async ({ page }) => {
|
|
const testName = 'Basic Form Elements Present';
|
|
let passed = false;
|
|
|
|
try {
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Try to access event creation
|
|
const createEventButton = await page.locator('text=Create Event, a[href*="event"], .event-create').first();
|
|
|
|
if (await createEventButton.count() > 0) {
|
|
await createEventButton.click();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check for basic form elements
|
|
const formElements = await page.locator('input, textarea, select, button').count();
|
|
const titleField = await page.locator('#post_title, input[name*="title"]').count();
|
|
|
|
if (formElements >= 3 && titleField > 0) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('Event creation form may be incomplete');
|
|
}
|
|
} else {
|
|
testResults.recommendations.push('Cannot access event creation form');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
test('Cross-Browser Compatibility - Basic Check', async ({ page }) => {
|
|
const testName = 'Cross-Browser Compatibility - Basic Check';
|
|
let passed = false;
|
|
|
|
try {
|
|
await page.goto(`${STAGING_URL}/trainer/dashboard/`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check if basic JavaScript works
|
|
const jsWorking = await page.evaluate(() => {
|
|
return typeof document !== 'undefined' && typeof window !== 'undefined';
|
|
});
|
|
|
|
// Check if CSS is applied
|
|
const cssLoaded = await page.evaluate(() => {
|
|
const element = document.querySelector('body');
|
|
return element && getComputedStyle(element).display !== '';
|
|
});
|
|
|
|
if (jsWorking && cssLoaded) {
|
|
passed = true;
|
|
} else {
|
|
testResults.recommendations.push('Basic browser compatibility issues detected');
|
|
}
|
|
} catch (testError) {
|
|
console.log(`Test ${testName} failed: ${testError.message}`);
|
|
}
|
|
|
|
await recordTestResult(testName, passed);
|
|
});
|
|
|
|
}); |