Files
next-tjwater-frontend/tests/browser/scheduled-condition-acrylic.e2e.ts
T

127 lines
4.9 KiB
TypeScript

import { expect, test, type Locator } from "playwright/test";
test("scheduled conditions keep acrylic blur outside transformed ancestors", async ({ page }) => {
await page.goto("/", { waitUntil: "domcontentloaded" });
const panel = page.getByRole("region", { name: "工况任务", exact: true });
await expect(panel).toBeVisible();
await page.waitForTimeout(250);
await expectAcrylicComposition(panel);
await expect(panel).toHaveCSS("width", "432px");
const timeline = panel.getByTestId("scheduled-condition-timeline");
const collapsedPanelBox = await panel.boundingBox();
const collapsedTimelineBox = await timeline.boundingBox();
expect(collapsedPanelBox).not.toBeNull();
expect(collapsedTimelineBox).not.toBeNull();
await panel.getByRole("button", { name: "展开工况任务" }).click();
await page.waitForTimeout(250);
await expectAcrylicComposition(panel);
await expect(panel).toHaveCSS("width", "880px");
const expandedPanelBox = await panel.boundingBox();
const expandedTimelineBox = await timeline.boundingBox();
expect(expandedPanelBox).not.toBeNull();
expect(expandedTimelineBox).not.toBeNull();
expect(Math.round(expandedPanelBox!.x + expandedPanelBox!.width)).toBe(
Math.round(collapsedPanelBox!.x + collapsedPanelBox!.width)
);
expect(Math.round(expandedTimelineBox!.width)).toBe(
Math.round(collapsedTimelineBox!.width)
);
expect(Math.round(expandedTimelineBox!.x + expandedTimelineBox!.width)).toBe(
Math.round(collapsedTimelineBox!.x + collapsedTimelineBox!.width)
);
await panel.getByRole("button", { name: "收起工况任务" }).click();
await page.waitForTimeout(250);
await expect(panel).toHaveCSS("width", "432px");
const restoredTimelineBox = await timeline.boundingBox();
expect(restoredTimelineBox).not.toBeNull();
expect(Math.round(restoredTimelineBox!.width)).toBe(
Math.round(collapsedTimelineBox!.width)
);
});
test("narrow desktop keeps Agent and expanded conditions from overlapping", async ({ page }) => {
await page.setViewportSize({ width: 1024, height: 768 });
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByRole("button", { name: "工况任务", exact: true }).click();
const panel = page.getByRole("region", { name: "工况任务", exact: true });
const agentPanel = page.locator('aside[aria-label="Agent 命令面板"]');
const resizeHandle = page.getByRole("separator", { name: "调整 Agent 面板宽度" });
await resizeHandle.focus();
await page.keyboard.press("End");
await expect(agentPanel).toHaveCSS("width", "484px");
const compactAgentBox = await agentPanel.boundingBox();
const compactConditionBox = await panel.boundingBox();
expect(compactAgentBox).not.toBeNull();
expect(compactConditionBox).not.toBeNull();
expect(compactConditionBox!.x - (compactAgentBox!.x + compactAgentBox!.width)).toBeGreaterThanOrEqual(
24
);
await panel.getByRole("button", { name: "展开工况任务" }).click();
await expect(page.locator('aside[aria-label="Agent 折叠栏"]')).toBeVisible();
await expect(panel).toHaveCSS("width", "852px");
const expandedConditionBox = await panel.boundingBox();
const collapsedAgentBox = await page
.locator('aside[aria-label="Agent 折叠栏"]')
.boundingBox();
expect(expandedConditionBox).not.toBeNull();
expect(collapsedAgentBox).not.toBeNull();
expect(
expandedConditionBox!.x - (collapsedAgentBox!.x + collapsedAgentBox!.width)
).toBeGreaterThanOrEqual(24);
await panel.getByRole("button", { name: "收起工况任务" }).click();
await expect(agentPanel).toBeVisible();
});
async function expectAcrylicComposition(panel: Locator) {
const composition = await panel.evaluate((element) => {
const rootStyle = getComputedStyle(element);
const blockingAncestors: string[] = [];
const filteredDescendants: string[] = [];
let ancestor = element.parentElement;
while (ancestor && ancestor.tagName !== "MAIN") {
const style = getComputedStyle(ancestor);
if (
style.transform !== "none" ||
style.filter !== "none" ||
style.opacity !== "1" ||
style.isolation !== "auto" ||
style.willChange.includes("transform")
) {
blockingAncestors.push(ancestor.className);
}
ancestor = ancestor.parentElement;
}
for (const descendant of element.querySelectorAll("*")) {
if (getComputedStyle(descendant).backdropFilter !== "none") {
filteredDescendants.push(descendant.className);
}
}
return {
backdropFilter: rootStyle.backdropFilter,
blockingAncestors,
filteredDescendants,
transform: rootStyle.transform,
willChange: rootStyle.willChange
};
});
expect(composition.backdropFilter).toContain("blur(");
expect(composition.blockingAncestors).toEqual([]);
expect(composition.filteredDescendants).toEqual([]);
expect(composition.transform).toBe("none");
expect(composition.willChange).toBe("auto");
}