Files
ANDJJJJJJ/server/test-frontend.mjs

307 lines
8.6 KiB
JavaScript

/**
* 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();