126 lines
5.9 KiB
TypeScript
126 lines
5.9 KiB
TypeScript
/** 浏览器、安装后的真实后端与专用PG;候选由作者操作产生,不声称模型生成。 */
|
||
import { readFileSync } from "node:fs";
|
||
import { expect, test } from "@playwright/test";
|
||
|
||
test.use({ trace: "off" });
|
||
|
||
test("NC-browser-candidate-review:改稿恢复部分选择旧审阅冲突与真实采纳", async ({
|
||
page,
|
||
context,
|
||
}, info) => {
|
||
if (!process.env.MUSE_WORKBENCH_URL || !process.env.MUSE_AUTHOR_PASSWORD_FILE)
|
||
throw new 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("button", { name: "新建作品" }).click();
|
||
await page.getByLabel("名称", { exact: true }).fill("候选改稿(合成验收)");
|
||
await page.getByRole("button", { name: "保存档案" }).click();
|
||
await page.getByLabel("新章节标题").fill("街角的信");
|
||
await page.getByRole("button", { name: "添加章节" }).click();
|
||
const editor = page.getByRole("textbox", { name: "章节正文" });
|
||
await editor.click();
|
||
await page.keyboard.insertText(" “原句。”e\u0301🧑🏽");
|
||
await page.keyboard.press("Enter");
|
||
await page.keyboard.press("Enter");
|
||
await page.keyboard.insertText("末段仍留在原处。");
|
||
await expect(page.getByText("服务器已保存", { exact: true })).toBeVisible();
|
||
const chapter = decodeURIComponent(
|
||
new URL(page.url()).pathname.split("/").at(-1)!,
|
||
);
|
||
const docURL = `/api/v1/chapters/${encodeURIComponent(chapter)}/documents`;
|
||
const listURL = `/api/v1/chapters/${encodeURIComponent(chapter)}/writing-candidates`;
|
||
const original = await (await page.request.get(docURL)).json();
|
||
await page.getByRole("link", { name: "比较正文候选" }).click();
|
||
await page.getByRole("button", { name: "另拟改稿" }).click();
|
||
let draft = page.getByRole("textbox", { name: "候选改稿" });
|
||
await draft.locator("p").first().click();
|
||
await page.keyboard.press("Meta+ArrowLeft");
|
||
await page.keyboard.insertText("改稿:");
|
||
await draft.locator("p").last().click();
|
||
await page.keyboard.press("Meta+ArrowRight");
|
||
await page.keyboard.insertText("新增末句。");
|
||
// 刷新只恢复私人候选缓冲,不产生正文或候选写入。
|
||
await page.reload();
|
||
await page.getByRole("button", { name: "另拟改稿" }).click();
|
||
draft = page.getByRole("textbox", { name: "候选改稿" });
|
||
await expect(draft).toContainText("改稿:");
|
||
await expect(draft).toContainText("新增末句。");
|
||
expect((await (await page.request.get(docURL)).json()).revision).toBe(
|
||
original.revision,
|
||
);
|
||
expect(await (await page.request.get(listURL)).json()).toEqual([]);
|
||
await page.getByRole("button", { name: "保存候选版本", exact: true }).click();
|
||
await page.getByRole("button", { name: /^候选 1 · 版本 1/ }).click();
|
||
await expect(
|
||
page.getByRole("button", { name: "采纳为正文新版本" }),
|
||
).toBeEnabled();
|
||
const before = (await (await page.request.get(listURL)).json())[0];
|
||
expect(before.changes).toHaveLength(2);
|
||
const other = await context.newPage();
|
||
await other.goto(page.url());
|
||
await other.getByRole("button", { name: /^候选 1 · 版本 1/ }).click();
|
||
await expect(
|
||
other.getByRole("button", { name: "采纳为正文新版本" }),
|
||
).toBeEnabled();
|
||
await page.getByRole("button", { name: "编辑候选或部分选择" }).click();
|
||
await page.getByRole("button", { name: "按段选择", exact: true }).click();
|
||
await page.getByLabel("选择第 1 处改动").check();
|
||
await page
|
||
.getByRole("button", { name: "将所选改动保存为候选新版本" })
|
||
.click();
|
||
await page.getByRole("button", { name: /^候选 1 · 版本 2/ }).click();
|
||
const partial = (await (await page.request.get(listURL)).json())[0];
|
||
expect(partial.revision).toBe(2);
|
||
expect(partial.candidate_hash).not.toBe(before.candidate_hash);
|
||
expect(partial.visible_text).toContain("改稿:");
|
||
expect(partial.visible_text).not.toContain("新增末句。");
|
||
await page.screenshot({
|
||
path: info.outputPath("候选部分选择后审阅.png"),
|
||
fullPage: true,
|
||
timeout: 10000,
|
||
});
|
||
await page
|
||
.getByRole("button", { name: "采纳为正文新版本" })
|
||
.scrollIntoViewIfNeeded();
|
||
await page.screenshot({
|
||
path: info.outputPath("正文差异与决定面板.png"),
|
||
fullPage: true,
|
||
timeout: 10000,
|
||
});
|
||
await other.getByRole("button", { name: "采纳为正文新版本" }).click();
|
||
await expect(
|
||
other.getByRole("button", { name: "重新打开审阅" }),
|
||
).toBeVisible();
|
||
expect((await (await page.request.get(docURL)).json()).revision).toBe(
|
||
original.revision,
|
||
);
|
||
await other.close();
|
||
await page.getByRole("button", { name: "采纳为正文新版本" }).click();
|
||
await expect(page.getByText("已采纳", { exact: true })).toBeVisible();
|
||
const final = await (await page.request.get(docURL)).json();
|
||
expect(final.revision).toBe(original.revision + 1);
|
||
expect(final.visible_text).toBe(partial.visible_text);
|
||
expect(final.document.paragraphs[1]).toEqual(original.document.paragraphs[1]);
|
||
expect(final.document.paragraphs[2]).toEqual(original.document.paragraphs[2]);
|
||
await page.getByRole("link", { name: "返回正文" }).click();
|
||
await expect(page.getByRole("textbox", { name: "章节正文" })).toContainText(
|
||
"改稿:",
|
||
);
|
||
await page.getByRole("button", { name: "查看创作进度" }).click();
|
||
await expect(page.getByText("共 1 章,1 章已保存正文。")).toBeVisible();
|
||
const progress = await (
|
||
await page.request.get(
|
||
`/api/v1/works/${encodeURIComponent(original.work_id)}/progress`,
|
||
)
|
||
).json();
|
||
expect(progress.undecided_candidates).toBe(0);
|
||
expect(progress.chapters[0].document_revision).toBe(final.revision);
|
||
await info.attach("真实候选与正文版本", {
|
||
body: JSON.stringify({ original, candidate: partial, final }, null, 2),
|
||
contentType: "application/json",
|
||
});
|
||
});
|