Files
pikasTech-HWLAB/web/hwlab-cloud-web/tests/workbench-e2e/specs/project-management.spec.ts
T
2026-06-26 12:21:36 +00:00

100 lines
7.1 KiB
TypeScript

// SPEC: PJ2026-010404 项目管理 draft-2026-06-25-p0-project-management-mdtodo; draft-2026-06-26-p1-mdtodo-web-operable.
// Responsibility: Fake-server browser regression for project root and MDTODO pages.
import { expect, saveScreenshot, test } from "../fixtures/test";
test.describe("project management pages", () => {
test("renders project root and launches Workbench through public DTOs", async ({ page }, testInfo) => {
await page.goto("/projects");
await expect(page.getByTestId("project-management-root")).toBeVisible();
await expect(page.getByTestId("project-management-summary")).toContainText("Projects");
await expect(page.getByTestId("project-list")).toContainText("HWLAB MDTODO");
await expect(page.getByTestId("project-source-list")).toContainText("mdtodo-file-tree");
await expect(page.getByText("[redacted]")).toHaveCount(0);
await page.getByTestId("open-mdtodo-page").click();
await expect(page).toHaveURL(/\/projects\/mdtodo/u);
await expect(page.getByTestId("project-management-mdtodo")).toBeVisible();
await expect(page.getByTestId("mdtodo-toolbar")).toBeVisible();
await expect(page.getByTestId("mdtodo-source-select")).toHaveValue("hwlab-v03-mdtodo");
await expect(page.getByTestId("mdtodo-file-select")).toHaveValue("file_plan");
await expect(page.getByTestId("mdtodo-file-select")).toContainText("hwlab-v03-mdtodo-web-sample.md");
await expect(page.locator(".mdtodo-summary-grid .metric-card")).toHaveCount(0);
await expect(page.locator(".mdtodo-source-panel")).toHaveCount(0);
await expect(page.locator(".mdtodo-file-panel")).toHaveCount(0);
await expect(page.getByTestId("mdtodo-task-tree")).toContainText("实现项目根导航");
await expect(page.locator('[data-task-id="R1"]')).toBeVisible();
await expect(page.locator('[data-task-id="R1.1"]')).toBeVisible();
await expect(page.locator('[data-task-id="R1.1.1"]')).toBeVisible();
await expect(page.getByTestId("mdtodo-task-detail")).toContainText("mdtodo:hwlab-v03-mdtodo:file_plan:R1");
await expect(page.getByTestId("mdtodo-body-rendered")).toContainText("Root notes");
await page.getByTestId("mdtodo-report-link").click();
await expect(page.getByTestId("mdtodo-report-preview")).toContainText("Report body from fake server");
await page.getByTestId("mdtodo-report-fullscreen").click();
await expect(page.getByTestId("mdtodo-report-fullscreen-dialog")).toContainText("R1.1 implementation report");
await page.getByLabel("关闭报告").click();
await page.getByTestId("mdtodo-info-open").click();
await expect(page.getByTestId("mdtodo-info-popover")).toContainText("Source");
await expect(page.getByTestId("mdtodo-info-popover")).toContainText("Files");
await expect(page.getByTestId("mdtodo-info-popover")).toContainText("Tasks");
await page.getByLabel("关闭摘要").click();
await page.getByTestId("mdtodo-source-config-open").click();
await expect(page.getByTestId("mdtodo-source-config-dialog")).toBeVisible();
await expect(page.getByTestId("mdtodo-source-form-hwpod")).toHaveValue("d601-f103-v2");
await expect(page.getByTestId("mdtodo-source-form-root")).toHaveValue("docs/MDTODO/");
await page.getByTestId("mdtodo-source-probe").click();
await expect(page.getByTestId("mdtodo-source-message")).toContainText("Probe ok");
await page.getByTestId("mdtodo-source-reindex-dialog").click();
await expect(page.getByTestId("mdtodo-source-message")).toContainText("Reindex 2 files / 4 tasks");
await page.getByLabel("关闭配置").click();
await page.getByTestId("mdtodo-title-read").dblclick();
await page.getByTestId("mdtodo-edit-title").fill("实现项目根导航 - edited");
await page.getByTestId("mdtodo-edit-status").selectOption("in_progress");
await page.getByTestId("mdtodo-edit-save").click();
await expect(page.getByTestId("mdtodo-task-mutation-message")).toContainText("任务已保存");
await expect(page.getByTestId("mdtodo-task-detail")).toContainText("实现项目根导航 - edited");
await expect(page.locator('[data-task-id="R1"]')).toContainText("进行中");
await page.getByTestId("mdtodo-body-rendered").dblclick();
await page.getByTestId("mdtodo-edit-body").fill("Body saved from Playwright.");
await page.getByTestId("mdtodo-edit-body-save").click();
await expect(page.getByTestId("mdtodo-task-mutation-message")).toContainText("正文已保存");
await page.getByTestId("mdtodo-new-title").fill("Playwright child");
await page.getByTestId("mdtodo-new-body").fill("Child from E2E.");
await page.getByTestId("mdtodo-add-subtask").click();
await expect(page.getByTestId("mdtodo-task-mutation-message")).toContainText("任务已创建");
await expect(page.locator('[data-task-id="R1.2"]')).toContainText("Playwright child");
await page.getByTestId("mdtodo-new-title").fill("Playwright sibling");
await page.getByTestId("mdtodo-continue-task").click();
await expect(page.locator('[data-task-id="R1.3"]')).toContainText("Playwright sibling");
await page.getByTestId("mdtodo-delete-task").click();
await expect(page.getByTestId("mdtodo-task-mutation-message")).toContainText("再次点击确认删除");
await page.getByTestId("mdtodo-delete-task").click();
await expect(page.getByTestId("mdtodo-task-mutation-message")).toContainText("任务已删除");
await expect(page.locator('[data-task-id="R1.3"]')).toHaveCount(0);
await expect(page.getByTestId("mdtodo-workbench-link-summary")).toContainText("ses_project_seed");
await expect(page.getByTestId("mdtodo-workbench-launch")).toBeEnabled();
await expect(page.locator("iframe")).toHaveCount(0);
await saveScreenshot(page, testInfo, "project-management-mdtodo");
await page.getByTestId("mdtodo-workbench-launch").click();
await expect(page).toHaveURL(/\/workbench\/sessions\/ses_project_launch_/u);
await expect(page.locator("#workspace")).toBeVisible();
const sessionId = page.url().match(/\/workbench\/sessions\/([^/?#]+)/u)?.[1] ?? "";
expect(sessionId).toMatch(/^ses_project_launch_/u);
const sessionDetail = await page.request.get(`/v1/workbench/sessions/${encodeURIComponent(sessionId)}`);
expect(sessionDetail.ok()).toBeTruthy();
const sessionPayload = await sessionDetail.json();
expect(sessionPayload.session?.launchContext?.projectId ?? sessionPayload.session?.metadata?.launchContext?.projectId).toBe("project_hwlab_v03");
expect(sessionPayload.session?.launchContext?.taskRef ?? sessionPayload.session?.metadata?.launchContext?.taskRef).toBe("mdtodo:hwlab-v03-mdtodo:file_plan:R1");
expect(sessionPayload.session?.messageCount ?? sessionPayload.session?.messages?.length ?? 0).toBeGreaterThan(0);
expect(sessionPayload.session?.firstUserMessagePreview ?? "").toContain("MDTODO");
const links = await page.request.get("/v1/project-management/workbench-links?taskRef=mdtodo:hwlab-v03-mdtodo:file_plan:R1");
expect(links.ok()).toBeTruthy();
const linksPayload = await links.json();
expect(linksPayload.links.some((link: { sessionId?: string }) => link.sessionId === sessionId)).toBeTruthy();
await saveScreenshot(page, testInfo, "project-management-workbench-launch");
});
});