import { test, expect } from './helpers/fixtures.js' test.describe('My Updates page', () => { test('authenticated user sees the my-updates page', async ({ adminPage }) => { await adminPage.goto('/member/my-updates') await expect(adminPage.locator('h1', { hasText: 'My Updates' })).toBeVisible({ timeout: 10000, }) }) test('authenticated user sees the new update link', async ({ adminPage }) => { await adminPage.goto('/member/my-updates') // Wait for ClientOnly content to hydrate await expect(adminPage.locator('h1', { hasText: 'My Updates' })).toBeVisible({ timeout: 10000, }) // The page shows either the "+ New Update" button (stats row) or // the "+ Post Your First Update" link (empty state) — both go to /updates/new const newUpdateLink = adminPage.locator('a[href="/updates/new"]') await expect(newUpdateLink.first()).toBeVisible({ timeout: 10000 }) }) test('unauthenticated user sees sign-in prompt', async ({ browser }) => { const context = await browser.newContext() const page = await context.newPage() await page.goto('/member/my-updates') // Should show the page's "Sign in required" heading await expect(page.locator('.state-heading')).toBeVisible({ timeout: 10000 }) await context.close() }) }) test.describe('New Update page', () => { test('loads the new update form', async ({ adminPage }) => { await adminPage.goto('/updates/new') await expect(adminPage.locator('h1', { hasText: 'New Update' })).toBeVisible({ timeout: 10000, }) // Form elements are present await expect(adminPage.locator('textarea')).toBeVisible() await expect(adminPage.locator('select')).toBeVisible() // Submit button exists and starts disabled (empty textarea) const submitBtn = adminPage.locator('button[type="submit"]', { hasText: 'Post Update' }) await expect(submitBtn).toBeVisible() await expect(submitBtn).toBeDisabled() }) test('submit button enables when content is entered', async ({ adminPage }) => { await adminPage.goto('/updates/new') await adminPage.waitForLoadState('networkidle') await expect(adminPage.locator('h1', { hasText: 'New Update' })).toBeVisible({ timeout: 10000, }) const textarea = adminPage.locator('textarea') const submitBtn = adminPage.locator('button[type="submit"]', { hasText: 'Post Update' }) await expect(submitBtn).toBeDisabled() // Use click + type to ensure Vue hydration processes the input events await textarea.click() await textarea.pressSequentially('Test update content', { delay: 10 }) await expect(submitBtn).toBeEnabled({ timeout: 5000 }) }) test('privacy selector defaults to members and has all options', async ({ adminPage }) => { await adminPage.goto('/updates/new') await expect(adminPage.locator('h1', { hasText: 'New Update' })).toBeVisible({ timeout: 10000, }) const select = adminPage.locator('select') await expect(select).toHaveValue('members') // Verify all three privacy options exist await expect(select.locator('option[value="members"]')).toBeAttached() await expect(select.locator('option[value="public"]')).toBeAttached() await expect(select.locator('option[value="private"]')).toBeAttached() }) test('cancel link navigates back to my-updates', async ({ adminPage }) => { await adminPage.goto('/updates/new') await expect(adminPage.locator('h1', { hasText: 'New Update' })).toBeVisible({ timeout: 10000, }) const cancelLink = adminPage.locator('a', { hasText: 'Cancel' }) await expect(cancelLink).toHaveAttribute('href', '/member/my-updates') }) test('back link points to my-updates', async ({ adminPage }) => { await adminPage.goto('/updates/new') const backLink = adminPage.locator('.back-link a') await expect(backLink).toBeVisible({ timeout: 10000 }) await expect(backLink).toHaveAttribute('href', '/member/my-updates') }) }) test.describe('Updates API (public access)', () => { test('public updates endpoint returns data', async ({ page }) => { const response = await page.request.get('/api/updates') expect(response.ok()).toBe(true) const data = await response.json() expect(data).toHaveProperty('updates') expect(data).toHaveProperty('total') expect(data).toHaveProperty('hasMore') expect(Array.isArray(data.updates)).toBe(true) }) })