import { test, expect } from './helpers/fixtures.js' test.describe('Admin members page', () => { test('members list loads for admin', async ({ adminPage }) => { await adminPage.goto('/admin/members') await expect(adminPage.locator('h1')).toHaveText('Members') await expect(adminPage.getByText('Manage members, contributions, and access')).toBeVisible() }) test('search bar works', async ({ adminPage }) => { await adminPage.goto('/admin/members') const searchInput = adminPage.getByPlaceholder('Search members...') await expect(searchInput).toBeVisible({ timeout: 10000 }) // Wait for the initial member list to load before searching await expect( adminPage.locator('table').or(adminPage.getByText('No members found matching your criteria')) ).toBeVisible({ timeout: 15000 }) await searchInput.fill('nonexistent-query-xyz') // Page should not crash -- either shows filtered results or the empty state await expect( adminPage.locator('table').or(adminPage.getByText('No members found matching your criteria')) ).toBeVisible({ timeout: 10000 }) }) test('non-admin redirect', async ({ browser }) => { const context = await browser.newContext() const page = await context.newPage() await page.goto('/admin/members') // Admin middleware redirects non-admin users to / or /members await page.waitForURL((url) => !url.pathname.startsWith('/admin')) expect(page.url()).not.toContain('/admin/members') await context.close() }) test('add member button opens modal', async ({ adminPage }) => { await adminPage.goto('/admin/members') // Wait for page to fully load and hydrate await expect(adminPage.locator('h1')).toHaveText('Members') await adminPage.waitForLoadState('networkidle') const addBtn = adminPage.getByRole('button', { name: 'Add Member' }) await expect(addBtn).toBeVisible({ timeout: 10000 }) await addBtn.click() // Modal should appear with the form heading and fields await expect(adminPage.getByPlaceholder('Full name')).toBeVisible({ timeout: 10000 }) await expect(adminPage.getByPlaceholder('email@example.com')).toBeVisible() }) })