Files
next-tjwater-frontend/tests/browser/agent-select-menu.e2e.ts
T
jiang 85a9a3ab45 fix(ui): refine acrylic controls and timeline interactions
Restore full acrylic materials to stacked task cards and floating controls.
Extend the map behind the navigation header while preserving document and
control insets. Align timeline and scale readouts, refresh dense-marker
hover content, and highlight model and approval menu options.

Keep narrow timeline headers clear of their legend and actions. Update
coupled geometry checks and retain city zoom-12 and menu regression coverage.

Validation: scoped git diff --check and read-only UI geometry inspection.
Test suites were not rerun at the user's request.
2026-10-09 18:11:33 +08:00

96 lines
4.8 KiB
TypeScript

import { expect, test, type Locator } from "@playwright/test";
import { mockAgentApi } from "./support/mock-agent-api";
import { mockWorkbenchContext } from "./support/mock-workbench-context";
import { expectThemeColor } from "./support/theme-colors";
test.beforeEach(async ({ page }) => {
await page.emulateMedia({ reducedMotion: "reduce" });
await mockWorkbenchContext(page);
await mockAgentApi(page);
await page.route("**/api/v1/agent/chat/models", (route) => route.fulfill({
headers: { "Access-Control-Allow-Origin": "*" },
json: {
default_model: "test/fast",
models: [
{ id: "test/fast", label: "快速", description: "快速回答和日常任务处理", icon: "bolt" },
{ id: "test/expert", label: "专家", description: "深入分析和复杂任务处理", icon: "sparkle" }
]
}
}));
});
for (const width of [1440, 375]) {
test(`model options show hover and keyboard highlight without changing selection at ${width}px`, async ({ page }) => {
await page.setViewportSize({ width, height: 900 });
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByRole("button", { name: width < 1024 ? "打开 Agent 面板" : /展开 Agent 助手面板/ }).click();
// Radix hides the trigger from the accessibility tree while its modal menu is open.
const trigger = page.locator('button[aria-label="选择 Agent 模型"]');
await expect(trigger).toHaveAccessibleDescription("当前模型:快速");
await trigger.click();
await waitForMenuAnimations(page.getByRole("menu"));
const fast = page.getByRole("menuitem", { name: /快速回答和日常任务处理/ });
const expert = page.getByRole("menuitem", { name: /深入分析和复杂任务处理/ });
const box = await expert.boundingBox();
for (const item of [fast, expert]) {
await item.hover();
await expect(item).toHaveAttribute("data-highlighted", "");
await expectThemeColor(item, "background-color", "--action-selection-soft-hover");
await expectThemeColor(item, "border-color", "--action-border-hover");
await expect(trigger).toHaveAttribute("aria-description", "当前模型:快速");
}
expect(await expert.boundingBox()).toEqual(box);
await page.getByRole("menu").screenshot({ path: `test-results/agent-select-menu/model-${width}.png` });
await page.keyboard.press("ArrowUp");
await expect(fast).toBeFocused();
await expectThemeColor(fast, "background-color", "--action-selection-soft-hover");
await page.keyboard.press("ArrowDown");
await expect(expert).toBeFocused();
await page.keyboard.press("Enter");
await expect(page.getByRole("menu")).toHaveCount(0);
await expect(trigger).toHaveAccessibleDescription("当前模型:专家");
await expect(trigger).toBeFocused();
});
test(`approval options highlight both selected and unselected modes at ${width}px`, async ({ page }) => {
await page.setViewportSize({ width, height: 900 });
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByRole("button", { name: width < 1024 ? "打开 Agent 面板" : /展开 Agent 助手面板/ }).click();
const trigger = page.locator('button[aria-label="权限批准模式"]');
await trigger.click();
await waitForMenuAnimations(page.getByRole("menu"));
const request = page.getByRole("menuitem", { name: /工具权限逐次确认/ });
const always = page.getByRole("menuitem", { name: /自动允许本轮权限请求/ });
for (const item of [request, always]) {
await item.hover();
await expectThemeColor(item, "background-color", "--action-selection-soft-hover");
await expectThemeColor(item, "border-color", "--action-border-hover");
await expect(trigger).toContainText("请求批准");
}
await page.getByRole("menu").screenshot({ path: `test-results/agent-select-menu/approval-${width}.png` });
await always.click();
await expect(page.getByRole("menu")).toHaveCount(0);
await expect(trigger).toBeFocused();
await expect(trigger).toContainText("始终允许");
await trigger.click();
await waitForMenuAnimations(page.getByRole("menu"));
await always.hover();
await expectThemeColor(always, "background-color", "--action-selection-soft-hover");
await page.keyboard.press("ArrowUp");
await expect(request).toBeFocused();
await expectThemeColor(request, "background-color", "--action-selection-soft-hover");
await page.keyboard.press("Enter");
await expect(trigger).toContainText("请求批准");
await expect(trigger).toBeFocused();
});
}
async function waitForMenuAnimations(menu: Locator) {
await expect(menu).toBeVisible();
await menu.evaluate((element) => Promise.all(
element.getAnimations({ subtree: true })
.filter((animation) => animation.playState === "running")
.map((animation) => animation.finished.catch(() => undefined))
));
}