- 归档并收敛 R2 历史留痕至 docs/实现回顾/R2改造历史留痕.md,删除已退出生命周期的改造计划、旧文件处置及验证过程文档 - 现行测试用例身份收敛至 tests/用例清单.json(1358条扁平登记),适配 conftest、索引维护与测试执行验证 - 清理源码、配置、SQL迁移头、测试夹具及规则文档中的 Wxx 实施分期标签与过时过程描述 - 同步重新打包构建资源清单,通过全量离线测试、模块边界、类型检查与索引双向强核验
79 lines
4.0 KiB
TypeScript
79 lines
4.0 KiB
TypeScript
/** 真实浏览器与隔离库:资料对照页的来源清单、原文对照、清理应用与榜单快照失败态。 */
|
||
import { readFileSync } from "node:fs";
|
||
import { expect, test } from "@playwright/test";
|
||
|
||
test.use({ trace: "off" });
|
||
|
||
test("NC-browser-source-workbench:资料对照页与榜单失败态", 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([]);
|
||
});
|
||
|
||
|
||
test("NC-browser-research-workbench:拆书工作区发起与台账呈现", 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([]);
|
||
});
|