import { test, expect } from '@playwright/test'; import { login } from './helpers/auth'; test.describe('Clients', () => { test.beforeEach(async ({ page }) => { await login(page); await page.goto('/clients'); }); test('clients list page renders', async ({ page }) => { await expect(page.locator('h1:has-text("Clients")')).toBeVisible(); await expect(page.locator('table')).toBeVisible(); }); test('client rows load and show data', async ({ page }) => { // Wait for loading to complete await page.waitForSelector('tr.border-b', { timeout: 15000 }); const rows = page.locator('tbody tr.border-b'); const count = await rows.count(); expect(count).toBeGreaterThan(0); }); test('search filters clients', async ({ page }) => { await page.waitForSelector('tbody tr', { timeout: 10000 }); const searchInput = page.locator('input[placeholder*="Search"]'); await searchInput.fill('abc_no_match_xyz'); await page.waitForTimeout(500); await expect(page.locator('text=No clients found')).toBeVisible(); await searchInput.fill(''); }); test('Add Client modal opens and closes', async ({ page }) => { await page.click('button:has-text("Add Client")'); await expect(page.locator('text=Add New Client')).toBeVisible(); await page.click('button:has-text("Cancel")'); await expect(page.locator('text=Add New Client')).not.toBeVisible(); }); test('Add Client form requires plan', async ({ page }) => { await page.click('button:has-text("Add Client")'); // Create button should be disabled without required fields const createBtn = page.locator('button:has-text("Create Client")'); await expect(createBtn).toBeDisabled(); }); test('clicking a client row navigates to detail', async ({ page }) => { await page.waitForSelector('tbody tr.border-b', { timeout: 15000 }); await page.locator('tbody tr.border-b').first().click(); await expect(page).toHaveURL(/\/clients\/.+/); }); test('client detail page loads with tabs', async ({ page }) => { await page.waitForSelector('tbody tr.border-b', { timeout: 15000 }); await page.locator('tbody tr.border-b').first().click(); await expect(page.locator('button:has-text("Profile")')).toBeVisible(); await expect(page.locator('button:has-text("Subscriptions")')).toBeVisible(); await expect(page.locator('button:has-text("Invoices")')).toBeVisible(); await expect(page.locator('button:has-text("Payments")')).toBeVisible(); await expect(page.locator('button:has-text("Tickets")')).toBeVisible(); }); test('client detail — invoices tab loads', async ({ page }) => { await page.waitForSelector('tbody tr.border-b', { timeout: 15000 }); await page.locator('tbody tr.border-b').first().click(); await page.click('button:has-text("Invoices")'); await expect(page.locator('table')).toBeVisible({ timeout: 10000 }); }); });