diff --git a/app/(app)/payments/page.tsx b/app/(app)/payments/page.tsx index 505d05a..789bff0 100644 --- a/app/(app)/payments/page.tsx +++ b/app/(app)/payments/page.tsx @@ -90,7 +90,7 @@ export default function PaymentsPage() { ) : payments.length === 0 ? ( } /> ) : payments.map(p => ( - setSelected(p)} className="cursor-pointer hover:bg-blue-50 transition-colors"> + setSelected(p)} className="cursor-pointer hover:bg-blue-50 transition-colors"> {p.paymentDate ? formatDate(p.paymentDate) : formatDate(p.createdAt)} {p.client ? `${p.client.firstName} ${p.client.lastName}` : "—"} diff --git a/e2e/payments.spec.ts b/e2e/payments.spec.ts index 307b6a9..3731256 100644 --- a/e2e/payments.spec.ts +++ b/e2e/payments.spec.ts @@ -7,31 +7,40 @@ test.describe('Payments', () => { await page.goto('/payments'); }); - test('payments page renders', async ({ page }) => { + test('page renders with header and table', async ({ page }) => { await expect(page.locator('h1:has-text("Payments")')).toBeVisible(); await expect(page.locator('table')).toBeVisible(); }); - test('payments load with amounts', async ({ page }) => { - await page.waitForSelector('tbody tr', { timeout: 15000 }); - const rows = page.locator('tbody tr'); - const count = await rows.count(); + test('payments list loads rows from API', async ({ page }) => { + await expect(page.locator('[data-testid="payment-row"]').first()).toBeVisible({ timeout: 15000 }); + const count = await page.locator('[data-testid="payment-row"]').count(); expect(count).toBeGreaterThan(0); }); - test('channel filter buttons work', async ({ page }) => { + test('channel filter buttons exist and toggle active state', async ({ page }) => { const cashBtn = page.locator('button:has-text("CASH")').first(); + await expect(cashBtn).toBeVisible(); await cashBtn.click(); - await page.waitForTimeout(500); - await expect(page.locator('h1:has-text("Payments")')).toBeVisible(); - // All filter works - await page.locator('button:has-text("All")').click(); + await expect(cashBtn).toHaveClass(/bg-blue-600/); + // Reset to All + await page.locator('button:has-text("All")').first().click(); }); test('clicking payment row opens detail modal', async ({ page }) => { - await page.waitForSelector('tbody tr', { timeout: 15000 }); - await page.locator('tbody tr').first().click(); - await page.waitForTimeout(300); - await expect(page.locator('text=Payment Details')).toBeVisible(); + await expect(page.locator('[data-testid="payment-row"]').first()).toBeVisible({ timeout: 15000 }); + await page.locator('[data-testid="payment-row"]').first().click(); + await expect(page.locator('text=Payment Details')).toBeVisible({ timeout: 5000 }); + // Check modal has key fields + await expect(page.locator('text=Amount')).toBeVisible(); + await expect(page.locator('text=Method')).toBeVisible(); + }); + + test('detail modal closes on close button', async ({ page }) => { + await expect(page.locator('[data-testid="payment-row"]').first()).toBeVisible({ timeout: 15000 }); + await page.locator('[data-testid="payment-row"]').first().click(); + await expect(page.locator('text=Payment Details')).toBeVisible({ timeout: 5000 }); + await page.locator('button:has-text("Close")').click(); + await expect(page.locator('text=Payment Details')).not.toBeVisible({ timeout: 5000 }); }); });