Files
next-tjwater-frontend/tests/browser/notice-dev-tools.e2e.ts
T

90 lines
5.7 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { mockInvestigationPresentation } from "./support/mock-investigation-presentation";
test.beforeEach(async ({ page }) => {
await mockInvestigationPresentation(page, []);
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.waitForFunction(() => Boolean(window.__waterNetworkMap?.getLayer("scada-pressure-hit")));
await page.getByRole("button", { name: "切换地图 Dev Panel" }).click();
await page.getByTestId("map-dev-panel").getByRole("tab", { name: "通知测试" }).click();
});
test("Dev previews all five tones, transient expiry and loading completion", async ({ page }, testInfo) => {
const panel = page.getByTestId("map-dev-panel");
for (const label of ["信息", "成功", "警告", "错误", "加载"]) {
await panel.getByRole("button", { name: `测试${label}通知` }).click();
}
const loading = page.locator("[data-sonner-toast]").filter({ hasText: "正在加载管网 · 测试" });
await expect(loading).toBeVisible();
await expect(loading.getByRole("button", { name: "关闭通知" })).toHaveCount(0);
await expect(loading).toHaveCSS("opacity", "1");
await testInfo.attach("notice-tones", { body: await page.screenshot({ path: testInfo.outputPath("tones.png") }), contentType: "image/png" });
await panel.getByRole("button", { name: "模拟加载完成" }).click();
await expect(page.locator("[data-sonner-toast]").filter({ hasText: "管网加载完成 · 测试" })).toBeVisible();
await page.mouse.move(5, 5);
await expect(page.locator("[data-sonner-toast]").filter({ hasText: "管网加载完成 · 测试" })).toHaveCount(0, { timeout: 6000 });
await expect(page.locator("[data-sonner-toast]").filter({ hasText: "地图视图已更新 · 测试" })).toHaveCount(0);
await expect(page.locator("[data-sonner-toast]").filter({ hasText: "部分监测数据延迟 · 测试" })).toBeVisible();
await panel.getByRole("button", { name: "清除测试通知" }).click();
await expect(page.locator("[data-sonner-toast]").filter({ hasText: "· 测试" })).toHaveCount(0);
});
for (const width of [1280, 375, 320]) {
test(`linked notices survive timeout and navigation, wrap and close independently at ${width}px`, async ({ page }, testInfo) => {
const panel = page.getByTestId("map-dev-panel");
await panel.getByRole("button", { name: "测试报告通知" }).click();
await panel.getByRole("button", { name: "测试任务通知" }).click();
await panel.getByRole("button", { name: "测试长文本通知" }).click();
const notices = page.locator("[data-sonner-toast]").filter({ hasText: "保留至手动关闭" });
await expect(notices).toHaveCount(3);
await notices.filter({ hasText: "新收到一项" }).getByRole("button", { name: "查看任务" }).click();
await expect(panel.getByRole("status")).toHaveText("已触发“查看任务”测试操作,通知仍保留。");
await notices.filter({ hasText: "城南片区" }).getByRole("button", { name: "查看报告" }).click();
await expect(panel.getByRole("status")).toHaveText("已触发“查看报告”测试操作,通知仍保留。");
await page.getByRole("button", { name: "关闭 Dev Panel" }).click();
await page.setViewportSize({ width, height: 900 });
await page.mouse.move(5, 5);
await page.clock.install();
await page.clock.fastForward(15_000);
await expect(notices).toHaveCount(3);
for (const notice of await notices.all()) {
await expect(notice).toBeInViewport();
expect(await notice.evaluate((element) => ({
overflow: element.scrollWidth > element.clientWidth,
left: element.getBoundingClientRect().left,
right: element.getBoundingClientRect().right <= innerWidth
}))).toEqual({ overflow: false, left: expect.any(Number), right: true });
const close = notice.getByRole("button", { name: "关闭通知" });
await expect.poll(() => close.evaluate((element) => {
const rect = element.getBoundingClientRect();
return element.contains(document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2));
})).toBe(true);
}
await testInfo.attach(`linked-notices-${width}`, {
body: await page.screenshot({ path: testInfo.outputPath("notices.png") }), contentType: "image/png"
});
await notices.filter({ hasText: "新收到一项" }).getByRole("button", { name: "关闭通知" }).click();
await page.clock.runFor(250);
await expect(notices).toHaveCount(2);
await notices.filter({ hasText: "城南片区" }).getByRole("button", { name: "查看报告" }).click();
await expect(notices).toHaveCount(2);
});
}
test("closing retained notices reveals the remaining notices in the original stack", async ({ page }, testInfo) => {
const panel = page.getByTestId("map-dev-panel");
await panel.getByRole("button", { name: "连续 6 条通知" }).click();
const notices = page.locator("[data-sonner-toast]").filter({ hasText: "保留至手动关闭" });
await expect(notices).toHaveCount(6);
const oldest = notices.filter({ hasText: "第 1 条测试通知" });
await expect(oldest).toHaveAttribute("data-visible", "false");
await notices.first().getByRole("button", { name: "关闭通知" }).click();
await expect(notices).toHaveCount(5);
await notices.first().getByRole("button", { name: "关闭通知" }).click();
await expect(notices).toHaveCount(4);
await expect(oldest).toHaveAttribute("data-visible", "true");
await testInfo.attach("notice-original-stack", { body: await page.screenshot({ path: testInfo.outputPath("stack.png") }), contentType: "image/png" });
await panel.getByRole("button", { name: "清除测试通知" }).click();
await expect(notices).toHaveCount(0);
});