import { test, expect } from "@playwright/test"; import pg from "pg"; const DATABASE_URL = process.env.DATABASE_URL; if (!DATABASE_URL) { throw new Error( "DATABASE_URL must be set to run the executive-meetings UI test", ); } const pool = new pg.Pool({ connectionString: DATABASE_URL }); const createdMeetingIds = []; const today = new Date().toISOString().slice(0, 10); async function loginViaUi(page, username, password) { await page.goto("/login"); await page.locator("#username").fill(username); await page.locator("#password").fill(password); await Promise.all([ page.waitForURL((url) => !url.pathname.endsWith("/login"), { timeout: 15_000, }), page.locator('form button[type="submit"]').click(), ]); } test.afterAll(async () => { if (createdMeetingIds.length > 0) { await pool.query( `DELETE FROM executive_meeting_attendees WHERE meeting_id = ANY($1::int[])`, [createdMeetingIds], ); await pool.query( `DELETE FROM executive_meeting_audit_logs WHERE entity_type = 'meeting' AND entity_id = ANY($1::int[])`, [createdMeetingIds], ); await pool.query( `DELETE FROM executive_meetings WHERE id = ANY($1::int[])`, [createdMeetingIds], ); } await pool.end(); }); test("Manage tab: admin can create a meeting from the UI and see it in the list", async ({ page, }) => { await page.addInitScript(() => { try { window.localStorage.setItem("tx-lang", "en"); } catch { /* localStorage may not be ready before navigation */ } }); await loginViaUi(page, "admin", "admin123"); await page.goto("/executive-meetings"); await page.getByTestId("em-nav-manage").click(); const addBtn = page.getByTestId("em-add-meeting"); await expect(addBtn).toBeVisible(); const createPromise = page.waitForResponse( (resp) => { const u = new URL(resp.url()); return ( u.pathname === "/api/executive-meetings" && resp.request().method() === "POST" ); }, { timeout: 15_000 }, ); await addBtn.click(); const uniq = `${Date.now().toString(36)}_${Math.random() .toString(36) .slice(2, 6)}`; const titleAr = `اجتماع واجهة ${uniq}`; const titleEn = `UI Meeting ${uniq}`; await page.getByTestId("em-form-titleAr").fill(titleAr); const dialog = page.getByRole("dialog"); const titleEnInput = dialog .locator("input") .nth(1); // titleAr=0, titleEn=1, meetingDate=2 (date), dailyNumber=3 await titleEnInput.fill(titleEn); await dialog.locator('input[type="date"]').first().fill(today); await page.getByTestId("em-form-save").click(); const resp = await createPromise; expect(resp.status()).toBe(201); const created = await resp.json(); expect(created.id).toBeTruthy(); createdMeetingIds.push(created.id); await expect(dialog).toBeHidden({ timeout: 10_000 }); const { rows } = await pool.query( `SELECT id, title_en, meeting_date FROM executive_meetings WHERE id = $1`, [created.id], ); expect(rows.length).toBe(1); expect(rows[0].title_en).toBe(titleEn); const isoDate = rows[0].meeting_date instanceof Date ? rows[0].meeting_date.toISOString().slice(0, 10) : String(rows[0].meeting_date).slice(0, 10); expect(isoDate).toBe(today); });