40227-vm/frontend/tests/e2e/product-workflow.seeded.e2e.ts
2026-06-12 06:55:35 +02:00

89 lines
3.1 KiB
TypeScript

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<void> {
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();
});
});