Files
tilbudgivern/tests/advanced-dashboard.spec.js
T
alexpolo1 bbb75ccce2 feat: Add Advanced Dashboard and perform repo cleanup
This commit introduces a new Advanced Dashboard feature, which provides enhanced analytics and system health monitoring.

Additionally, this commit includes a general repository cleanup, which consists of:

- Removal of a duplicate  file from the root directory.
- Addition of temporary report and documentation files to .
- Relocation of several test files from the root to the  directory.
- Staging of various other modified files that were previously uncommitted.

The new Advanced Dashboard feature includes:
-  and  for the UI.
-  for the backend API.
-  for API documentation.

New tests for smart packages and autosave functionality have also been added.
2026-02-28 17:38:23 +00:00

182 lines
6.3 KiB
JavaScript

/**
* Advanced Dashboard API Tests
* Tests for PM2 logs, SQL status, and comprehensive health monitoring
*/
const { test, expect } = require('@playwright/test');
const BASE_URL = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:4032';
test.describe('Advanced Dashboard - Health APIs', () => {
test('GET /api/health/pm2-logs - Returns PM2 process information', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/pm2-logs`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.success).toBe(true);
expect(Array.isArray(data.logs)).toBe(true);
expect(data.timestamp).toBeDefined();
// If logs exist, verify structure
if (data.logs.length > 0) {
const firstLog = data.logs[0];
expect(firstLog.name).toBeDefined();
expect(firstLog.status).toBeDefined();
expect(typeof firstLog.cpu).toBe('string');
expect(typeof firstLog.memory).toBe('number');
expect(typeof firstLog.restarts).toBe('number');
}
});
test('GET /api/health/sql-status - Returns comprehensive database status', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/sql-status`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.status).toBeDefined();
expect(data.timestamp).toBeDefined();
expect(['ok', 'warning', 'error', 'disconnected']).toContain(data.status);
// Verify database metrics
if (data.connected) {
expect(typeof data.databaseSize).toBe('number');
expect(typeof data.databaseSize_MB).toBe('number');
expect(typeof data.tableCount).toBe('number');
expect(typeof data.activeQueries).toBe('number');
expect(typeof data.totalConnections).toBe('number');
expect(typeof data.indexCount).toBe('number');
}
});
test('GET /api/health/detailed - Returns detailed health check', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/detailed`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.status).toBeDefined();
expect(['ok', 'degraded', 'error']).toContain(data.status);
expect(data.timestamp).toBeDefined();
expect(typeof data.uptime).toBe('number');
expect(data.checks).toBeDefined();
// Verify check structure
expect(data.checks.database).toBeDefined();
expect(data.checks.memory).toBeDefined();
});
test('GET /api/health/quick - Returns quick health status', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/quick`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(['ok', 'degraded', 'error']).toContain(data.status);
expect(data.checks).toBeDefined();
});
test('GET /api/health/logs - Returns system logs', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/logs`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.success).toBe(true);
expect(Array.isArray(data.logs)).toBe(true);
});
test('GET /api/health/stats - Returns performance statistics', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/stats`);
expect(response.status()).toBe(200);
const data = await response.json();
expect(data.success).toBe(true);
expect(Array.isArray(data.hourlyStats)).toBe(true);
expect(Array.isArray(data.topEndpoints)).toBe(true);
// Verify hourly stats structure
if (data.hourlyStats.length > 0) {
const stat = data.hourlyStats[0];
expect(stat.hour).toBeDefined();
expect(typeof stat.requests).toBe('number');
expect(typeof stat.avg_response_time).toBe('number');
}
});
test('PM2 logs contain valid process status', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/pm2-logs`);
const data = await response.json();
if (data.logs.length > 0) {
const validStatuses = ['online', 'stopping', 'stopped', 'waiting restart', 'one-launch-status'];
data.logs.forEach(log => {
expect(validStatuses).toContain(log.status);
});
}
});
test('SQL status provides meaningful database metrics', async ({ request }) => {
const response = await request.get(`${BASE_URL}/api/health/sql-status`);
const data = await response.json();
if (data.connected) {
// Database size should be reasonable
expect(data.databaseSize_MB).toBeGreaterThanOrEqual(0);
expect(data.tableCount).toBeGreaterThanOrEqual(0);
expect(data.activeQueries).toBeGreaterThanOrEqual(0);
expect(data.totalConnections).toBeGreaterThanOrEqual(0);
}
});
});
test.describe('Advanced Dashboard - API Integration', () => {
test('Multiple concurrent health checks should succeed', async ({ request }) => {
const promises = [
request.get(`${BASE_URL}/api/health/detailed`),
request.get(`${BASE_URL}/api/health/quick`),
request.get(`${BASE_URL}/api/health/pm2-logs`),
request.get(`${BASE_URL}/api/health/sql-status`),
request.get(`${BASE_URL}/api/health/stats`)
];
const responses = await Promise.all(promises);
responses.forEach(response => {
expect(response.status()).toBe(200);
});
});
test('Health endpoints should respond within reasonable time', async ({ request }) => {
const endpoints = [
'/api/health/quick',
'/api/health/pm2-logs',
'/api/health/sql-status'
];
for (const endpoint of endpoints) {
const startTime = Date.now();
const response = await request.get(`${BASE_URL}${endpoint}`);
const duration = Date.now() - startTime;
expect(response.status()).toBe(200);
expect(duration).toBeLessThan(5000); // Should respond within 5 seconds
}
});
test('Health check data should be consistent across multiple calls', async ({ request }) => {
const response1 = await request.get(`${BASE_URL}/api/health/quick`);
const data1 = await response1.json();
const response2 = await request.get(`${BASE_URL}/api/health/quick`);
const data2 = await response2.json();
// Status should be consistent
expect(data1.status).toBe(data2.status);
});
});