fix: complete agent question interactions
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
|
||||
test("submits a custom answer with the actionable id after a later tool placeholder", async ({
|
||||
page
|
||||
}) => {
|
||||
const replies: Array<{ pathname: string; body: unknown }> = [];
|
||||
await mockQuestionApi(page, replies);
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
|
||||
const prompt = page.getByPlaceholder(/输入调度问题/).filter({ visible: true }).first();
|
||||
await prompt.fill("测试 question 自定义回答");
|
||||
await page
|
||||
.getByRole("button", { name: "发送 Agent 指令" })
|
||||
.filter({ visible: true })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
const panel = page.locator('aside[aria-label="Agent 命令面板"]').filter({ visible: true });
|
||||
await panel.getByRole("radio", { name: "自定义回答" }).click();
|
||||
await panel.getByPlaceholder("输入自定义回答").fill("分析高峰时段压力");
|
||||
await panel.getByRole("button", { name: "提交回答" }).click();
|
||||
|
||||
await expect.poll(() => replies).toEqual([
|
||||
{
|
||||
pathname: "/api/v1/agent/chat/question/question-1/reply",
|
||||
body: {
|
||||
session_id: "question-session",
|
||||
answers: [["分析高峰时段压力"]]
|
||||
}
|
||||
}
|
||||
]);
|
||||
await expect(panel.getByText("已回答", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("button", { name: "提交回答" })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("keeps the custom answer control within a 375px Agent sheet", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 812 });
|
||||
await mockQuestionApi(page, []);
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "打开 Agent 面板" }).click();
|
||||
await page.getByRole("button", { name: /Agent 工作台抽屉高度/ }).click();
|
||||
|
||||
const panel = page.locator('aside[aria-label="Agent 命令面板"]').filter({ visible: true });
|
||||
const prompt = panel.getByPlaceholder(/输入调度问题/);
|
||||
await prompt.fill("测试窄屏 question");
|
||||
await panel.getByRole("button", { name: "发送 Agent 指令" }).click();
|
||||
await panel.getByRole("radio", { name: "自定义回答" }).click();
|
||||
|
||||
const textarea = panel.getByPlaceholder("输入自定义回答");
|
||||
await expect(textarea).toBeVisible();
|
||||
const box = await textarea.boundingBox();
|
||||
expect(box).not.toBeNull();
|
||||
expect(box!.x).toBeGreaterThanOrEqual(0);
|
||||
expect(box!.x + box!.width).toBeLessThanOrEqual(375);
|
||||
});
|
||||
|
||||
async function mockQuestionApi(
|
||||
page: Page,
|
||||
replies: Array<{ pathname: string; body: unknown }>
|
||||
) {
|
||||
await page.route("**/api/v1/agent/chat/**", async (route) => {
|
||||
const request = route.request();
|
||||
const pathname = new URL(request.url()).pathname;
|
||||
|
||||
if (pathname.endsWith("/stream")) {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
headers: {
|
||||
"Cache-Control": "no-cache",
|
||||
"Content-Type": "text/event-stream",
|
||||
"X-Vercel-AI-UI-Message-Stream": "v1"
|
||||
},
|
||||
body: createQuestionStream()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathname.endsWith("/question/question-1/reply")) {
|
||||
replies.push({
|
||||
pathname,
|
||||
body: request.postDataJSON()
|
||||
});
|
||||
await route.fulfill({ json: {} });
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathname.endsWith("/models")) {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
default_model: "test/model",
|
||||
models: [
|
||||
{
|
||||
id: "test/model",
|
||||
label: "测试模型",
|
||||
description: "Question 交互测试",
|
||||
icon: "bolt"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathname.endsWith("/sessions")) {
|
||||
await route.fulfill({ json: { sessions: [] } });
|
||||
return;
|
||||
}
|
||||
|
||||
await route.fulfill({ json: {} });
|
||||
});
|
||||
}
|
||||
|
||||
function createQuestionStream() {
|
||||
const question = {
|
||||
session_id: "question-session",
|
||||
questions: [
|
||||
{
|
||||
header: "分析范围",
|
||||
question: "你想分析哪一部分?",
|
||||
options: [
|
||||
{
|
||||
label: "雨污混接分析",
|
||||
description: "检查混接问题"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
tool: {
|
||||
messageID: "assistant-question",
|
||||
callID: "call-1"
|
||||
}
|
||||
};
|
||||
const parts = [
|
||||
{ type: "start", messageId: "assistant-question" },
|
||||
{ type: "text-start", id: "answer" },
|
||||
{ type: "text-delta", id: "answer", delta: "请选择分析范围。" },
|
||||
{
|
||||
type: "data-question_request",
|
||||
id: "question-1",
|
||||
data: {
|
||||
...question,
|
||||
request_id: "question-1",
|
||||
created_at: 100
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "data-question_request",
|
||||
id: "call-1",
|
||||
data: {
|
||||
...question,
|
||||
request_id: "call-1",
|
||||
created_at: 120
|
||||
}
|
||||
},
|
||||
{ type: "text-end", id: "answer" },
|
||||
{ type: "finish", finishReason: "stop" }
|
||||
];
|
||||
|
||||
return parts.map((part) => `data: ${JSON.stringify(part)}\n\n`).join("");
|
||||
}
|
||||
Reference in New Issue
Block a user