- 上下文清单、任务列表与详情、恢复控制、运行观察、创作对话与消息流、正式变更决策面板、正文写作与候选审阅、资料研究等页面同步本轮后端能力。 - 事件标签表补齐后端事件类型;查询键与生成客户端随 HTTP 契约重新生成。 - 依赖调整后 lockfile 同步;交互用例与浏览器旅程 spec 一并更新。 - 证据:make 前端检查(lint + typecheck + Pi 工具桥 tsc)exit 0;make 前端测试 37 文件 / 120 用例通过。
39 lines
2.7 KiB
TypeScript
39 lines
2.7 KiB
TypeScript
import { readFileSync } from "node:fs";
|
||
import { expect, test } from "@playwright/test";
|
||
|
||
// @muse-case {"case_id":"NC-browser-task-execution","environment":"浏览器","given":"显式作者、隔离配置、合成数据与已知发布构建","when":"经真实维护、业务或浏览器入口执行并读取持久结果","then":["NC-browser-task-execution:批准额度后单步执行到真实候选"],"contract":"docs/系统架构/新版设计/模块设计/S02-任务运行.md"}
|
||
test("NC-browser-task-execution:批准额度后单步执行到真实候选", async ({ page }, info) => {
|
||
const file = process.env.MUSE_AUTHOR_PASSWORD_FILE;
|
||
const taskId = process.env.MUSE_EXECUTION_TASK_ID;
|
||
if (!file || !taskId) throw new Error("需要隔离口令及具名任务身份");
|
||
await page.goto(`/tasks?task=${taskId}`);
|
||
await page.getByLabel("访问口令").fill(readFileSync(file,"utf8").trim());
|
||
await page.getByRole("button",{name:"进入工作台"}).click();
|
||
await page.goto(`/tasks?task=${taskId}`);
|
||
const budget = page.getByRole("region",{name:"模型调用预算"});
|
||
await expect(budget.getByText(/尚未批准模型额度/)).toBeVisible();
|
||
await budget.getByLabel("总上限(USD)",{exact:true}).fill("10");
|
||
// 对应隔离测试已登记账户;这不是生产默认费用建议。
|
||
const date = new Date(Date.now()+10*60*1000);
|
||
const local = new Date(date.getTime()-date.getTimezoneOffset()*60000).toISOString().slice(0,16);
|
||
await budget.getByLabel("批准截止时间",{exact:true}).fill(local);
|
||
await budget.getByLabel("最多调用次数",{exact:true}).fill("8");
|
||
await budget.getByLabel("单次上限(USD)",{exact:true}).fill("1");
|
||
await budget.getByRole("button",{name:"批准本任务额度"}).click();
|
||
await expect(budget.getByText(/已批准上限:USD 10/)).toBeVisible();
|
||
await page.reload();
|
||
await expect(budget.getByText(/已批准上限:USD 10/)).toBeVisible();
|
||
await expect(budget.getByRole("button",{name:"批准本任务额度"})).toHaveCount(0);
|
||
for (let i=0;i<5;i++) {
|
||
const response = page.waitForResponse(r=>r.url().includes(`/tasks/${taskId}/advance`) && r.request().method()==="POST");
|
||
await page.getByRole("button",{name:"执行下一步",exact:true}).click();
|
||
const step = await response;
|
||
expect(step.status()).toBe(200);
|
||
expect((await step.json()).executed_step).not.toBeNull();
|
||
if (i<4) await expect(page.getByRole("button",{name:"执行下一步",exact:true})).toBeEnabled();
|
||
}
|
||
await expect(page.getByRole("button",{name:"执行下一步",exact:true})).toHaveCount(0);
|
||
await expect(page.getByText("已完成",{exact:true}).first()).toBeVisible();
|
||
await page.screenshot({path:info.outputPath("任务额度与完成.png"),fullPage:true});
|
||
});
|