- Add interactive modal popup for announcement 'Read More' functionality - Fix nonce conflict by creating separate hvac_announcements_ajax object - Implement secure AJAX handler with rate limiting and permission checks - Add comprehensive modal CSS with smooth animations and responsive design - Include accessibility features (ARIA, keyboard navigation, screen reader support) - Create detailed documentation in docs/ANNOUNCEMENT-MODAL-SYSTEM.md - Update API-REFERENCE.md with new modal endpoints and security details - Add automated Playwright E2E testing for modal functionality - All modal interactions working: click to open, X to close, ESC to close, outside click - Production-ready with full error handling and content sanitization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			136 lines
		
	
	
		
			No EOL
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			No EOL
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * Test announcement modal functionality
 | |
|  */
 | |
| 
 | |
| const { chromium } = require('playwright');
 | |
| 
 | |
| async function testAnnouncementModal() {
 | |
|     console.log('🎭 Starting announcement modal test...');
 | |
|     
 | |
|     const browser = await chromium.launch({
 | |
|         headless: false,
 | |
|         slowMo: 1000
 | |
|     });
 | |
|     
 | |
|     try {
 | |
|         const context = await browser.newContext({
 | |
|             viewport: { width: 1200, height: 800 }
 | |
|         });
 | |
|         
 | |
|         const page = await context.newPage();
 | |
|         
 | |
|         // Navigate to staging login
 | |
|         console.log('📋 Step 1: Navigating to staging login...');
 | |
|         await page.goto('https://upskill-staging.measurequick.com/training-login/');
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Login as test trainer
 | |
|         console.log('🔐 Step 2: Logging in as test trainer...');
 | |
|         await page.fill('#username', 'test_trainer');
 | |
|         await page.fill('#password', 'TestTrainer123!');
 | |
|         await page.click('input[type="submit"]');
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Navigate to resources page
 | |
|         console.log('📚 Step 3: Navigating to resources page...');
 | |
|         await page.goto('https://upskill-staging.measurequick.com/trainer/resources/');
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Take screenshot of resources page
 | |
|         console.log('📸 Step 4: Taking screenshot of resources page...');
 | |
|         await page.screenshot({ path: 'resources-page-before-modal.png', fullPage: true });
 | |
|         
 | |
|         // Look for announcement and Read More button
 | |
|         console.log('🔍 Step 5: Looking for Read More button...');
 | |
|         const readMoreButton = await page.locator('.read-more-btn').first();
 | |
|         
 | |
|         if (await readMoreButton.count() === 0) {
 | |
|             console.log('❌ No Read More buttons found on page');
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         console.log('✅ Found Read More button');
 | |
|         
 | |
|         // Click Read More button
 | |
|         console.log('👆 Step 6: Clicking Read More button...');
 | |
|         await readMoreButton.click();
 | |
|         
 | |
|         // Wait for modal to appear
 | |
|         console.log('⏳ Step 7: Waiting for modal to appear...');
 | |
|         await page.waitForSelector('#announcement-modal.active', { timeout: 5000 });
 | |
|         
 | |
|         // Check if modal is visible
 | |
|         const modal = page.locator('#announcement-modal');
 | |
|         const isVisible = await modal.isVisible();
 | |
|         
 | |
|         if (!isVisible) {
 | |
|             console.log('❌ Modal is not visible after clicking Read More');
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         console.log('✅ Modal appeared successfully');
 | |
|         
 | |
|         // Take screenshot with modal open
 | |
|         console.log('📸 Step 8: Taking screenshot with modal open...');
 | |
|         await page.screenshot({ path: 'resources-page-with-modal.png', fullPage: true });
 | |
|         
 | |
|         // Check modal content
 | |
|         console.log('📝 Step 9: Checking modal content...');
 | |
|         const modalTitle = await page.locator('.modal-title').textContent();
 | |
|         const modalContent = await page.locator('.modal-content-text').textContent();
 | |
|         
 | |
|         console.log('Modal Title:', modalTitle);
 | |
|         console.log('Modal Content Preview:', modalContent.substring(0, 100) + '...');
 | |
|         
 | |
|         // Test modal close button
 | |
|         console.log('❌ Step 10: Testing modal close button...');
 | |
|         await page.click('.modal-close');
 | |
|         
 | |
|         // Wait for modal to disappear
 | |
|         await page.waitForTimeout(500);
 | |
|         const isModalHidden = await page.locator('#announcement-modal').isHidden();
 | |
|         
 | |
|         if (!isModalHidden) {
 | |
|             console.log('❌ Modal did not close with close button');
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         console.log('✅ Modal closed successfully with close button');
 | |
|         
 | |
|         // Test opening modal again and closing with ESC key
 | |
|         console.log('⌨️  Step 11: Testing ESC key close...');
 | |
|         await readMoreButton.click();
 | |
|         await page.waitForSelector('#announcement-modal.active');
 | |
|         await page.keyboard.press('Escape');
 | |
|         await page.waitForTimeout(500);
 | |
|         
 | |
|         const isModalHiddenAfterEsc = await page.locator('#announcement-modal').isHidden();
 | |
|         
 | |
|         if (!isModalHiddenAfterEsc) {
 | |
|             console.log('❌ Modal did not close with ESC key');
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         console.log('✅ Modal closed successfully with ESC key');
 | |
|         
 | |
|         console.log('🎉 All modal tests passed!');
 | |
|         return true;
 | |
|         
 | |
|     } catch (error) {
 | |
|         console.error('❌ Test failed with error:', error.message);
 | |
|         return false;
 | |
|     } finally {
 | |
|         await browser.close();
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Run the test
 | |
| testAnnouncementModal().then(success => {
 | |
|     if (success) {
 | |
|         console.log('✅ Announcement modal functionality is working correctly!');
 | |
|         process.exit(0);
 | |
|     } else {
 | |
|         console.log('❌ Announcement modal test failed');
 | |
|         process.exit(1);
 | |
|     }
 | |
| }); |