66 lines
3.4 KiB
TypeScript
66 lines
3.4 KiB
TypeScript
/** 真实浏览器和隔离库:生成正文任务的创作对话、候选检查与失败候选不能采纳。 */
|
||
import { readFileSync } from "node:fs";
|
||
import { expect, test } from "@playwright/test";
|
||
|
||
test.use({ trace: "off" });
|
||
|
||
test("NC-browser-generation-dialog:创作对话、独立检查与采纳阻断", async ({
|
||
page,
|
||
}, info) => {
|
||
if (!process.env.MUSE_WORKBENCH_URL || !process.env.MUSE_AUTHOR_PASSWORD_FILE)
|
||
throw new Error("需要明确的隔离后端和作者口令文件。");
|
||
const goodTaskId = process.env.MUSE_GEN_TASK_ID;
|
||
const failedTaskId = process.env.MUSE_GEN_FAILED_TASK_ID;
|
||
if (!goodTaskId || !failedTaskId)
|
||
throw new Error("需要已跑完的通过任务与失败候选任务编号。");
|
||
const consoleErrors: string[] = [];
|
||
page.on("pageerror", (error) => consoleErrors.push(String(error)));
|
||
|
||
await page.goto("/");
|
||
await page
|
||
.getByLabel("访问口令")
|
||
.fill(readFileSync(process.env.MUSE_AUTHOR_PASSWORD_FILE, "utf8").trim());
|
||
await page.getByRole("button", { name: "进入工作台" }).click();
|
||
await page.getByRole("link", { name: /任务记录/ }).waitFor();
|
||
page.on("console", (message) => {
|
||
if (message.type() === "error" && !/favicon/.test(message.text()))
|
||
consoleErrors.push(message.text());
|
||
});
|
||
|
||
await page.goto("/tasks");
|
||
await page.getByLabel("任务编号").fill(goodTaskId);
|
||
await page.getByRole("button", { name: "查看任务" }).click();
|
||
const 对话 = page.locator('section[aria-label="创作对话"]');
|
||
await expect(对话).toBeVisible();
|
||
// 流式正文与过程事件可见。
|
||
await expect(对话.getByText("雨点敲着铁皮屋顶,林深把信压在掌心。")).toBeVisible();
|
||
await expect(对话.getByText("候选已保存")).toBeVisible();
|
||
// 独立检查报告:基础项全过、连续性无发现;采纳入口开放。
|
||
const 动作 = page.locator('section[aria-label="候选检查与决定"]');
|
||
await expect(动作.getByText("通过", { exact: true }).first()).toBeVisible();
|
||
await expect(动作.getByText("连续性检查没有发现问题。")).toBeVisible();
|
||
await expect(
|
||
动作.getByRole("button", { name: "采纳为正文新版本" }),
|
||
).toBeEnabled();
|
||
|
||
await page.screenshot({ path: `${info.outputDir}/生成任务与候选检查.png`, fullPage: true });
|
||
|
||
// 失败候选:复读细纲措辞 → 冲突呈现且采纳被服务端阻断(错误经作者决定面板呈现)。
|
||
await page.goto("/tasks");
|
||
await page.getByLabel("任务编号").fill(failedTaskId);
|
||
await page.getByRole("button", { name: "查看任务" }).click();
|
||
const 失败动作 = page.locator('section[aria-label="候选检查与决定"]');
|
||
await expect(失败动作).toBeVisible();
|
||
await expect(失败动作.getByText(/复读了细纲措辞/)).toBeVisible();
|
||
await expect(失败动作.getByText("未通过").first()).toBeVisible();
|
||
await 失败动作.getByRole("button", { name: "采纳为正文新版本" }).click();
|
||
await expect(失败动作.locator("p[role=\"alert\"]")).toContainText(/必需检查未通过/);
|
||
// 上一次点击的服务端拒绝(CHECK_FAILED)会以 422 响应返回,浏览器控制台把它记为资源错误;
|
||
// 拒绝本身正是上一行断言钉住的行为,故按 W14 同样的噪声排除纪律只排除这一条。
|
||
expect(
|
||
consoleErrors.filter((文本) => !文本.includes("status of 422")),
|
||
"页面不得出现预期外的控制台错误",
|
||
).toEqual([]);
|
||
}
|
||
);
|