- block-structure.spec.ts:真后端端到端——进 work1 workspace→章节结构条(1 小节)→分割(真实 split POST 200→2 小节)→合并(真实 merge POST 200→1 小节);'N 个小节'来自 chapterDetail 真数据,证明 split 真产生 block。 - global-setup section 8:幂等复位 work1 chapter1 为单 Block(删 split 残留,保留 order_no 最小首 Block)。 - BlockStructureBar.extractText 兼容纯文本 content(基础种子 block content 为纯文本非 ProseMirror JSON,JSON.parse 失败时退回原串,使 split 可用)。 验证:playwright block-structure 1 passed(真后端活体) + eslint 0。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.9 KiB
TypeScript
44 lines
1.9 KiB
TypeScript
import { expect, test, type Page } from '@playwright/test';
|
|
|
|
/**
|
|
* Block 分割/合并端到端(真实后端,MSW off)。
|
|
*
|
|
* 覆盖 D 链路:进 work1 workspace → BlockStructureBar 显示章节结构 → 分割首节(真实 split,1→2)→
|
|
* 验证 2 个小节 → 合并首节与下一节(真实 merge,2→1)→ 验证回到 1 个小节。
|
|
* globalSetup 已复位 work1 chapter1 为单 Block(幂等:即使中途失败残留也清掉)。
|
|
*/
|
|
const TOKEN = 'test1';
|
|
|
|
async function seedToken(page: Page): Promise<void> {
|
|
await page.addInitScript((t) => {
|
|
window.localStorage.setItem('accessToken', t);
|
|
window.localStorage.setItem('tenantId', '1');
|
|
}, TOKEN);
|
|
}
|
|
|
|
test('用户分割与合并章节内 Block(真实后端结构编辑)', async ({ page }) => {
|
|
await seedToken(page);
|
|
|
|
await page.goto('/workspace/1');
|
|
await expect(page.getByRole('heading', { name: /正在创作/ })).toBeVisible({ timeout: 15_000 });
|
|
|
|
// 章节结构条出现,初始 1 个小节(globalSetup 已复位)。
|
|
await expect(page.getByText(/章节结构 · 1 个小节/)).toBeVisible({ timeout: 15_000 });
|
|
|
|
// 分割首节(真实 split)→ chapterDetail 重拉 → 2 个小节。
|
|
const splitResp = page.waitForResponse(
|
|
(r) => /\/blocks\/[^/]+\/split/.test(r.url()) && r.request().method() === 'POST'
|
|
);
|
|
await page.getByRole('button', { name: '分割小节 1' }).click();
|
|
expect((await splitResp).status()).toBe(200);
|
|
await expect(page.getByText(/章节结构 · 2 个小节/)).toBeVisible({ timeout: 10_000 });
|
|
|
|
// 合并首节与下一节(真实 merge)→ 回到 1 个小节。
|
|
const mergeResp = page.waitForResponse(
|
|
(r) => /\/blocks\/[^/]+\/merge/.test(r.url()) && r.request().method() === 'POST'
|
|
);
|
|
await page.getByRole('button', { name: '合并小节 1 与下一节' }).click();
|
|
expect((await mergeResp).status()).toBe(200);
|
|
await expect(page.getByText(/章节结构 · 1 个小节/)).toBeVisible({ timeout: 10_000 });
|
|
});
|