feat: add project-aware agent workspace
Generic Container CI/CD / test-build-publish (push) Successful in 2m9s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 2m39s

This commit is contained in:
2026-10-22 18:52:18 +08:00
parent c6a0e74e72
commit 2d8506fea0
191 changed files with 12373 additions and 3556 deletions
+19 -15
View File
@@ -79,22 +79,26 @@ test("证据提问在预览、展开及更多依据中使用统一实体按钮",
}
});
async function expectCenteredReference(panel: Locator) {
async function expectTaskReferenceLayout(panel: Locator) {
await expect(panel).toHaveAttribute("data-agent-starting", "true");
await expect(panel.getByRole("group", { name: "对话引用" })).toBeVisible();
await expect(panel.getByRole("group", { name: "推荐问题" })).toHaveCount(0);
await expect(panel.locator("form")).toHaveCount(1);
// Existing task state keeps the normal reading area, as required by agent-chat-ui-design.md.
const status = panel.getByRole("region", { name: "任务协作状态" });
await expect(status).toBeVisible();
await expect.poll(async () => {
const panelBox = (await panel.boundingBox())!;
const header = (await panel.locator("header").boundingBox())!;
const composer = (await panel.locator("form").boundingBox())!;
// The mobile header extends above the panel to cover the drawer handle.
const center = (header.y + header.height + panelBox.y + panelBox.height) / 2;
return Math.abs(composer.y + composer.height / 2 - center);
}).toBeLessThan(2);
return panelBox.y + panelBox.height - composer.y - composer.height;
}).toBeLessThan(32);
const statusBox = (await status.boundingBox())!;
const composerBox = (await panel.locator("form").boundingBox())!;
expect(composerBox.y).toBeGreaterThanOrEqual(statusBox.y + statusBox.height);
}
test("单一协作入口展示任务引用,保留草稿且仅手动发送,并适配窄屏", async ({ page }, testInfo) => {
test.setTimeout(60_000);
await page.emulateMedia({ reducedMotion: "reduce" });
await mockWorkbenchContext(page);
await mockAgentApi(page, { sessions: [{ session_id: "ordinary-main", title: "供水核查主聊天", purpose: "ordinary_chat", created_at: now, updated_at: now }] });
@@ -124,13 +128,13 @@ test("单一协作入口展示任务引用,保留草稿且仅手动发送,
const agent = page.getByRole("complementary", { name: "Agent 命令面板" });
await expect(agent.getByRole("heading", { name: "我已就绪,请描述任务" })).toHaveCount(0);
await agent.getByRole("button", { name: "打开 Agent 历史记录" }).click();
await agent.getByRole("button", { name: /供水核查主聊天/ }).click();
await page.getByRole("dialog", { name: "历史对话" }).getByRole("button", { name: /^供水核查主聊天/ }).click();
const prompt = agent.locator("textarea");
await prompt.fill("保留的现场补充草稿");
await page.getByRole("button", { name: "工况任务", exact: true }).click();
const feed = page.getByRole("region", { name: "工况任务", exact: true });
const expand = feed.getByRole("button", { name: "展开工况任务" });
if (await expand.isVisible()) await expand.click();
await expect(feed).toBeVisible();
await feed.getByRole("button", { name: "展开工况任务" }).click();
await feed.getByRole("button", { name: /调查任务/ }).click();
await feed.getByText("居民异味投诉调查", { exact: true }).first().click();
await expect(feed.getByText("16:00", { exact: true })).toBeVisible();
@@ -158,7 +162,7 @@ test("单一协作入口展示任务引用,保留草稿且仅手动发送,
await expect(prompt).toHaveValue("保留的现场补充草稿\n\n请解释“上游监测数据质量已核对”这条证据的范围、来源和判断影响。");
await expect(prompt).toBeFocused();
await expect(reference).toContainText("已引用证据");
await expectCenteredReference(agent);
await expectTaskReferenceLayout(agent);
expect(submitted).toBe(0);
await agent.screenshot({ path: testInfo.outputPath("investigation-reference-desktop.png") });
await feed.getByRole("button", { name: /定时任务/ }).click();
@@ -167,10 +171,10 @@ test("单一协作入口展示任务引用,保留草稿且仅手动发送,
const mobileAgent = page.getByRole("complementary", { name: "Agent 命令面板" });
await expect(mobileAgent.getByRole("heading", { name: "我已就绪,请描述任务" })).toHaveCount(0);
await expect(mobileAgent.getByRole("group", { name: "对话引用" })).toContainText("居民异味投诉调查");
await expectCenteredReference(mobileAgent);
await expectTaskReferenceLayout(mobileAgent);
await mobileAgent.screenshot({ path: testInfo.outputPath("investigation-reference-narrow.png") });
await page.setViewportSize({ width: 320, height: 900 });
await expectCenteredReference(mobileAgent);
await expectTaskReferenceLayout(mobileAgent);
await mobileAgent.screenshot({ path: testInfo.outputPath("investigation-reference-320.png") });
expect(await mobileAgent.evaluate((element) => element.scrollWidth <= element.clientWidth + 1)).toBe(true);
await page.setViewportSize({ width: 375, height: 900 });
@@ -194,10 +198,10 @@ test("单一协作入口展示任务引用,保留草稿且仅手动发送,
return panelBox.y + panelBox.height - composer.y - composer.height;
}).toBeLessThan(32);
await expect(mobileAgent.getByRole("button", { name: "停止 Agent 分析" })).toHaveCount(0);
await mobileAgent.getByRole("button", { name: "打开 Agent 历史记录" }).click();
await mobileAgent.getByRole("button", { name: /供水核查主聊天/ }).click();
await expect(mobileAgent.getByRole("group", { name: "对话引用" })).toHaveCount(0);
incoming = true;
await mobileAgent.getByRole("button", { name: "打开 Agent 历史记录" }).click();
await page.getByRole("dialog", { name: "历史对话" }).getByRole("button", { name: /^供水核查主聊天/ }).click();
await expect(mobileAgent.getByRole("group", { name: "对话引用" })).toHaveCount(0);
await expect(mobileAgent.getByText("已核对上游监测,请补充现场采样记录。")).toBeVisible();
await expect(mobileAgent.getByText("待接收", { exact: true })).toBeVisible();
await expect(mobileAgent.getByRole("button", { name: "停止 Agent 分析" })).toHaveCount(0);