import { test, expect } from '@playwright/test'; import { getPortId, login, navigateTo, waitForSheet } from './helpers'; const RES_CLIENT_NAME = `E2E Res Client ${Date.now()}`; const RES_CLIENT_EMAIL = `e2e-res-${Date.now()}@test.example`; test.describe('Residential', () => { test.beforeEach(async ({ page }) => { await login(page, 'super_admin'); }); test('residential clients page loads with empty state or table', async ({ page }) => { await navigateTo(page, '/residential/clients'); await expect(page.getByRole('heading', { name: /residential clients/i })).toBeVisible({ timeout: 10_000, }); // Either table or empty state should render — both ok. const hasTableOrEmpty = await Promise.race([ page .locator('table') .first() .isVisible({ timeout: 5_000 }) .catch(() => false), page .getByRole('button', { name: /new/i }) .first() .isVisible({ timeout: 5_000 }) .catch(() => false), ]); expect(hasTableOrEmpty).toBeTruthy(); }); test('create a residential client via UI', async ({ page }) => { await navigateTo(page, '/residential/clients'); await page.locator('main').getByRole('button', { name: /^new$/i }).first().click(); await waitForSheet(page); const sheet = page.locator('[role="dialog"]'); await sheet.locator('#rc-name').fill(RES_CLIENT_NAME); await sheet.locator('#rc-email').fill(RES_CLIENT_EMAIL); await sheet.getByRole('button', { name: /create|save/i }).click(); await expect(sheet).not.toBeVisible({ timeout: 30_000 }); await page.waitForTimeout(1500); // Reload list and confirm row is present. await navigateTo(page, '/residential/clients'); await expect(page.getByText(RES_CLIENT_NAME).first()).toBeVisible({ timeout: 30_000 }); }); test('residential interests page loads', async ({ page }) => { await navigateTo(page, '/residential/interests'); await expect(page.getByRole('heading', { name: /residential interests/i })).toBeVisible({ timeout: 10_000, }); }); test('residential nav section is visible in sidebar', async ({ page }) => { await navigateTo(page, '/dashboard'); // Both residential links should appear for super_admin. await expect(page.getByRole('link', { name: /residential clients/i }).first()).toBeVisible({ timeout: 10_000, }); await expect(page.getByRole('link', { name: /residential interests/i }).first()).toBeVisible({ timeout: 10_000, }); }); test('public residential inquiry endpoint accepts a submission', async ({ page }) => { // Direct API call to the public endpoint — confirms wiring without UI. // Public endpoint takes portId via query string (no auth, but the helper // resolves the port ID for us via the admin API). const portId = await getPortId(page); const res = await page.request.post( `/api/public/residential-inquiries?portId=${encodeURIComponent(portId)}`, { data: { firstName: `Public${Date.now()}`, lastName: 'Smoke', email: `public-res-${Date.now()}@test.example`, phone: '+1-555-0100', notes: 'Smoke test inquiry', }, headers: { 'Content-Type': 'application/json' }, }, ); // 201 success, 429 if rate-limit hit (also acceptable as proof endpoint exists). expect([201, 429]).toContain(res.status()); }); });