/** * Frontend Integration Test * Tests all form types, navigation, validation, and summary functionality */ import { JSDOM } from 'jsdom'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Load the HTML file const htmlPath = join(__dirname, '../public/index.html'); const html = readFileSync(htmlPath, 'utf-8'); // Mock questions data covering all form types const mockQuestions = [ { key: 'email', label: 'E-Mail Adresse', type: 'email', required: true, step: 1, order: 1, helpText: 'Ihre E-Mail für Benachrichtigungen' }, { key: 'name', label: 'Name', type: 'text', required: true, step: 1, order: 2 }, { key: 'priority', label: 'Priorität', type: 'select', required: true, step: 2, order: 1, optionsJson: JSON.stringify(['Hoch', 'Mittel', 'Niedrig']) }, { key: 'categories', label: 'Kategorien', type: 'multiselect', required: false, step: 2, order: 2, optionsJson: JSON.stringify(['Arbeit', 'Privat', 'Newsletter', 'Spam']) }, { key: 'description', label: 'Beschreibung', type: 'textarea', required: false, step: 3, order: 1, helpText: 'Zusätzliche Informationen' } ]; console.log('🧪 Starting Frontend Integration Tests...\n'); // Test 1: Verify all form types render correctly function testFormTypeRendering() { console.log('Test 1: Form Type Rendering'); const dom = new JSDOM(html, { runScripts: 'dangerously', resources: 'usable' }); const { window } = dom; const { document } = window; // Mock fetch for questions window.fetch = async (url) => { if (url.includes('/api/questions')) { return { json: async () => mockQuestions }; } }; // Wait for questions to load return new Promise((resolve) => { setTimeout(() => { const container = document.getElementById('form-container'); // Check text input const textInput = document.querySelector('input[type="text"]'); console.log(' ✓ Text input rendered:', textInput !== null); // Check email input const emailInput = document.querySelector('input[type="email"]'); console.log(' ✓ Email input rendered:', emailInput !== null); // Check required markers const labels = Array.from(document.querySelectorAll('label')); const hasRequiredMarker = labels.some(l => l.textContent.includes('*')); console.log(' ✓ Required field markers present:', hasRequiredMarker); // Check help text const helpText = document.querySelector('small'); console.log(' ✓ Help text rendered:', helpText !== null); window.close(); resolve(); }, 100); }); } // Test 2: Verify navigation between steps function testStepNavigation() { console.log('\nTest 2: Step Navigation'); const dom = new JSDOM(html, { runScripts: 'dangerously' }); const { window } = dom; const { document } = window; window.fetch = async (url) => { if (url.includes('/api/questions')) { return { json: async () => mockQuestions }; } }; return new Promise((resolve) => { setTimeout(() => { const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); // Check initial state (step 1) console.log(' ✓ Previous button hidden on step 1:', prevBtn.style.display === 'none'); console.log(' ✓ Next button visible:', nextBtn.style.display !== 'none'); // Simulate filling required fields const emailInput = document.querySelector('input[type="email"]'); const textInput = document.querySelector('input[type="text"]'); if (emailInput) emailInput.value = 'test@example.com'; if (textInput) textInput.value = 'Test User'; // Click next nextBtn.click(); setTimeout(() => { console.log(' ✓ Previous button visible on step 2:', prevBtn.style.display !== 'none'); window.close(); resolve(); }, 50); }, 100); }); } // Test 3: Verify validation of required fields function testRequiredFieldValidation() { console.log('\nTest 3: Required Field Validation'); const dom = new JSDOM(html, { runScripts: 'dangerously' }); const { window } = dom; const { document } = window; // Mock alert let alertCalled = false; window.alert = (msg) => { alertCalled = true; console.log(' ✓ Validation alert triggered:', msg); }; window.fetch = async (url) => { if (url.includes('/api/questions')) { return { json: async () => mockQuestions }; } }; return new Promise((resolve) => { setTimeout(() => { const nextBtn = document.getElementById('next-btn'); // Try to proceed without filling required fields nextBtn.click(); setTimeout(() => { console.log(' ✓ Validation prevents navigation:', alertCalled); window.close(); resolve(); }, 50); }, 100); }); } // Test 4: Verify summary and buy button function testSummaryAndBuyButton() { console.log('\nTest 4: Summary and Buy Button'); const dom = new JSDOM(html, { runScripts: 'dangerously' }); const { window } = dom; const { document } = window; window.fetch = async (url) => { if (url.includes('/api/questions')) { return { json: async () => mockQuestions }; } }; return new Promise((resolve) => { setTimeout(() => { // Fill all required fields and navigate to summary const emailInput = document.querySelector('input[type="email"]'); const textInput = document.querySelector('input[type="text"]'); if (emailInput) emailInput.value = 'test@example.com'; if (textInput) textInput.value = 'Test User'; // Navigate through all steps const nextBtn = document.getElementById('next-btn'); // Step 1 -> 2 nextBtn.click(); setTimeout(() => { const selectInput = document.querySelector('select:not([multiple])'); if (selectInput) selectInput.value = 'Hoch'; // Step 2 -> 3 nextBtn.click(); setTimeout(() => { // Step 3 -> Summary nextBtn.click(); setTimeout(() => { const summary = document.getElementById('summary'); const buyBtn = document.getElementById('buy-btn'); const summaryContent = document.getElementById('summary-content'); console.log(' ✓ Summary section visible:', summary.style.display !== 'none'); console.log(' ✓ Buy button present:', buyBtn !== null); console.log(' ✓ Summary content populated:', summaryContent.children.length > 0); window.close(); resolve(); }, 50); }, 50); }, 50); }, 100); }); } // Test 5: Verify multiselect handling function testMultiselectHandling() { console.log('\nTest 5: Multiselect Handling'); const dom = new JSDOM(html, { runScripts: 'dangerously' }); const { window } = dom; const { document } = window; window.fetch = async (url) => { if (url.includes('/api/questions')) { return { json: async () => mockQuestions }; } }; return new Promise((resolve) => { setTimeout(() => { // Navigate to step 2 where multiselect is const emailInput = document.querySelector('input[type="email"]'); const textInput = document.querySelector('input[type="text"]'); if (emailInput) emailInput.value = 'test@example.com'; if (textInput) textInput.value = 'Test User'; const nextBtn = document.getElementById('next-btn'); nextBtn.click(); setTimeout(() => { const multiselect = document.querySelector('select[multiple]'); console.log(' ✓ Multiselect rendered:', multiselect !== null); console.log(' ✓ Multiselect has size attribute:', multiselect?.size === 5); console.log(' ✓ Multiselect has options:', multiselect?.options.length > 0); window.close(); resolve(); }, 50); }, 100); }); } // Run all tests async function runTests() { try { await testFormTypeRendering(); await testStepNavigation(); await testRequiredFieldValidation(); await testSummaryAndBuyButton(); await testMultiselectHandling(); console.log('\n✅ All frontend integration tests completed!\n'); } catch (error) { console.error('\n❌ Test failed:', error); process.exit(1); } } runTests();