diff --git a/wordpress-dev/tests/e2e/help-system-documentation.test.ts b/wordpress-dev/tests/e2e/help-system-documentation.test.ts new file mode 100644 index 00000000..c5fc6120 --- /dev/null +++ b/wordpress-dev/tests/e2e/help-system-documentation.test.ts @@ -0,0 +1,344 @@ +/** + * Help System - Documentation Page E2E Tests + * + * Tests the documentation page functionality including: + * - Page content and structure + * - Navigation menu functionality + * - FAQ section + * - Links and buttons + */ + +import { test, expect } from '@playwright/test'; +import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config'; + +test.describe('Help System - Documentation Page @help @documentation', () => { + + test.beforeEach(async ({ page }) => { + // Login as trainer before each test + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + }); + + test('Documentation page loads and displays correctly', async ({ page }) => { + console.log('Testing documentation page loading...'); + + // Navigate to documentation page + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Check page title + await expect(page.locator('h1')).toContainText('Trainer Documentation'); + + // Check subtitle + await expect(page.locator('.hvac-doc-subtitle')).toContainText('Everything you need to know about managing your training events'); + + // Check main container + await expect(page.locator('.hvac-documentation')).toBeVisible(); + + console.log('✓ Documentation page loads correctly'); + await page.screenshot({ path: 'test-results/screenshots/documentation-page.png' }); + }); + + test('Documentation navigation menu works', async ({ page }) => { + console.log('Testing documentation navigation menu...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Check navigation menu exists + await expect(page.locator('.hvac-doc-navigation')).toBeVisible(); + + // Test navigation links + const navLinks = [ + { text: 'Getting Started', target: '#getting-started' }, + { text: 'Managing Events', target: '#managing-events' }, + { text: 'Attendee Management', target: '#attendee-management' }, + { text: 'Certificates', target: '#certificates' }, + { text: 'FAQ', target: '#faq' } + ]; + + for (const link of navLinks) { + const navLink = page.locator('.hvac-doc-link').filter({ hasText: link.text }); + await expect(navLink).toBeVisible(); + await expect(navLink).toHaveAttribute('href', link.target); + } + + console.log('✓ Navigation menu structure is correct'); + }); + + test('Documentation smooth scrolling works', async ({ page }) => { + console.log('Testing documentation smooth scrolling...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Click on FAQ link and verify smooth scroll + const faqLink = page.locator('.hvac-doc-link[href="#faq"]'); + await faqLink.click(); + + // Wait for scroll animation + await page.waitForTimeout(1000); + + // Check that FAQ section is in view + const faqSection = page.locator('#faq'); + await expect(faqSection).toBeInViewport(); + + // Click on Getting Started link + const gettingStartedLink = page.locator('.hvac-doc-link[href="#getting-started"]'); + await gettingStartedLink.click(); + + await page.waitForTimeout(1000); + + // Check that Getting Started section is in view + const gettingStartedSection = page.locator('#getting-started'); + await expect(gettingStartedSection).toBeInViewport(); + + console.log('✓ Smooth scrolling navigation works'); + }); + + test('Getting Started section content is correct', async ({ page }) => { + console.log('Testing Getting Started section content...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Check Getting Started section + const gettingStartedSection = page.locator('#getting-started'); + await expect(gettingStartedSection).toBeVisible(); + + // Check section header + await expect(gettingStartedSection.locator('h2')).toContainText('Getting Started'); + + // Check for the three main cards + const cards = [ + { title: '1. Complete Your Profile', buttonText: 'Edit Profile' }, + { title: '2. Create Your First Event', buttonText: 'Create Event' }, + { title: '3. Monitor Your Dashboard', buttonText: 'View Dashboard' } + ]; + + for (const card of cards) { + const cardElement = gettingStartedSection.locator('.hvac-doc-card').filter({ hasText: card.title }); + await expect(cardElement).toBeVisible(); + await expect(cardElement.locator('h3')).toContainText(card.title); + + // Check action button + const button = cardElement.locator('.hvac-doc-btn'); + await expect(button).toContainText(card.buttonText); + } + + console.log('✓ Getting Started section content is correct'); + }); + + test('Managing Events section content is correct', async ({ page }) => { + console.log('Testing Managing Events section content...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Navigate to Managing Events section + const managingEventsSection = page.locator('#managing-events'); + await expect(managingEventsSection).toBeVisible(); + + // Check section header with icon + await expect(managingEventsSection.locator('h2')).toContainText('Managing Events'); + await expect(managingEventsSection.locator('h2 i')).toHaveClass(/fa-calendar-alt/); + + // Check for key features + const features = [ + 'Event Creation Process', + 'Key Event Features', + 'Event Summary Page' + ]; + + for (const feature of features) { + const featureElement = managingEventsSection.locator('.hvac-feature').filter({ hasText: feature }); + await expect(featureElement).toBeVisible(); + } + + // Check event creation process steps + const processSteps = ['Draft:', 'Review:', 'Published:']; + for (const step of processSteps) { + await expect(managingEventsSection).toContainText(step); + } + + console.log('✓ Managing Events section content is correct'); + }); + + test('FAQ section content is comprehensive', async ({ page }) => { + console.log('Testing FAQ section content...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Navigate to FAQ section + const faqSection = page.locator('#faq'); + await expect(faqSection).toBeVisible(); + + // Check section header with icon + await expect(faqSection.locator('h2')).toContainText('Frequently Asked Questions'); + await expect(faqSection.locator('h2 i')).toHaveClass(/fa-question-circle/); + + // Check for expected FAQ items + const expectedFAQs = [ + 'How do I get paid for my events?', + 'How long does event review take?', + 'Can I modify events after they\'re published?', + 'What if I need to cancel an event?', + 'How do I improve my event visibility?', + 'Can I offer different types of training?', + 'What support is available?' + ]; + + for (const faq of expectedFAQs) { + const faqItem = faqSection.locator('.hvac-faq-item').filter({ hasText: faq }); + await expect(faqItem).toBeVisible(); + await expect(faqItem.locator('h3')).toContainText(faq); + } + + // Check that FAQ answers contain relevant information + await expect(faqSection).toContainText('100%'); // Revenue info + await expect(faqSection).toContainText('Stripe'); // Payment processor + await expect(faqSection).toContainText('1-2 business days'); // Review time + + console.log('✓ FAQ section content is comprehensive'); + await page.screenshot({ path: 'test-results/screenshots/faq-section.png' }); + }); + + test('Documentation action links work correctly', async ({ page }) => { + console.log('Testing documentation action links...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Test Edit Profile link + const editProfileLink = page.locator('.hvac-doc-btn').filter({ hasText: 'Edit Profile' }); + await expect(editProfileLink).toHaveAttribute('href', '/trainer-profile'); + + // Test Create Event link + const createEventLink = page.locator('.hvac-doc-btn').filter({ hasText: 'Create Event' }); + await expect(createEventLink).toHaveAttribute('href', '/manage-event'); + + // Test View Dashboard link + const dashboardLink = page.locator('.hvac-doc-btn').filter({ hasText: 'View Dashboard' }); + await expect(dashboardLink).toHaveAttribute('href', '/hvac-dashboard'); + + console.log('✓ Documentation action links are correct'); + }); + + test('Documentation page is accessible via help buttons', async ({ page }) => { + console.log('Testing documentation page accessibility via help buttons...'); + + // From dashboard + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + const helpButtonDashboard = page.locator('a').filter({ hasText: 'Help' }); + if (await helpButtonDashboard.count() > 0) { + await expect(helpButtonDashboard).toHaveAttribute('href', '/hvac-documentation/'); + console.log('✓ Help button found on dashboard'); + } + + // From profile page + await page.goto(PATHS.profile); + await page.waitForLoadState('networkidle'); + + const helpButtonProfile = page.locator('a').filter({ hasText: 'Help' }); + if (await helpButtonProfile.count() > 0) { + await expect(helpButtonProfile).toHaveAttribute('href', '/hvac-documentation/'); + console.log('✓ Help button found on profile page'); + } + + // Test clicking help button actually navigates to documentation + if (await helpButtonProfile.count() > 0) { + await helpButtonProfile.click(); + await page.waitForLoadState('networkidle'); + + await expect(page).toHaveURL(/hvac-documentation/); + await expect(page.locator('h1')).toContainText('Trainer Documentation'); + console.log('✓ Help button navigation works'); + } + }); + + test('Documentation page responsive design works', async ({ page }) => { + console.log('Testing documentation page responsive design...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Test desktop view + await page.setViewportSize({ width: 1200, height: 800 }); + await expect(page.locator('.hvac-documentation')).toBeVisible(); + + // Test tablet view + await page.setViewportSize({ width: 768, height: 1024 }); + await expect(page.locator('.hvac-documentation')).toBeVisible(); + + // Test mobile view + await page.setViewportSize({ width: 375, height: 667 }); + await expect(page.locator('.hvac-documentation')).toBeVisible(); + + // Check that navigation menu adapts + const navMenu = page.locator('.hvac-doc-nav'); + await expect(navMenu).toBeVisible(); + + console.log('✓ Documentation page responsive design works'); + await page.screenshot({ path: 'test-results/screenshots/documentation-mobile.png' }); + }); + + test('Documentation sections have proper styling', async ({ page }) => { + console.log('Testing documentation styling...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Check that all sections have the correct CSS classes + const sections = ['#getting-started', '#managing-events', '#attendee-management', '#certificates', '#faq']; + + for (const sectionId of sections) { + const section = page.locator(sectionId); + await expect(section).toHaveClass(/hvac-doc-section/); + + // Check section headers have icons + const header = section.locator('h2'); + await expect(header).toBeVisible(); + + const icon = header.locator('i'); + if (await icon.count() > 0) { + await expect(icon).toHaveClass(/fa-/); + } + } + + // Check cards have proper styling + const docCards = page.locator('.hvac-doc-card'); + const cardCount = await docCards.count(); + expect(cardCount).toBeGreaterThan(0); + + console.log(`✓ Found ${cardCount} properly styled documentation cards`); + }); + + test('Documentation content is accurate and helpful', async ({ page }) => { + console.log('Testing documentation content accuracy...'); + + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Check for key platform information + await expect(page.getByText('100% of your ticket sales')).toBeVisible(); + await expect(page.getByText('minus standard Stripe processing fees')).toBeVisible(); + await expect(page.getByText('1-2 business days')).toBeVisible(); // Review process time + + // Check for feature mentions + await expect(page.getByText('certificates')).toBeVisible(); + await expect(page.getByText('check-in')).toBeVisible(); + await expect(page.getByText('email')).toBeVisible(); + + // Check for proper support information + await expect(page.getByText('support team')).toBeVisible(); + await expect(page.getByText('documentation')).toBeVisible(); + + console.log('✓ Documentation content is accurate and helpful'); + }); +}); \ No newline at end of file diff --git a/wordpress-dev/tests/e2e/help-system-integration.test.ts b/wordpress-dev/tests/e2e/help-system-integration.test.ts new file mode 100644 index 00000000..aeda326f --- /dev/null +++ b/wordpress-dev/tests/e2e/help-system-integration.test.ts @@ -0,0 +1,339 @@ +/** + * Help System - Integration E2E Tests + * + * Tests the complete help system integration including: + * - End-to-end user journey through help features + * - Cross-page functionality + * - Cookie persistence + * - Complete help system workflow + */ + +import { test, expect } from '@playwright/test'; +import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config'; + +test.describe('Help System - Integration Tests @help @integration', () => { + + test('Complete help system user journey', async ({ page, context }) => { + console.log('Testing complete help system user journey...'); + + // Clear cookies for fresh experience + await context.clearCookies(); + + // 1. Login and see welcome guide + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Welcome guide should appear + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + console.log('✓ Step 1: Welcome guide appears on first visit'); + + // 2. Navigate through welcome guide + await page.click('#hvac-next-card'); + await page.click('#hvac-next-card'); + await page.click('#hvac-next-card'); + + // Complete the welcome guide + await page.check('#hvac-dont-show-again'); + await page.click('#hvac-get-started'); + + // Modal should disappear + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + console.log('✓ Step 2: Welcome guide navigation and dismissal works'); + + // 3. Test tooltips on dashboard + const createEventTooltip = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Create Event' }); + if (await createEventTooltip.count() > 0) { + await createEventTooltip.hover(); + await page.waitForTimeout(600); + console.log('✓ Step 3: Dashboard tooltips work'); + } + + // 4. Navigate to documentation via help button + const helpButton = page.locator('a').filter({ hasText: 'Help' }); + if (await helpButton.count() > 0) { + await helpButton.click(); + await page.waitForLoadState('networkidle'); + + await expect(page).toHaveURL(/hvac-documentation/); + await expect(page.locator('h1')).toContainText('Trainer Documentation'); + console.log('✓ Step 4: Navigation to documentation works'); + } + + // 5. Test documentation navigation + const faqLink = page.locator('.hvac-doc-link[href="#faq"]'); + await faqLink.click(); + await page.waitForTimeout(1000); + + const faqSection = page.locator('#faq'); + await expect(faqSection).toBeInViewport(); + console.log('✓ Step 5: Documentation navigation works'); + + // 6. Return to dashboard and verify welcome guide doesn't show + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + console.log('✓ Step 6: Welcome guide stays dismissed'); + + // 7. Visit profile page and check help button + await page.goto(PATHS.profile); + await page.waitForLoadState('networkidle'); + + const profileHelpButton = page.locator('a').filter({ hasText: 'Help' }); + await expect(profileHelpButton).toBeVisible(); + console.log('✓ Step 7: Help button available on profile page'); + + await page.screenshot({ path: 'test-results/screenshots/help-system-integration.png' }); + console.log('✓ Complete help system user journey successful'); + }); + + test('Help system works across multiple sessions', async ({ page, context }) => { + console.log('Testing help system persistence across sessions...'); + + // Session 1: Dismiss welcome guide + await context.clearCookies(); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Dismiss permanently + await page.check('#hvac-dont-show-again'); + await page.click('#hvac-get-started'); + + console.log('✓ Session 1: Welcome guide dismissed'); + + // Session 2: Create new page context (simulates new session) + const newContext = await page.context().browser()?.newContext(); + if (newContext) { + const newPage = await newContext.newPage(); + + // Copy cookies from original context + const cookies = await context.cookies(); + await newContext.addCookies(cookies); + + await newPage.goto(PATHS.login); + await newPage.fill('#user_login', 'test_trainer'); + await newPage.fill('#user_pass', 'Test123!'); + await newPage.click('#wp-submit'); + await newPage.waitForLoadState('networkidle'); + + await newPage.goto(PATHS.dashboard); + await newPage.waitForLoadState('networkidle'); + + // Welcome guide should NOT appear + await expect(newPage.locator('#hvac-welcome-modal')).not.toBeVisible(); + console.log('✓ Session 2: Welcome guide stays dismissed'); + + await newContext.close(); + } + }); + + test('Help system accessibility features work', async ({ page }) => { + console.log('Testing help system accessibility...'); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Test keyboard navigation if welcome guide appears + const welcomeModal = page.locator('#hvac-welcome-modal'); + if (await welcomeModal.isVisible()) { + // Test tab navigation + await page.keyboard.press('Tab'); + + // Test arrow key navigation + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowLeft'); + + // Test escape key + await page.keyboard.press('Escape'); + await expect(welcomeModal).not.toBeVisible(); + + console.log('✓ Welcome guide keyboard accessibility works'); + } + + // Test tooltip accessibility + const tooltipElements = page.locator('.hvac-tooltip-wrapper'); + const count = await tooltipElements.count(); + + if (count > 0) { + // Check first tooltip has proper attributes + await expect(tooltipElements.first()).toHaveAttribute('data-tooltip'); + console.log('✓ Tooltip accessibility attributes present'); + } + }); + + test('Help system performance and loading', async ({ page }) => { + console.log('Testing help system performance...'); + + // Measure page load time with help system + const startTime = Date.now(); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + const loadTime = Date.now() - startTime; + console.log(`Page load time with help system: ${loadTime}ms`); + + // Check that help system assets are loaded + const helpCSS = await page.locator('link[href*="hvac-help-system.css"]').count(); + const helpJS = await page.locator('script[src*="hvac-help-system.js"]').count(); + const fontAwesome = await page.locator('link[href*="font-awesome"]').count(); + + expect(helpCSS).toBeGreaterThan(0); + expect(helpJS).toBeGreaterThan(0); + expect(fontAwesome).toBeGreaterThan(0); + + console.log('✓ All help system assets loaded correctly'); + + // Test JavaScript functionality + const hvacHelpAvailable = await page.evaluate(() => { + return typeof window.HVACHelp !== 'undefined'; + }); + + expect(hvacHelpAvailable).toBe(true); + console.log('✓ Help system JavaScript initialized'); + }); + + test('Help system error handling', async ({ page }) => { + console.log('Testing help system error handling...'); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + // Test accessing documentation page directly + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + // Should load successfully for authenticated users + await expect(page.locator('h1')).toContainText('Trainer Documentation'); + console.log('✓ Documentation page loads for authenticated users'); + + // Test help system with disabled JavaScript + await page.context().addInitScript(() => { + // Simulate JS error scenario + window.addEventListener('error', (e) => { + console.log('JavaScript error handled:', e.message); + }); + }); + + await page.reload(); + await page.waitForLoadState('networkidle'); + + // Page should still be functional even if JS fails + await expect(page.locator('h1')).toContainText('Trainer Documentation'); + console.log('✓ Help system gracefully handles JS errors'); + }); + + test('Help system AJAX functionality', async ({ page }) => { + console.log('Testing help system AJAX functionality...'); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Monitor network requests + const requests: any[] = []; + page.on('request', request => { + if (request.url().includes('admin-ajax.php')) { + requests.push(request); + } + }); + + // If welcome guide appears, test AJAX dismissal + const welcomeModal = page.locator('#hvac-welcome-modal'); + if (await welcomeModal.isVisible()) { + await page.check('#hvac-dont-show-again'); + await page.click('#hvac-get-started'); + + // Wait for AJAX request + await page.waitForTimeout(2000); + + // Check if AJAX request was made + const ajaxRequests = requests.filter(req => + req.postData() && req.postData().includes('hvac_dismiss_welcome') + ); + + if (ajaxRequests.length > 0) { + console.log('✓ AJAX dismissal request sent'); + } + } + + console.log('✓ Help system AJAX functionality tested'); + }); + + test('Help system mobile responsiveness', async ({ page }) => { + console.log('Testing help system mobile responsiveness...'); + + // Set mobile viewport + await page.setViewportSize({ width: 375, height: 667 }); + + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Test welcome guide on mobile + const welcomeModal = page.locator('#hvac-welcome-modal'); + if (await welcomeModal.isVisible()) { + // Check modal is properly sized for mobile + await expect(welcomeModal).toBeVisible(); + + // Test navigation on mobile + await page.click('#hvac-next-card'); + await page.click('#hvac-get-started'); + + console.log('✓ Welcome guide works on mobile'); + } + + // Test documentation page on mobile + await page.goto(`${STAGING_URL}/hvac-documentation/`); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('.hvac-documentation')).toBeVisible(); + + // Test navigation menu on mobile + const navMenu = page.locator('.hvac-doc-nav'); + await expect(navMenu).toBeVisible(); + + console.log('✓ Documentation page works on mobile'); + await page.screenshot({ path: 'test-results/screenshots/help-system-mobile.png' }); + }); +}); \ No newline at end of file diff --git a/wordpress-dev/tests/e2e/help-system-tooltips.test.ts b/wordpress-dev/tests/e2e/help-system-tooltips.test.ts new file mode 100644 index 00000000..c1ad022c --- /dev/null +++ b/wordpress-dev/tests/e2e/help-system-tooltips.test.ts @@ -0,0 +1,292 @@ +/** + * Help System - Tooltips E2E Tests + * + * Tests the tooltip system functionality including: + * - Tooltip appearance on hover + * - Tooltip positioning + * - Tooltip content accuracy + * - Cross-page functionality + */ + +import { test, expect } from '@playwright/test'; +import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config'; + +test.describe('Help System - Tooltips @help @tooltips', () => { + + test.beforeEach(async ({ page }) => { + // Login as trainer before each test + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + }); + + test('Dashboard navigation tooltips appear on hover', async ({ page }) => { + console.log('Testing dashboard navigation tooltips...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Test Create Event button tooltip + const createEventButton = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Create Event' }); + await expect(createEventButton).toBeVisible(); + + // Hover over button + await createEventButton.hover(); + + // Wait for tooltip to appear (there's a delay) + await page.waitForTimeout(600); // Tooltip has 500ms delay + + // Check tooltip content + await expect(createEventButton).toHaveAttribute('data-tooltip', 'Create a new training event with custom pricing and registration options'); + + console.log('✓ Create Event tooltip works'); + + // Test My Events button tooltip + const myEventsButton = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'My Events' }); + await myEventsButton.hover(); + await page.waitForTimeout(600); + + await expect(myEventsButton).toHaveAttribute('data-tooltip', 'View and manage all your existing events in one place'); + + console.log('✓ My Events tooltip works'); + + // Test Generate Certificates button tooltip + const certificatesButton = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Generate Certificates' }); + await certificatesButton.hover(); + await page.waitForTimeout(600); + + await expect(certificatesButton).toHaveAttribute('data-tooltip', 'Create professional certificates for attendees who completed your training'); + + console.log('✓ Generate Certificates tooltip works'); + + await page.screenshot({ path: 'test-results/screenshots/dashboard-tooltips.png' }); + }); + + test('Dashboard statistics tooltips work correctly', async ({ page }) => { + console.log('Testing dashboard statistics tooltips...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Test "Your Stats" section tooltip + const statsHeader = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Your Stats' }); + if (await statsHeader.count() > 0) { + await statsHeader.hover(); + await page.waitForTimeout(600); + + await expect(statsHeader).toHaveAttribute('data-tooltip', 'Overview of your event performance and revenue metrics'); + console.log('✓ Stats header tooltip works'); + } + + // Test individual stat card tooltips + const statCards = [ + { text: 'Total Events', expectedTooltip: 'All events you\'ve created, including drafts and published events' }, + { text: 'Upcoming Events', expectedTooltip: 'Published events scheduled for future dates' }, + { text: 'Past Events', expectedTooltip: 'Completed events where you can generate certificates' }, + { text: 'Tickets Sold', expectedTooltip: 'Total number of tickets sold across all your events' }, + { text: 'Total Revenue', expectedTooltip: 'Total earnings from all ticket sales (before Stripe fees)' } + ]; + + for (const card of statCards) { + const statElement = page.locator('.hvac-tooltip-wrapper').filter({ hasText: card.text }); + if (await statElement.count() > 0) { + await statElement.hover(); + await page.waitForTimeout(600); + + await expect(statElement).toHaveAttribute('data-tooltip', card.expectedTooltip); + console.log(`✓ ${card.text} tooltip works`); + } + } + + await page.screenshot({ path: 'test-results/screenshots/statistics-tooltips.png' }); + }); + + test('Events table section tooltips work', async ({ page }) => { + console.log('Testing events table tooltips...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Test "Your Events" header tooltip + const eventsHeader = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Your Events' }); + if (await eventsHeader.count() > 0) { + await eventsHeader.hover(); + await page.waitForTimeout(600); + + await expect(eventsHeader).toHaveAttribute('data-tooltip', 'Detailed view of all your events with performance metrics and management options'); + console.log('✓ Events header tooltip works'); + } + + // Test filter tooltip + const filterElement = page.locator('.hvac-tooltip-wrapper').filter({ hasText: 'Filter:' }); + if (await filterElement.count() > 0) { + await filterElement.hover(); + await page.waitForTimeout(600); + + await expect(filterElement).toHaveAttribute('data-tooltip', 'Filter events by their publication status'); + console.log('✓ Filter tooltip works'); + } + + await page.screenshot({ path: 'test-results/screenshots/events-table-tooltips.png' }); + }); + + test('Tooltip positioning works correctly', async ({ page }) => { + console.log('Testing tooltip positioning...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Find tooltips with different position attributes + const topTooltip = page.locator('.hvac-tooltip-wrapper[data-position="top"]').first(); + const bottomTooltip = page.locator('.hvac-tooltip-wrapper[data-position="bottom"]').first(); + + if (await topTooltip.count() > 0) { + await expect(topTooltip).toHaveAttribute('data-position', 'top'); + console.log('✓ Top positioned tooltip found'); + } + + if (await bottomTooltip.count() > 0) { + await expect(bottomTooltip).toHaveAttribute('data-position', 'bottom'); + console.log('✓ Bottom positioned tooltip found'); + } + + // Test default positioning (should default to top if not specified) + const defaultTooltip = page.locator('.hvac-tooltip-wrapper').not('[data-position]').first(); + if (await defaultTooltip.count() > 0) { + console.log('✓ Default positioned tooltip found'); + } + }); + + test('Tooltips work on trainer profile page', async ({ page }) => { + console.log('Testing tooltips on trainer profile page...'); + + await page.goto(PATHS.profile); + await page.waitForLoadState('networkidle'); + + // Check if help button is present with tooltip + const helpButton = page.locator('a').filter({ hasText: 'Help' }); + await expect(helpButton).toBeVisible(); + + // Test any tooltips that might be on the profile page + const tooltipElements = page.locator('.hvac-tooltip-wrapper'); + const tooltipCount = await tooltipElements.count(); + + if (tooltipCount > 0) { + console.log(`Found ${tooltipCount} tooltip elements on profile page`); + + // Test the first tooltip + await tooltipElements.first().hover(); + await page.waitForTimeout(600); + + // Verify it has a data-tooltip attribute + await expect(tooltipElements.first()).toHaveAttribute('data-tooltip'); + } + + console.log('✓ Profile page tooltips checked'); + await page.screenshot({ path: 'test-results/screenshots/profile-tooltips.png' }); + }); + + test('Tooltip CSS classes are applied correctly', async ({ page }) => { + console.log('Testing tooltip CSS classes...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Check if tooltip wrapper elements have the correct classes + const tooltipWrappers = page.locator('.hvac-tooltip-wrapper'); + const count = await tooltipWrappers.count(); + + expect(count).toBeGreaterThan(0); + console.log(`Found ${count} tooltip wrapper elements`); + + // Check that each wrapper has the required attributes + for (let i = 0; i < Math.min(count, 5); i++) { // Test first 5 tooltips + const wrapper = tooltipWrappers.nth(i); + + // Should have hvac-tooltip-wrapper class + await expect(wrapper).toHaveClass(/hvac-tooltip-wrapper/); + + // Should have data-tooltip attribute + await expect(wrapper).toHaveAttribute('data-tooltip'); + + console.log(`✓ Tooltip ${i + 1} has correct attributes`); + } + }); + + test('Tooltips disappear when not hovering', async ({ page }) => { + console.log('Testing tooltip hover behavior...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + const tooltipElement = page.locator('.hvac-tooltip-wrapper').first(); + + // Hover over element + await tooltipElement.hover(); + await page.waitForTimeout(600); + + // Move mouse away + await page.mouse.move(0, 0); + await page.waitForTimeout(200); + + // Tooltip should not be visible (this is handled by CSS) + // We can verify the hover state is removed by checking computed styles + console.log('✓ Tooltip hover behavior tested'); + }); + + test('Help system CSS and JS are loaded', async ({ page }) => { + console.log('Testing help system assets loading...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Check if help system CSS is loaded + const helpSystemCSS = await page.locator('link[href*="hvac-help-system.css"]').count(); + expect(helpSystemCSS).toBeGreaterThan(0); + console.log('✓ Help system CSS is loaded'); + + // Check if help system JS is loaded + const helpSystemJS = await page.locator('script[src*="hvac-help-system.js"]').count(); + expect(helpSystemJS).toBeGreaterThan(0); + console.log('✓ Help system JS is loaded'); + + // Check if Font Awesome is loaded for icons + const fontAwesome = await page.locator('link[href*="font-awesome"]').count(); + expect(fontAwesome).toBeGreaterThan(0); + console.log('✓ Font Awesome is loaded'); + }); + + test('Tooltip functionality works with JavaScript', async ({ page }) => { + console.log('Testing tooltip JavaScript functionality...'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Check if the HVACHelp object is available in the global scope + const hvacHelpExists = await page.evaluate(() => { + return typeof window.HVACHelp !== 'undefined'; + }); + + expect(hvacHelpExists).toBe(true); + console.log('✓ HVACHelp JavaScript object is available'); + + // Test the addTooltip function + const tooltipAdded = await page.evaluate(() => { + const testElement = document.createElement('span'); + testElement.id = 'test-tooltip-element'; + testElement.textContent = 'Test Element'; + document.body.appendChild(testElement); + + window.HVACHelp.addTooltip('#test-tooltip-element', 'Test tooltip text', 'top'); + + const element = document.getElementById('test-tooltip-element'); + return element.classList.contains('hvac-tooltip-wrapper') && + element.getAttribute('data-tooltip') === 'Test tooltip text'; + }); + + expect(tooltipAdded).toBe(true); + console.log('✓ JavaScript addTooltip function works'); + }); +}); \ No newline at end of file diff --git a/wordpress-dev/tests/e2e/help-system-welcome-guide.test.ts b/wordpress-dev/tests/e2e/help-system-welcome-guide.test.ts new file mode 100644 index 00000000..51d1ddcd --- /dev/null +++ b/wordpress-dev/tests/e2e/help-system-welcome-guide.test.ts @@ -0,0 +1,341 @@ +/** + * Help System - Welcome Guide E2E Tests + * + * Tests the interactive welcome guide modal functionality including: + * - Modal appearance on first login + * - Navigation between cards + * - Cookie-based dismissal + * - Accessibility features + */ + +import { test, expect } from '@playwright/test'; +import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config'; + +test.describe('Help System - Welcome Guide @help @welcome-guide', () => { + + test.beforeEach(async ({ page, context }) => { + // Clear cookies to ensure fresh state for welcome guide + await context.clearCookies(); + }); + + test('Welcome guide appears on first dashboard visit', async ({ page }) => { + console.log('Testing welcome guide appearance on first visit...'); + + // Login as trainer + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + // Navigate to dashboard + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Wait for welcome modal to appear + const welcomeModal = page.locator('#hvac-welcome-modal'); + await expect(welcomeModal).toBeVisible({ timeout: TIMEOUTS.standard }); + + // Verify modal header + await expect(page.locator('.hvac-modal-header h2')).toContainText('Welcome to Upskill HVAC Training Network!'); + + // Verify first card is active + const firstCard = page.locator('.hvac-welcome-card[data-card="0"]'); + await expect(firstCard).toHaveClass(/active/); + + // Verify first card content + await expect(firstCard.locator('h3')).toContainText('Verified Expert Platform'); + await expect(firstCard.locator('p')).toContainText('vetted community'); + + console.log('✓ Welcome guide appears correctly on first visit'); + await page.screenshot({ path: 'test-results/screenshots/welcome-guide-first-card.png' }); + }); + + test('Welcome guide navigation works correctly', async ({ page, context }) => { + console.log('Testing welcome guide navigation...'); + + // Clear cookies and login + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Wait for modal + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Test Next button navigation + const nextButton = page.locator('#hvac-next-card'); + await nextButton.click(); + + // Verify second card is active + const secondCard = page.locator('.hvac-welcome-card[data-card="1"]'); + await expect(secondCard).toHaveClass(/active/); + await expect(secondCard.locator('h3')).toContainText('Create & Manage Events'); + + // Test indicator navigation + const thirdIndicator = page.locator('.hvac-indicator[data-card="2"]'); + await thirdIndicator.click(); + + // Verify third card is active + const thirdCard = page.locator('.hvac-welcome-card[data-card="2"]'); + await expect(thirdCard).toHaveClass(/active/); + await expect(thirdCard.locator('h3')).toContainText('Keep 100% Revenue'); + + // Test Previous button + const prevButton = page.locator('#hvac-prev-card'); + await prevButton.click(); + + // Verify second card is active again + await expect(secondCard).toHaveClass(/active/); + + // Navigate to last card + const fourthIndicator = page.locator('.hvac-indicator[data-card="3"]'); + await fourthIndicator.click(); + + // Verify fourth card content + const fourthCard = page.locator('.hvac-welcome-card[data-card="3"]'); + await expect(fourthCard).toHaveClass(/active/); + await expect(fourthCard.locator('h3')).toContainText('Professional Certificates'); + + // Verify Next button becomes "Finish" on last card + await expect(nextButton).toContainText('Finish'); + + console.log('✓ Welcome guide navigation works correctly'); + await page.screenshot({ path: 'test-results/screenshots/welcome-guide-navigation.png' }); + }); + + test('Welcome guide keyboard navigation works', async ({ page, context }) => { + console.log('Testing welcome guide keyboard navigation...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Test right arrow key + await page.keyboard.press('ArrowRight'); + const secondCard = page.locator('.hvac-welcome-card[data-card="1"]'); + await expect(secondCard).toHaveClass(/active/); + + // Test left arrow key + await page.keyboard.press('ArrowLeft'); + const firstCard = page.locator('.hvac-welcome-card[data-card="0"]'); + await expect(firstCard).toHaveClass(/active/); + + console.log('✓ Keyboard navigation works correctly'); + }); + + test('Welcome guide dismissal with "Don\'t show again" works', async ({ page, context }) => { + console.log('Testing welcome guide permanent dismissal...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Check "Don't show again" checkbox + await page.check('#hvac-dont-show-again'); + + // Click "Get Started" button + await page.click('#hvac-get-started'); + + // Modal should disappear + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + + // Refresh page to test cookie persistence + await page.reload(); + await page.waitForLoadState('networkidle'); + + // Modal should not appear again + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + + console.log('✓ Welcome guide dismissal with cookie works correctly'); + }); + + test('Welcome guide close button works', async ({ page, context }) => { + console.log('Testing welcome guide close button...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Click close button + await page.click('.hvac-modal-close'); + + // Modal should disappear + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + + // Refresh page - modal should appear again (not permanently dismissed) + await page.reload(); + await page.waitForLoadState('networkidle'); + + // Modal should appear again since we didn't check "don't show again" + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + console.log('✓ Welcome guide close button works correctly'); + }); + + test('Welcome guide ESC key closes modal', async ({ page, context }) => { + console.log('Testing welcome guide ESC key functionality...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Press ESC key + await page.keyboard.press('Escape'); + + // Modal should disappear + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + + console.log('✓ ESC key closes welcome guide correctly'); + }); + + test('Welcome guide only appears on dashboard page', async ({ page, context }) => { + console.log('Testing welcome guide page-specific behavior...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + // Visit profile page first + await page.goto(PATHS.profile); + await page.waitForLoadState('networkidle'); + + // Modal should not appear on profile page + await expect(page.locator('#hvac-welcome-modal')).not.toBeVisible(); + + // Now visit dashboard + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + // Modal should appear on dashboard + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + console.log('✓ Welcome guide appears only on dashboard page'); + }); + + test('Welcome guide has proper accessibility attributes', async ({ page, context }) => { + console.log('Testing welcome guide accessibility...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Check close button has aria-label + await expect(page.locator('.hvac-modal-close')).toHaveAttribute('aria-label', 'Close welcome guide'); + + // Check navigation buttons are properly labeled + await expect(page.locator('#hvac-prev-card')).toContainText('Previous'); + await expect(page.locator('#hvac-next-card')).toContainText('Next'); + + // Test focus management + await page.keyboard.press('Tab'); + const focusedElement = await page.locator(':focus').first(); + + console.log('✓ Welcome guide has proper accessibility features'); + }); + + test('Welcome guide cards contain expected content', async ({ page, context }) => { + console.log('Testing welcome guide content accuracy...'); + + await context.clearCookies(); + await page.goto(PATHS.login); + await page.fill('#user_login', 'test_trainer'); + await page.fill('#user_pass', 'Test123!'); + await page.click('#wp-submit'); + await page.waitForLoadState('networkidle'); + + await page.goto(PATHS.dashboard); + await page.waitForLoadState('networkidle'); + + await expect(page.locator('#hvac-welcome-modal')).toBeVisible(); + + // Test all four cards + const expectedCards = [ + { + title: 'Verified Expert Platform', + keywords: ['vetted', 'community', 'screening'] + }, + { + title: 'Create & Manage Events', + keywords: ['create', 'events', 'pricing', 'reviewed'] + }, + { + title: 'Keep 100% Revenue', + keywords: ['100%', 'ticket', 'sales', 'Stripe'] + }, + { + title: 'Professional Certificates', + keywords: ['certificates', 'completion', 'professional'] + } + ]; + + for (let i = 0; i < expectedCards.length; i++) { + // Navigate to card + const indicator = page.locator(`.hvac-indicator[data-card="${i}"]`); + await indicator.click(); + + const card = page.locator(`.hvac-welcome-card[data-card="${i}"]`); + await expect(card).toHaveClass(/active/); + + // Check title + await expect(card.locator('h3')).toContainText(expectedCards[i].title); + + // Check that description contains expected keywords + const description = card.locator('p'); + for (const keyword of expectedCards[i].keywords) { + await expect(description).toContainText(keyword); + } + } + + console.log('✓ All welcome guide cards contain expected content'); + await page.screenshot({ path: 'test-results/screenshots/welcome-guide-content-check.png' }); + }); +}); \ No newline at end of file