Complete Email Sortierer implementation with Appwrite and Stripe integration
This commit is contained in:
306
server/test-frontend.mjs
Normal file
306
server/test-frontend.mjs
Normal file
@@ -0,0 +1,306 @@
|
||||
/**
|
||||
* 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();
|
||||
Reference in New Issue
Block a user