muse-agent-example/web/tests/旅程/资料对照.spec.ts
zizi ae02fd1732 前端:工作台页面、事件标签与旅程用例
- 上下文清单、任务列表与详情、恢复控制、运行观察、创作对话与消息流、正式变更决策面板、正文写作与候选审阅、资料研究等页面同步本轮后端能力。
- 事件标签表补齐后端事件类型;查询键与生成客户端随 HTTP 契约重新生成。
- 依赖调整后 lockfile 同步;交互用例与浏览器旅程 spec 一并更新。
- 证据:make 前端检查(lint + typecheck + Pi 工具桥 tsc)exit 0;make 前端测试 37 文件 / 120 用例通过。
2026-09-18 01:15:07 +08:00

81 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 真实浏览器与隔离库:资料对照页的来源清单、原文对照、清理应用与榜单快照失败态。 */
import { readFileSync } from "node:fs";
import { expect, test } from "@playwright/test";
test.use({ trace: "off" });
// @muse-case {"case_id":"NC-w17-browser","environment":"真实隔离库 + Chrome","given":"隔离浏览器环境与预置来源/快照","when":"打开资料对照页并应用清理、展开榜单快照","then":["来源与原文对照可见","清理说明可见","失败快照如实呈现"],"contract":"docs/系统架构/新版设计/模块设计/B03-资料研究.md"}
test("NC-w17-browser:资料对照页与榜单失败态", async ({ page }, info) => {
if (!process.env.MUSE_WORKBENCH_URL || !process.env.MUSE_AUTHOR_PASSWORD_FILE)
throw new Error("需要明确的隔离后端和作者口令文件。");
const sourceId = process.env.MUSE_SOURCE_ID!;
if (!sourceId) 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: /资料研究/ }).click();
// 来源清单可见并点开预置来源。
const 清单 = page.locator('section[aria-label="来源清单"]');
await expect(清单.getByText("样章:码头来信")).toBeVisible();
await 清单.getByRole("button", { name: /样章:码头来信/ }).click();
// 原文与清理对照:噪声原文可见;应用清理后对照说明出现且原文不动。
const 对照 = page.locator('section[aria-label="原文与清理对照"]');
await expect(对照.getByText("最新章节请访问 example.com")).toBeVisible();
await 对照.getByRole("button", { name: "生成并应用清理对照" }).click();
await expect(对照.getByText("清理已应用为对照版本;原文保持不变。")).toBeVisible();
await expect(对照.getByText("最新章节请访问 example.com")).toBeVisible();
// 榜单快照独立页面:失败态如实呈现,成功快照带条目数。
await page.goto("/rankings");
await page.getByLabel("榜单编号").fill("rank-demo");
await page.getByRole("button", { name: "查看快照" }).click();
const 榜单 = page.locator('section[aria-label="榜单快照"]');
await expect(榜单.getByText(/采集失败:上游 503/)).toBeVisible();
await expect(榜单.getByText(/2 条 · /).first()).toBeVisible();
await page.screenshot({ path: `${info.outputDir}/榜单与选题页.png`, fullPage: true });
expect(
consoleErrors.filter((文本) => !文本.includes("favicon")),
"页面不得出现控制台错误",
).toEqual([]);
});
// @muse-case {"case_id":"NC-w18-browser","environment":"真实隔离库 + Chrome","given":"隔离浏览器环境与预置来源","when":"打开拆书工作区并按选书理由发起拆解","then":["台账条目出现","进度与失败如实呈现"],"contract":"docs/系统架构/新版设计/模块设计/B03-资料研究.md"}
test("NC-w18-browser:拆书工作区发起与台账呈现", async ({ page }, info) => {
if (!process.env.MUSE_WORKBENCH_URL || !process.env.MUSE_AUTHOR_PASSWORD_FILE)
throw new Error("需要明确的隔离后端和作者口令文件。");
const sourceId = process.env.MUSE_SOURCE_ID!;
if (!sourceId) 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.goto("/research");
await page.getByRole("button", { name: /样章:码头来信/ }).click();
await page.getByLabel("选书理由(写入拆书依据)").fill("题材接近,节奏可借鉴");
await page.getByRole("button", { name: "发起拆解" }).click();
// 部署是否装配研究流程都如实呈现:成功给任务编号,未装配给明确错误;不伪造进度。
await expect(page.locator('p[role="status"]')).toBeVisible({ timeout: 15_000 });
const 台账 = page.locator('section[aria-label="拆书台账"]');
await expect(台账.getByText(/次拆解/)).toBeVisible();
await page.screenshot({ path: `${info.outputDir}/拆书工作区.png`, fullPage: true });
expect(
consoleErrors.filter((文本) => !文本.includes("favicon")),
"页面不得出现控制台错误",
).toEqual([]);
});