import { expect, type Page, test } from '@playwright/test'; /** * Product-workflow persistence e2e (Workstream 8). Proves persisted product * workflows survive across requests (the "sees it after reload" guarantee), * backed by the real backend rather than mock data: a director posts a FRAME * entry and reads it back, and a staff member marks progress and reads it back. * * Requires the backend running with the database migrated + seeded, and the * seed passwords in the environment. */ const USER_PASSWORD = 'flatlogicUser123!'; const BACKEND_API_URL = process.env.VITE_BACKEND_API_URL || 'http://localhost:8080/api'; const DIRECTOR_EMAIL = 'director@flatlogic.com'; const TEACHER_EMAIL = 'teacher@flatlogic.com'; interface FrameRow { readonly id: string; readonly author: string; } interface ProgressRow { readonly item_id: string; readonly value: string | null; } async function login(page: Page, email: string, password: string): Promise { await page.goto('/login'); await page.getByPlaceholder('you@school.edu').fill(email); await page.getByPlaceholder('Enter your password').fill(password); await page.getByRole('button', { name: 'Sign In', exact: true }).click(); await page.waitForURL((url) => !url.pathname.startsWith('/login'), { timeout: 10_000, }); } test.describe('Product-workflow persistence', () => { test('a director posts a FRAME entry and reads it back', async ({ page }) => { await login(page, DIRECTOR_EMAIL, USER_PASSWORD); const author = `E2E Director ${Date.now()}`; const createRes = await page.request.post(`${BACKEND_API_URL}/frame_entries`, { data: { data: { week_of: '2026-06-01', posted_date: '2026-06-02', formal: 'Formal note', recognition: 'Recognition note', application: 'Application note', management: 'Management note', emotional: 'Emotional note', author, }, }, }); expect(createRes.ok()).toBe(true); // Re-fetch (fresh request) and confirm the entry persisted. const listRes = await page.request.get(`${BACKEND_API_URL}/frame_entries`); expect(listRes.status()).toBe(200); const body = (await listRes.json()) as { rows?: FrameRow[] }; expect((body.rows ?? []).some((row) => row.author === author)).toBe(true); }); test('a staff member marks a sign learned and progress persists', async ({ page, }) => { await login(page, TEACHER_EMAIL, USER_PASSWORD); const itemId = `sign-${Date.now()}`; const upsertRes = await page.request.post(`${BACKEND_API_URL}/user_progress`, { data: { data: { progress_type: 'sign_learned', item_id: itemId, value: 'learned' }, }, }); expect(upsertRes.ok()).toBe(true); const listRes = await page.request.get( `${BACKEND_API_URL}/user_progress?progress_type=sign_learned&item_id=${itemId}`, ); expect(listRes.status()).toBe(200); const body = (await listRes.json()) as { rows?: ProgressRow[] }; const saved = (body.rows ?? []).find((row) => row.item_id === itemId); expect(saved, 'the marked progress must persist').toBeTruthy(); }); });