Files
tilbudgivern/tests/simple-production-verification.spec.js
alexpolo1 26d3452d59 Add comprehensive tests for API verification, frontend integration, and PDF generation
- Implemented a new test suite for production API verification using curl, ensuring all critical endpoints respond correctly and return valid JSON.
- Added frontend integration tests to check for critical errors in the UI and verify key UI elements are present and functional.
- Created test data for quotes and project calculations to facilitate testing.
- Developed a script to check offers in the Ordrestyring system, including detailed task descriptions.
- Added tests for generating PDFs from quote data, ensuring the output is valid and contains expected information.
- Implemented a test script for the Røsevangen project, integrating with the Ordrestyring API and verifying database entries.
2025-11-07 08:02:07 +00:00

166 lines
5.8 KiB
JavaScript

const { test, expect } = require('@playwright/test');
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
// Production URL
const BASE_URL = 'https://tilbudsgiveren.alw.dk';
test.describe('Production API Verification via curl', () => {
test('All critical APIs respond correctly via curl', async () => {
const endpoints = [
'/api/health',
'/api/smart-packages?limit=3',
'/api/smart-packages/categories',
'/api/materials?limit=3',
'/api/planning/employees',
'/api/planning/calendar',
'/api/enhanced/roof-types'
];
console.log('🧪 Testing Production APIs via curl...\n');
for (const endpoint of endpoints) {
const cmd = `curl -s -w "\\n%{http_code}" "${BASE_URL}${endpoint}"`;
try {
const { stdout } = await execPromise(cmd);
const lines = stdout.trim().split('\n');
const statusCode = lines[lines.length - 1];
const response = lines.slice(0, -1).join('\n');
console.log(`${endpoint}: Status ${statusCode}`);
// Verify status code
expect(parseInt(statusCode)).toBe(200);
// Verify response contains valid JSON
if (response) {
const data = JSON.parse(response);
expect(data).toBeDefined();
// Specific verifications based on endpoint
if (endpoint.includes('/health')) {
expect(data.status).toBe('ok');
} else if (endpoint.includes('/smart-packages/categories')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.categories)).toBe(true);
expect(data.categories.length).toBeGreaterThan(0);
} else if (endpoint.includes('/smart-packages')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.packages)).toBe(true);
} else if (endpoint.includes('/materials')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.materials)).toBe(true);
} else if (endpoint.includes('/planning/employees')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.employees)).toBe(true);
expect(data.count).toBeGreaterThan(0);
console.log(` 📊 Employee Fix Verified: ${data.count} active employees of ${data.totalEmployees} total`);
} else if (endpoint.includes('/planning/calendar')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.data)).toBe(true);
expect(data.data.length).toBeGreaterThan(0);
console.log(` 📅 Calendar API Verified: ${data.data.length} calendar events`);
} else if (endpoint.includes('/roof-types')) {
expect(data.success).toBe(true);
expect(Array.isArray(data.roofTypes)).toBe(true);
expect(data.roofTypes.length).toBeGreaterThan(0);
console.log(` 🏠 Roof Types Verified: ${data.roofTypes.length} clean labels`);
}
}
} catch (error) {
console.log(`${endpoint}: Error - ${error.message}`);
throw error;
}
}
console.log('\n🎉 All API endpoints working correctly!');
});
});
test.describe('Frontend Integration Tests', () => {
test('Frontend loads and shows no critical errors', async ({ page }) => {
// Capture console errors
const consoleErrors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
// Capture network failures
const networkFailures = [];
page.on('response', response => {
if (response.status() >= 500) {
networkFailures.push({
url: response.url(),
status: response.status()
});
}
});
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(5000); // Let React fully load
// Check page loaded successfully
expect(page.url()).toContain(BASE_URL);
// Check for critical error messages in UI
const pageText = await page.textContent('body');
const criticalErrors = [
'Ingen materialer fundet',
'Smart Package Management Service ikke initialiseret',
'Failed to load categories',
'Backend services: Failed',
'Cannot read properties of undefined'
];
for (const errorText of criticalErrors) {
if (pageText.includes(errorText)) {
console.log(`❌ Found critical error in UI: "${errorText}"`);
expect(pageText).not.toContain(errorText);
}
}
// Check console errors
const criticalConsoleErrors = consoleErrors.filter(error =>
error.includes('500') ||
error.includes('Smart Package Management Service') ||
error.includes('Cannot read properties of undefined')
);
if (criticalConsoleErrors.length > 0) {
console.log('❌ Critical console errors found:', criticalConsoleErrors);
}
expect(criticalConsoleErrors.length).toBe(0);
console.log('✅ Frontend loaded successfully without critical errors');
console.log(` 📊 Total console errors: ${consoleErrors.length}`);
console.log(` 🌐 Network failures (5xx): ${networkFailures.length}`);
});
test('Key UI elements are present and functional', async ({ page }) => {
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(3000);
// Check that basic page structure exists
await expect(page.locator('body')).toBeVisible();
// Check that main app container exists (assuming React renders into root or app div)
const hasReactRoot = await page.locator('#root, #app, [data-reactroot]').count() > 0;
expect(hasReactRoot).toBe(true);
console.log('✅ Basic UI structure verified');
});
});