import { test, expect } from "@playwright/test"; import { EventProposalPage } from "../pages"; import { callMethod, updateDoc } from "../helpers/frappe"; test.describe("Event Proposal Form - Rendering", () => { test("should display the proposal form", async ({ page }) => { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); await proposalPage.expectFormVisible(); }); test("should display the banner title", async ({ page }) => { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); await proposalPage.expectBannerTitle("Propose an Event"); }); test("should display the title field", async ({ page }) => { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); await proposalPage.expectFieldVisible("Title"); }); test("should display the submit button", async ({ page }) => { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); await proposalPage.expectSubmitButtonVisible(); }); }); test.describe("Event Proposal Form - Submission", () => { test("should fill and submit a proposal", async ({ page }) => { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); const titleInput = proposalPage.getInputByLabel("Title"); await titleInput.fill("E2E Test: Automated Testing with Playwright"); const categorySelect = page.locator("select").first(); await categorySelect.waitFor({ state: "visible", timeout: 5000 }); await categorySelect.selectOption({ label: "E2E Test Category" }); const aboutTextarea = page .locator('label:has-text("About the event")') .locator("..") .locator("textarea"); await aboutTextarea.fill("An E2E test proposal about automated testing practices."); const { succeeded, status } = await proposalPage.submitAndExpectResponse(); console.log(`Proposal submission: status=${status}, succeeded=${succeeded}`); }); test("should show success banner after submission", async ({ page }) => { await page.route(/submit_event_proposal/, (route) => route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ message: null }), }), ); const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.waitForFormLoad(); const titleInput = proposalPage.getInputByLabel("Title"); await titleInput.fill("E2E Test: Another Proposal for Success Banner"); const categorySelect = page.locator("select").first(); await categorySelect.waitFor({ state: "visible", timeout: 5000 }); await categorySelect.selectOption({ label: "E2E Test Category" }); const aboutTextarea = page .locator('label:has-text("About the event")') .locator("..") .locator("textarea"); await aboutTextarea.fill("An E2E test proposal about building better events."); await proposalPage.submitAndExpectResponse(); await proposalPage.expectSuccess(); }); }); test.describe("Event Proposal Form - Access Control", () => { test("should show not found when proposals are disabled", async ({ page, request }) => { await updateDoc(request, "Pohodex Event Manager Settings", "Pohodex Event Manager Settings", { accept_event_proposals: 0, }); try { const proposalPage = new EventProposalPage(page); await proposalPage.goto(); await proposalPage.expectNotFound(); } finally { await updateDoc(request, "Pohodex Event Manager Settings", "Pohodex Event Manager Settings", { accept_event_proposals: 1, }); } }); test("should return error via API when proposals are disabled", async ({ request }) => { await updateDoc(request, "Pohodex Event Manager Settings", "Pohodex Event Manager Settings", { accept_event_proposals: 0, }); try { const result = await callMethod( request, "event_manager.api.forms.get_event_proposal_form_data", ).catch((err: Error) => err); expect(result).toBeInstanceOf(Error); } finally { await updateDoc(request, "Pohodex Event Manager Settings", "Pohodex Event Manager Settings", { accept_event_proposals: 1, }); } }); }); test.describe("Event Proposal Form - API", () => { test("should return form data with expected shape", async ({ request }) => { const data = await callMethod<{ form_fields: Array<{ fieldname: string }>; banner_title: string; form_title: string; success_title: string; }>(request, "event_manager.api.forms.get_event_proposal_form_data"); expect(data.form_fields).toBeInstanceOf(Array); expect(data.form_fields.length).toBeGreaterThan(0); expect(data.banner_title).toBeTruthy(); expect(data.form_title).toBeTruthy(); expect(data.success_title).toBeTruthy(); }); test("should not expose excluded fields in form data", async ({ request }) => { const data = await callMethod<{ form_fields: Array<{ fieldname: string }>; }>(request, "event_manager.api.forms.get_event_proposal_form_data"); const fieldnames = data.form_fields.map((f) => f.fieldname); const excludedFields = ["status", "submitted_by", "host", "naming_series", "amended_from"]; for (const excluded of excludedFields) { expect(fieldnames).not.toContain(excluded); } }); });