Files
pn-new-crm/tests/e2e/smoke/07-error-handling.spec.ts
Matt 67d7e6e3d5
Some checks failed
Build & Push Docker Images / build-and-push (push) Has been cancelled
Build & Push Docker Images / deploy (push) Has been cancelled
Build & Push Docker Images / lint (push) Has been cancelled
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00

69 lines
2.6 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { login, PORT_SLUG } from './helpers';
test.describe('Error Handling', () => {
test('non-existent route shows 404 page', async ({ page }) => {
await login(page, 'super_admin');
await page.goto(`/${PORT_SLUG}/this-page-does-not-exist`);
await page.waitForLoadState('networkidle');
const is404 = await page.getByText('404').isVisible().catch(() => false);
const isNotFound = await page.getByText(/not found/i).isVisible().catch(() => false);
expect(is404 || isNotFound).toBeTruthy();
});
test('empty required fields show validation errors', async ({ page }) => {
await login(page, 'super_admin');
// Go to new invoice page (has required fields)
await page.goto(`/${PORT_SLUG}/invoices/new`);
await page.waitForLoadState('networkidle');
// Click Next without filling required fields
const nextBtn = page.getByRole('button', { name: /next/i });
if (await nextBtn.isVisible({ timeout: 5_000 }).catch(() => false)) {
await nextBtn.click();
await page.waitForTimeout(1000);
// Should see validation error messages (red text)
const errorMsg = page.locator('.text-destructive').first();
await expect(errorMsg).toBeVisible({ timeout: 5_000 });
}
});
test('non-existent entity shows error or 404', async ({ page }) => {
await login(page, 'super_admin');
// Navigate to a client with a fake UUID
await page.goto(`/${PORT_SLUG}/clients/00000000-0000-0000-0000-000000000000`);
await page.waitForLoadState('networkidle');
await page.waitForTimeout(3000);
// Should show 404, not found, error, or empty state — but NOT crash
const is404 = await page.getByText('404').isVisible().catch(() => false);
const isNotFound = await page.getByText(/not found/i).isVisible().catch(() => false);
const isError = await page.getByText(/error|not exist/i).isVisible().catch(() => false);
const noData = await page.getByText(/no client|loading/i).isVisible().catch(() => false);
// At minimum, the page should not be a blank crash
const body = await page.locator('body').textContent();
expect(body && body.length > 10).toBeTruthy();
});
test('login form shows validation for invalid email', async ({ page }) => {
await page.goto('/login');
await page.fill('#email', 'not-an-email');
await page.fill('#password', 'x');
await page.click('button[type="submit"]');
await page.waitForTimeout(1000);
// Should see validation error for email
const errorMsg = page.locator('.text-destructive').first();
await expect(errorMsg).toBeVisible({ timeout: 5_000 });
});
});