who_need_help/e2e/tests/request-discovery.spec.ts

118 lines
4.2 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
captureBrowserFailures,
gotoLiveView,
projectEmail,
projectText,
registerAndConfirm,
selectOptionContaining,
setRequestLocation,
waitForMapReady,
} from "./helpers";
async function createMedicineRequest(
page: Parameters<typeof gotoLiveView>[0],
title: string,
location: { label: string; latitude: string; longitude: string },
) {
await gotoLiveView(page, "/requests/new");
await selectOptionContaining(page, "Category", "Medicine pickup");
await page.getByLabel("Medicine pickup status").selectOption("reserved");
await page.getByLabel("Short title").fill(title);
await page
.getByLabel("What help do you need?")
.fill("Please collect a legal medicine order that is already reserved.");
await page.getByLabel("Urgency").selectOption("now");
await page.getByRole("button", { name: "In 3 hours" }).click();
await setRequestLocation(page, {
...location,
mode: "exact_public",
});
await page.locator("#request-form input[type=checkbox]").check();
await page.getByRole("button", { name: "Publish request" }).click();
await expect(page.getByRole("heading", { name: title })).toBeVisible();
}
test("request discovery searches the viewport, clusters dense points, and remembers layout", async ({
browser,
request,
}, testInfo) => {
const attemptScope = `${testInfo.project.name}-${Date.now()}-${process.pid}`;
const requester = await registerAndConfirm(
browser,
request,
projectEmail(`discovery-requester-${attemptScope}`, testInfo.project.name),
"Discovery requester",
);
const viewer = await registerAndConfirm(
browser,
request,
projectEmail(`discovery-viewer-${attemptScope}`, testInfo.project.name),
"Discovery viewer",
);
const assertRequesterClean = captureBrowserFailures(requester.page);
const assertViewerClean = captureBrowserFailures(viewer.page);
const denseTitles = [1, 2, 3].map((index) =>
projectText(`Kyiv viewport request ${index}`, attemptScope),
);
const berlinTitle = projectText("Berlin outside viewport", attemptScope);
const kyivArea = `Kyiv discovery ${attemptScope}`;
for (const title of denseTitles) {
await createMedicineRequest(requester.page, title, {
label: kyivArea,
latitude: "50.4501",
longitude: "30.5234",
});
}
await createMedicineRequest(requester.page, berlinTitle, {
label: "Berlin discovery area",
latitude: "52.5200",
longitude: "13.4050",
});
await gotoLiveView(
viewer.page,
`/requests?west=30.2&south=50.2&east=30.8&north=50.7&zoom=10&width=1280&height=720&view=split&area=${encodeURIComponent(kyivArea)}`,
);
await waitForMapReady(viewer.page);
for (const title of denseTitles) {
await expect(viewer.page.getByRole("heading", { name: title })).toBeVisible();
}
await expect(viewer.page.getByText(berlinTitle)).toHaveCount(0);
await expect(viewer.page.getByText("3 requests in this map area")).toBeVisible();
const mapItems = JSON.parse((await viewer.page.locator("#request-map").getAttribute("data-items"))!);
expect(mapItems).toContainEqual(expect.objectContaining({ type: "cluster", count: 3 }));
if ((await viewer.page.locator("#request-map canvas").count()) > 0) {
await expect(viewer.page.locator(".request-map-cluster", { hasText: "3" })).toBeVisible();
} else {
await expect(viewer.page.locator("#request-map")).toContainText("The map is unavailable");
}
await viewer.page.getByRole("button", { name: "Map", exact: true }).click();
await expect(viewer.page.locator("#request-map")).toBeVisible();
await expect(viewer.page.locator("#request-results-list")).toBeHidden();
await viewer.page.getByRole("button", { name: "List", exact: true }).click();
await expect(viewer.page.locator("#request-results-list")).toBeVisible();
await expect(viewer.page.locator("#request-map")).toBeHidden();
await viewer.page.reload();
await expect(viewer.page.getByRole("button", { name: "List", exact: true })).toHaveAttribute(
"aria-pressed",
"true",
);
await expect(viewer.page.getByText(berlinTitle)).toHaveCount(0);
assertRequesterClean();
assertViewerClean();
await requester.context.close();
await viewer.context.close();
});