upskill-event-manager/tests/page-objects/master-trainer/MasterTrainerEvents.js
Ben 7c9ca65cf2
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
feat: add comprehensive test framework and test files
- 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>
2025-08-29 23:23:26 -03:00

353 lines
No EOL
12 KiB
JavaScript

/**
* Master Trainer Events Management Page Object
* Handles interactions with the master trainer events management page
*/
const BasePage = require('../base/BasePage');
class MasterTrainerEvents extends BasePage {
constructor(page = null) {
super(page);
this.url = '/master-trainer/events/';
this.title = 'Events Management';
this.selectors = {
// Main page elements
pageTitle: 'h1, .page-title, .events-title',
eventsContainer: '.events-container, .events-list, .events-table',
// Events list and table
eventsTable: 'table.events-table, .events-grid',
eventRows: 'tr.event-row, .event-item',
eventTitle: '.event-title, .event-name',
eventDate: '.event-date, .event-start-date',
eventStatus: '.event-status, .status',
eventTrainer: '.event-trainer, .trainer-name',
eventVenue: '.event-venue, .venue-name',
// Action buttons
createEventBtn: 'a[href*="create"], .create-event, .add-event',
editEventBtn: 'a[href*="edit"], .edit-event, .event-edit',
deleteEventBtn: 'a[href*="delete"], .delete-event, .event-delete',
viewEventBtn: 'a[href*="view"], .view-event, .event-view',
// Bulk actions
bulkActionsSelect: 'select[name="bulk-action"], .bulk-actions select',
bulkApplyBtn: '.bulk-apply, .apply-bulk-action',
selectAllCheckbox: 'input[type="checkbox"].select-all',
eventCheckboxes: 'input[type="checkbox"].event-select',
// Filters and search
searchInput: 'input[type="search"], .search-events, #event-search',
searchBtn: '.search-btn, .search-submit',
statusFilter: 'select.status-filter, #status-filter',
trainerFilter: 'select.trainer-filter, #trainer-filter',
dateFilter: 'input.date-filter, #date-filter',
venueFilter: 'select.venue-filter, #venue-filter',
clearFiltersBtn: '.clear-filters, .reset-filters',
// Event statistics and overview
eventStats: '.event-stats, .events-statistics',
totalEvents: '.total-events, [data-metric="total"]',
upcomingEvents: '.upcoming-events, [data-metric="upcoming"]',
pastEvents: '.past-events, [data-metric="past"]',
cancelledEvents: '.cancelled-events, [data-metric="cancelled"]',
// Event categories and types
categoryFilter: 'select.category-filter, #category-filter',
eventTypes: '.event-types, .type-filter',
// Pagination
pagination: '.pagination, .page-navigation',
prevPageBtn: '.prev-page, .previous',
nextPageBtn: '.next-page, .next',
pageNumbers: '.page-numbers a',
// Export and reporting
exportBtn: '.export-events, .download-events',
reportingBtn: '.event-reports, .reporting',
// Loading and status indicators
loadingIndicator: '.loading, .spinner',
errorMessage: '.error-message, .notice-error',
successMessage: '.success-message, .notice-success',
emptyState: '.no-events, .events-empty'
};
}
/**
* Wait for events page to be fully loaded
*/
async waitForPageReady() {
await this.waitForElement(this.selectors.pageTitle);
await this.waitForAjaxComplete();
// Wait for events container or empty state
try {
await Promise.race([
this.waitForElement(this.selectors.eventsContainer, 10000),
this.waitForElement(this.selectors.emptyState, 10000)
]);
} catch (error) {
console.warn('Events container or empty state not found, continuing...');
}
}
/**
* Get all events from the current page
*/
async getEventsList() {
const events = [];
const eventRows = await this.page.$$(this.selectors.eventRows);
for (const row of eventRows) {
const event = {
title: await this.getTextFromElement(row, this.selectors.eventTitle),
date: await this.getTextFromElement(row, this.selectors.eventDate),
status: await this.getTextFromElement(row, this.selectors.eventStatus),
trainer: await this.getTextFromElement(row, this.selectors.eventTrainer),
venue: await this.getTextFromElement(row, this.selectors.eventVenue)
};
events.push(event);
}
return events;
}
/**
* Get event statistics from the page
*/
async getEventStatistics() {
const stats = {};
try {
if (await this.hasElement(this.selectors.totalEvents)) {
const totalText = await this.getElementText(this.selectors.totalEvents);
stats.total = this.extractNumber(totalText);
}
if (await this.hasElement(this.selectors.upcomingEvents)) {
const upcomingText = await this.getElementText(this.selectors.upcomingEvents);
stats.upcoming = this.extractNumber(upcomingText);
}
if (await this.hasElement(this.selectors.pastEvents)) {
const pastText = await this.getElementText(this.selectors.pastEvents);
stats.past = this.extractNumber(pastText);
}
if (await this.hasElement(this.selectors.cancelledEvents)) {
const cancelledText = await this.getElementText(this.selectors.cancelledEvents);
stats.cancelled = this.extractNumber(cancelledText);
}
} catch (error) {
console.warn('Failed to get event statistics:', error.message);
}
return stats;
}
/**
* Search for events by term
*/
async searchEvents(searchTerm) {
if (await this.hasElement(this.selectors.searchInput)) {
await this.fillField(this.selectors.searchInput, searchTerm);
if (await this.hasElement(this.selectors.searchBtn)) {
await this.clickElement(this.selectors.searchBtn);
} else {
// Submit by pressing Enter
await this.page.keyboard.press('Enter');
}
await this.waitForAjaxComplete();
await this.waitForPageReady();
}
}
/**
* Filter events by status
*/
async filterByStatus(status) {
if (await this.hasElement(this.selectors.statusFilter)) {
await this.selectOption(this.selectors.statusFilter, status);
await this.waitForAjaxComplete();
await this.waitForPageReady();
}
}
/**
* Filter events by trainer
*/
async filterByTrainer(trainerId) {
if (await this.hasElement(this.selectors.trainerFilter)) {
await this.selectOption(this.selectors.trainerFilter, trainerId);
await this.waitForAjaxComplete();
await this.waitForPageReady();
}
}
/**
* Clear all filters
*/
async clearAllFilters() {
if (await this.hasElement(this.selectors.clearFiltersBtn)) {
await this.clickElement(this.selectors.clearFiltersBtn);
await this.waitForAjaxComplete();
await this.waitForPageReady();
}
}
/**
* Navigate to create event page
*/
async createNewEvent() {
if (await this.hasElement(this.selectors.createEventBtn)) {
await this.clickElement(this.selectors.createEventBtn);
await this.waitForPageLoad();
return true;
}
return false;
}
/**
* Edit an event by index or title
*/
async editEvent(identifier) {
const eventRows = await this.page.$$(this.selectors.eventRows);
if (typeof identifier === 'number' && eventRows[identifier]) {
// Edit by index
const editBtn = await eventRows[identifier].$(this.selectors.editEventBtn);
if (editBtn) {
await editBtn.click();
await this.waitForPageLoad();
return true;
}
} else if (typeof identifier === 'string') {
// Edit by event title
for (const row of eventRows) {
const titleElement = await row.$(this.selectors.eventTitle);
if (titleElement) {
const title = await titleElement.textContent();
if (title.trim().includes(identifier)) {
const editBtn = await row.$(this.selectors.editEventBtn);
if (editBtn) {
await editBtn.click();
await this.waitForPageLoad();
return true;
}
}
}
}
}
return false;
}
/**
* Perform bulk actions on selected events
*/
async performBulkAction(action, eventIndices = []) {
// Select events by index
const eventRows = await this.page.$$(this.selectors.eventRows);
for (const index of eventIndices) {
if (eventRows[index]) {
const checkbox = await eventRows[index].$(this.selectors.eventCheckboxes);
if (checkbox) {
await checkbox.click();
}
}
}
// Select bulk action
if (await this.hasElement(this.selectors.bulkActionsSelect)) {
await this.selectOption(this.selectors.bulkActionsSelect, action);
if (await this.hasElement(this.selectors.bulkApplyBtn)) {
await this.clickElement(this.selectors.bulkApplyBtn);
await this.waitForAjaxComplete();
await this.waitForPageReady();
return true;
}
}
return false;
}
/**
* Select all events on current page
*/
async selectAllEvents() {
if (await this.hasElement(this.selectors.selectAllCheckbox)) {
await this.clickElement(this.selectors.selectAllCheckbox);
return true;
}
return false;
}
/**
* Export events data
*/
async exportEvents() {
if (await this.hasElement(this.selectors.exportBtn)) {
await this.clickElement(this.selectors.exportBtn);
// Wait for download to start
await this.page.waitForTimeout(2000);
return true;
}
return false;
}
/**
* Check if events page has any events
*/
async hasEvents() {
return await this.hasElement(this.selectors.eventRows);
}
/**
* Check if page is showing empty state
*/
async isEmptyState() {
return await this.isElementVisible(this.selectors.emptyState);
}
/**
* Get available event management features
*/
async getAvailableFeatures() {
return {
canCreate: await this.hasElement(this.selectors.createEventBtn),
canSearch: await this.hasElement(this.selectors.searchInput),
canFilter: await this.hasElement(this.selectors.statusFilter),
canBulkAction: await this.hasElement(this.selectors.bulkActionsSelect),
canExport: await this.hasElement(this.selectors.exportBtn),
hasStatistics: await this.hasElement(this.selectors.eventStats)
};
}
/**
* Helper method to get text from child element
*/
async getTextFromElement(parentElement, selector) {
try {
const element = await parentElement.$(selector);
return element ? await element.textContent() : '';
} catch (error) {
return '';
}
}
/**
* Extract number from text string
*/
extractNumber(text) {
const match = text.match(/\d+/);
return match ? parseInt(match[0], 10) : 0;
}
}
module.exports = MasterTrainerEvents;