Files
TX/artifacts/tx-os/tests/executive-meetings-manage-create.spec.mjs
T

114 lines
3.2 KiB
JavaScript
Raw Normal View History

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);
});