import { expect, test } from "@playwright/test"; import { captureBrowserFailures, projectEmail, projectText, registerAndConfirm, selectOptionContaining, waitForMapReady, } from "./helpers"; test("two users complete a medicine handover with realtime chat and blind reviews", async ({ browser, request, }, testInfo) => { const requestTitle = projectText("E2E medicine pickup", testInfo.project.name); const requester = await registerAndConfirm( browser, request, projectEmail("requester", testInfo.project.name), "E2E Requester", ); const helper = await registerAndConfirm( browser, request, projectEmail("helper", testInfo.project.name), "E2E Helper", ); const assertRequesterClean = captureBrowserFailures(requester.page); const assertHelperClean = captureBrowserFailures(helper.page); await requester.page.goto("/requests/new"); await selectOptionContaining(requester.page, "Category", "Medicine pickup"); await requester.page.getByLabel("Medicine pickup status").selectOption("reserved"); await requester.page.getByLabel("Short title").fill(requestTitle); await requester.page .getByLabel("What help do you need?") .fill("Please collect the legal medicine that is already reserved."); await requester.page.getByLabel("Urgency").selectOption("now"); const expiresAt = new Date(Date.now() + 3 * 60 * 60 * 1000) .toISOString() .slice(0, 16); await requester.page.getByLabel("Request expires (UTC)").fill(expiresAt); await requester.page.getByLabel("Approximate area").fill("E2E central district"); await requester.page.getByLabel("Location visibility").selectOption("approximate_public"); await requester.page.getByLabel("Latitude").fill("50.4501"); await requester.page.getByLabel("Longitude").fill("30.5234"); await requester.page.locator("#request-form input[type=checkbox]").check(); await requester.page.getByRole("button", { name: "Publish request" }).click(); await expect(requester.page).toHaveURL(/\/requests\/[0-9a-f-]+$/); const requestURL = requester.page.url(); await expect(requester.page.getByRole("heading", { name: requestTitle })).toBeVisible(); await helper.page.goto(requestURL); await helper.page.getByRole("button", { name: "I can help" }).click(); await expect(helper.page.getByRole("heading", { name: "Private match chat" })).toBeVisible(); await expect(requester.page.getByRole("heading", { name: "Private match chat" })).toBeVisible(); await helper.page .getByPlaceholder("Write a safe coordination message…") .fill("I am on my way to the pharmacy."); await helper.page.getByRole("button", { name: "Send", exact: true }).click(); await expect(requester.page.getByText("I am on my way to the pharmacy.")).toBeVisible(); await requester.page .getByPlaceholder("Write a safe coordination message…") .fill("Thank you. The order is waiting at the counter."); await requester.page.getByRole("button", { name: "Send", exact: true }).click(); await expect(helper.page.getByText("Thank you. The order is waiting at the counter.")).toBeVisible(); await helper.page.getByRole("button", { name: "Start helping" }).click(); const handoverCode = ( await requester.page.locator("text=HANDOVER CODE FOR THE HELPER").locator("..").locator(".font-mono").innerText() ).replace(/\s/g, ""); expect(handoverCode).toMatch(/^\d{6}$/); await helper.page.getByLabel("Enter handover code").fill(handoverCode); await helper.page.getByRole("button", { name: "Verify handover" }).click(); await expect(helper.page.getByText("Handover code verified.")).toBeVisible(); await helper.page.getByRole("button", { name: "Confirm my part is complete" }).click(); await requester.page.getByRole("button", { name: "Confirm my part is complete" }).click(); await expect(requester.page.getByRole("heading", { name: "Double-blind review" })).toBeVisible(); await expect(helper.page.getByRole("heading", { name: "Double-blind review" })).toBeVisible(); await helper.page.getByLabel("Rating").selectOption("5"); await helper.page.getByLabel("Comment (optional)").fill("Clear and safe coordination."); await helper.page.getByRole("button", { name: "Submit review" }).click(); await expect( helper.page.getByText("Review saved. It appears after both participants review."), ).toBeVisible(); await waitForMapReady(requester.page); await requester.page.goto("/profile"); await expect(requester.page.getByText("None revealed yet.")).toBeVisible(); await expect(requester.page.getByText("Clear and safe coordination.")).toHaveCount(0); await requester.page.goto(requestURL); await requester.page.getByLabel("Rating").selectOption("5"); await requester.page.getByLabel("Comment (optional)").fill("Reliable volunteer."); await requester.page.getByRole("button", { name: "Submit review" }).click(); await expect( requester.page.getByText("Review saved. It appears after both participants review."), ).toBeVisible(); await waitForMapReady(requester.page); await requester.page.goto("/profile"); await expect(requester.page.getByText("Clear and safe coordination.")).toBeVisible(); await waitForMapReady(helper.page); await helper.page.goto("/profile"); await expect(helper.page.getByText("Reliable volunteer.")).toBeVisible(); assertRequesterClean(); assertHelperClean(); await requester.context.close(); await helper.context.close(); });