fix: stabilize agent progress display
This commit is contained in:
@@ -7,6 +7,7 @@ const STREAM_CHUNK_DELAY_MS = 20;
|
||||
|
||||
let streamServer: Server;
|
||||
let streamServerUrl: string;
|
||||
let appendProgress: (() => void) | null = null;
|
||||
let failProgress: (() => void) | null = null;
|
||||
let releaseStream: (() => void) | null = null;
|
||||
|
||||
@@ -121,18 +122,20 @@ test.beforeAll(async () => {
|
||||
while (index < 3 && index < chunks.length) {
|
||||
sendNextTextChunk();
|
||||
}
|
||||
send({
|
||||
type: "data-progress",
|
||||
id: "assess-risk",
|
||||
data: {
|
||||
appendProgress = () => {
|
||||
send({
|
||||
type: "data-progress",
|
||||
id: "assess-risk",
|
||||
phase: "analysis",
|
||||
status: "running",
|
||||
title: "正在判断溢流风险",
|
||||
detail: "结合流量突变与液位趋势形成判断。",
|
||||
started_at: Date.now()
|
||||
}
|
||||
});
|
||||
data: {
|
||||
id: "assess-risk",
|
||||
phase: "analysis",
|
||||
status: "running",
|
||||
title: "正在判断溢流风险",
|
||||
detail: "结合流量突变与液位趋势形成判断。",
|
||||
started_at: Date.now()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
failProgress = () => {
|
||||
send({
|
||||
@@ -262,14 +265,65 @@ test("stream completion and the plan card remain positionally stable", async ({
|
||||
|
||||
await sendButton.click();
|
||||
const liveProgress = page.getByRole("list", { name: "最近执行进度" });
|
||||
await expect(liveProgress.locator("li")).toHaveCount(3);
|
||||
await expect(liveProgress.getByText("正在分析运行上下文", { exact: true })).toBeVisible();
|
||||
|
||||
await page.evaluate(() => {
|
||||
const state = window as typeof window & {
|
||||
__agentMinVisibleProgressRows?: number;
|
||||
__agentProgressWindowSampleDone?: boolean;
|
||||
};
|
||||
const startedAt = performance.now();
|
||||
state.__agentMinVisibleProgressRows = Number.POSITIVE_INFINITY;
|
||||
state.__agentProgressWindowSampleDone = false;
|
||||
|
||||
const sample = () => {
|
||||
const rows = document.querySelectorAll('ol[aria-label="最近执行进度"] > li').length;
|
||||
state.__agentMinVisibleProgressRows = Math.min(state.__agentMinVisibleProgressRows ?? rows, rows);
|
||||
if (performance.now() - startedAt < 400) {
|
||||
requestAnimationFrame(sample);
|
||||
} else {
|
||||
state.__agentProgressWindowSampleDone = true;
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(sample);
|
||||
});
|
||||
triggerProgressAppend();
|
||||
await expect(liveProgress.getByText("正在判断溢流风险", { exact: true })).toBeVisible();
|
||||
await expect(liveProgress.locator("li")).toHaveCount(3);
|
||||
await expect(liveProgress.getByText("正在分析运行上下文", { exact: true })).toHaveCount(0);
|
||||
await expect.poll(() =>
|
||||
page.evaluate(() =>
|
||||
(window as typeof window & { __agentProgressWindowSampleDone?: boolean }).__agentProgressWindowSampleDone ?? false
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
await page.evaluate(() =>
|
||||
(window as typeof window & { __agentMinVisibleProgressRows?: number }).__agentMinVisibleProgressRows
|
||||
)
|
||||
).toBeGreaterThanOrEqual(3);
|
||||
|
||||
const liveProgressRowHeights = await liveProgress.locator("li").evaluateAll((rows) =>
|
||||
rows.map((row) => row.getBoundingClientRect().height)
|
||||
);
|
||||
expect(liveProgressRowHeights.every((height) => Math.abs(height - 48) <= 0.01)).toBe(true);
|
||||
await expect(liveProgress.locator("li").first().locator("span.min-w-0 > span").first()).toHaveCSS(
|
||||
"white-space",
|
||||
"nowrap"
|
||||
);
|
||||
const progressToggle = page.getByRole("button", { name: /执行进度/ }).filter({ visible: true }).first();
|
||||
await expect(progressToggle).toBeEnabled();
|
||||
await progressToggle.click();
|
||||
const expandedLiveProgress = page.getByRole("list", { name: "全部执行进度" });
|
||||
await expect(expandedLiveProgress.locator("li")).toHaveCount(4);
|
||||
await expect(expandedLiveProgress.getByText("正在分析运行上下文", { exact: true })).toBeVisible();
|
||||
await expect(expandedLiveProgress.getByText("正在核对降雨过程与汇水区响应关系", { exact: true })).toHaveCSS(
|
||||
"white-space",
|
||||
"normal"
|
||||
);
|
||||
await progressToggle.click();
|
||||
await expect(page.getByRole("list", { name: "最近执行进度" }).locator("li")).toHaveCount(3);
|
||||
|
||||
await page.evaluate(() => {
|
||||
const state = window as typeof window & { __agentFailureMotionObserved?: boolean };
|
||||
@@ -300,7 +354,6 @@ test("stream completion and the plan card remain positionally stable", async ({
|
||||
await expect(page.getByText("分析完成", { exact: true }).filter({ visible: true }).first()).toBeVisible({
|
||||
timeout: 10_000
|
||||
});
|
||||
const progressToggle = page.getByRole("button", { name: /执行进度/ }).filter({ visible: true }).first();
|
||||
await expect(progressToggle).toContainText("共 4 条");
|
||||
await expect(page.getByRole("list", { name: "最近执行进度" })).toHaveCount(0);
|
||||
await expect(page.getByText("溢流风险判断完成", { exact: true }).filter({ visible: true })).toHaveCount(0);
|
||||
@@ -358,8 +411,32 @@ test("stream completion and the plan card remain positionally stable", async ({
|
||||
).toBeLessThanOrEqual(2);
|
||||
|
||||
await progressToggle.click();
|
||||
await expect(page.getByRole("list", { name: "全部执行进度" }).locator("li")).toHaveCount(4);
|
||||
const expandedProgress = page.getByRole("list", { name: "全部执行进度" });
|
||||
await expect(expandedProgress.locator("li")).toHaveCount(4);
|
||||
await expect(page.getByText("正在分析运行上下文", { exact: true }).filter({ visible: true }).first()).toBeVisible();
|
||||
const expandedLongTitle = expandedProgress.getByText("正在核对降雨过程与汇水区响应关系", { exact: true });
|
||||
await expect(expandedLongTitle).toHaveCSS("white-space", "normal");
|
||||
await expect(expandedProgress.locator("li").nth(1)).not.toHaveCSS("height", "48px");
|
||||
|
||||
await progressToggle.click();
|
||||
await prompt.fill("验证展开状态在流结束后保持");
|
||||
await sendButton.click();
|
||||
|
||||
const latestProgressToggle = page.getByRole("button", { name: /执行进度/ }).filter({ visible: true }).last();
|
||||
await expect(latestProgressToggle).toContainText("最近 3 条");
|
||||
triggerProgressAppend();
|
||||
await expect(
|
||||
page.getByRole("list", { name: "最近执行进度" }).getByText("正在判断溢流风险", { exact: true })
|
||||
).toBeVisible();
|
||||
await latestProgressToggle.click();
|
||||
await expect(latestProgressToggle).toContainText("全部 4 条");
|
||||
resumeStream();
|
||||
|
||||
await expect(latestProgressToggle).toContainText("全部 4 条", { timeout: 10_000 });
|
||||
await expect(page.getByRole("list", { name: "全部执行进度" })).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("list", { name: "全部执行进度" }).getByText("溢流风险判断完成", { exact: true })
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
function createLongMarkdownResponse() {
|
||||
@@ -393,6 +470,16 @@ function resumeStream() {
|
||||
resume();
|
||||
}
|
||||
|
||||
function triggerProgressAppend() {
|
||||
if (!appendProgress) {
|
||||
throw new Error("Progress append checkpoint was not reached");
|
||||
}
|
||||
|
||||
const append = appendProgress;
|
||||
appendProgress = null;
|
||||
append();
|
||||
}
|
||||
|
||||
function triggerProgressFailure() {
|
||||
if (!failProgress) {
|
||||
throw new Error("Progress failure checkpoint was not reached");
|
||||
|
||||
Reference in New Issue
Block a user