Files
bakery-ia/frontend/tests/dashboard/dashboard-smoke.spec.ts

153 lines
4.6 KiB
TypeScript
Raw Normal View History

2025-11-14 07:46:29 +01:00
import { test, expect } from '@playwright/test';
2025-11-15 21:21:06 +01:00
import { acceptCookieConsent } from '../helpers/utils';
2025-11-14 07:46:29 +01:00
test.describe('Dashboard Smoke Tests', () => {
// Use authenticated state
test.use({ storageState: 'tests/.auth/user.json' });
2025-11-15 21:21:06 +01:00
test.beforeEach(async ({ page }) => {
// Accept cookie consent if present
await acceptCookieConsent(page);
});
2025-11-14 07:46:29 +01:00
test('should load dashboard successfully', async ({ page }) => {
await page.goto('/app/dashboard');
2025-11-15 21:21:06 +01:00
await acceptCookieConsent(page);
2025-11-14 07:46:29 +01:00
// Verify dashboard loads
await expect(page.locator('body')).toContainText(/dashboard|panel de control/i);
// Should not show any error messages
const errorMessages = page.locator('[role="alert"]').filter({ hasText: /error|failed/i });
await expect(errorMessages).toHaveCount(0);
});
test('should display key dashboard sections', async ({ page }) => {
await page.goto('/app/dashboard');
// Wait for content to load
await page.waitForLoadState('networkidle');
// Check for common dashboard sections
const sections = [
/health.*status|estado.*salud/i,
/action.*queue|cola.*acciones/i,
/production|producción/i,
/orders|pedidos/i,
];
// At least some sections should be visible
let visibleSections = 0;
for (const sectionPattern of sections) {
const section = page.locator('body').filter({ hasText: sectionPattern });
if (await section.isVisible().catch(() => false)) {
visibleSections++;
}
}
expect(visibleSections).toBeGreaterThan(0);
});
test('should display unified Add button', async ({ page }) => {
await page.goto('/app/dashboard');
// Look for Add button
const addButton = page.getByRole('button', { name: /^add$|^añadir$|^\+$/i });
if (await addButton.isVisible().catch(() => false)) {
await expect(addButton).toBeVisible();
}
});
test('should navigate to different sections from dashboard', async ({ page }) => {
await page.goto('/app/dashboard');
// Look for navigation links
const navigationLinks = [
{ pattern: /operations|operaciones/i, expectedUrl: /operations/ },
{ pattern: /analytics|analítica/i, expectedUrl: /analytics/ },
{ pattern: /settings|configuración/i, expectedUrl: /settings/ },
];
for (const { pattern, expectedUrl } of navigationLinks) {
const link = page.getByRole('link', { name: pattern }).first();
if (await link.isVisible().catch(() => false)) {
await link.click();
// Verify navigation
await expect(page).toHaveURL(expectedUrl, { timeout: 5000 });
// Go back to dashboard
await page.goto('/app/dashboard');
await page.waitForLoadState('networkidle');
break; // Test one navigation link
}
}
});
test('should load data without errors', async ({ page }) => {
// Listen for console errors
const errors: string[] = [];
page.on('console', (msg) => {
if (msg.type() === 'error') {
errors.push(msg.text());
}
});
// Listen for failed network requests
const failedRequests: string[] = [];
page.on('response', (response) => {
if (response.status() >= 400) {
failedRequests.push(`${response.status()} ${response.url()}`);
}
});
await page.goto('/app/dashboard');
await page.waitForLoadState('networkidle');
// Should not have critical console errors
const criticalErrors = errors.filter((err) =>
err.toLowerCase().includes('failed') || err.toLowerCase().includes('error')
);
2025-11-15 21:21:06 +01:00
// Allow some non-critical errors but not too many (increased from 5 to 10 for K8s environment)
expect(criticalErrors.length).toBeLessThan(10);
2025-11-14 07:46:29 +01:00
});
test('should be responsive on mobile viewport', async ({ page }) => {
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/app/dashboard');
// Dashboard should still load
await expect(page.locator('body')).toContainText(/dashboard|panel de control/i);
// Content should be visible (not cut off)
const body = page.locator('body');
await expect(body).toBeVisible();
});
test('should handle refresh without losing state', async ({ page }) => {
await page.goto('/app/dashboard');
// Wait for initial load
await page.waitForLoadState('networkidle');
// Get some state (e.g., URL)
const urlBefore = page.url();
// Refresh page
await page.reload();
// Should still be on dashboard
await expect(page).toHaveURL(urlBefore);
// Should still show dashboard content
await expect(page.locator('body')).toContainText(/dashboard|panel de control/i);
});
});