fix(POSTV1-07): 固定画布布局与文字贴纸选择
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run

This commit is contained in:
suyx
2026-08-05 17:59:53 +08:00
parent d9e39702e0
commit 9d2aa879e9
3 changed files with 106 additions and 15 deletions
+70
View File
@@ -212,3 +212,73 @@ test("TDD-WP4-TXT-002 waits for the archived font and commits exact style ranges
writeEvidence("TDD-WP4-TXT-002-font-metrics-ranges", "pixel-diff.json", { background_alpha_separate: true, clipped_visible_text: false, effective_font_size: 96 });
if (process.env.DADA_EVIDENCE_DIR_TEXT_EDITOR) await page.screenshot({ fullPage: true, path: resolve(process.env.DADA_EVIDENCE_DIR_TEXT_EDITOR, "TDD-WP4-TXT-002-font-metrics-ranges", "font-styles.png") });
});
test("POSTV1-07 keeps the canvas anchored when the text template panel opens", async ({ page }) => {
const projectId = uuid(760);
const backend: Backend = { canvas: emptyCanvas(), recent: [], saves: 0, version: 5 };
await routeEditor(page, projectId, backend);
await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
const stage = page.getByLabel("编辑画布");
const before = await stage.boundingBox();
if (!before) throw new Error("Canvas geometry is unavailable before opening text templates.");
await page.getByRole("button", { name: "文字模板", exact: true }).click();
await expect(page.locator(".editor-template-grid button")).toHaveCount(32);
const after = await stage.boundingBox();
if (!after) throw new Error("Canvas geometry is unavailable after opening text templates.");
const assetsPanelScroll = await page.getByLabel("素材与底图来源").evaluate((panel) => ({
clientHeight: panel.clientHeight,
overflowY: getComputedStyle(panel).overflowY,
scrollHeight: panel.scrollHeight,
}));
expect(Math.abs(after.x - before.x)).toBeLessThanOrEqual(1);
expect(Math.abs(after.y - before.y)).toBeLessThanOrEqual(1);
expect(Math.abs(after.width - before.width)).toBeLessThanOrEqual(1);
expect(Math.abs(after.height - before.height)).toBeLessThanOrEqual(1);
expect(assetsPanelScroll.overflowY).toBe("auto");
expect(assetsPanelScroll.scrollHeight).toBeGreaterThan(assetsPanelScroll.clientHeight);
});
test("POSTV1-07 keeps text selection stable and dismisses move feedback", async ({ page }) => {
const projectId = uuid(770);
const backend: Backend = { canvas: emptyCanvas(), recent: [], saves: 0, version: 6 };
await routeEditor(page, projectId, backend);
await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
await page.getByRole("button", { name: "文字模板", exact: true }).click();
await page.getByRole("button", { name: /H003 生活分享家/ }).click();
await expect.poll(() => backend.canvas.elements.length).toBe(1);
await expect.poll(() => backend.saves, { timeout: 5_000 }).toBeGreaterThan(0);
await page.reload();
const stage = page.getByLabel("编辑画布");
const bounds = await stage.boundingBox();
const element = backend.canvas.elements[0];
if (!bounds || !element) throw new Error("Text selection geometry is unavailable.");
const positionBefore = structuredClone(element.position);
const savesBefore = backend.saves;
const clientX = bounds.x + bounds.width * element.position.x;
const clientY = bounds.y + bounds.height * element.position.y;
await page.mouse.move(clientX, clientY);
await page.mouse.down();
await expect(page.getByLabel("字体覆盖")).toBeVisible();
const selectedBounds = await stage.boundingBox();
const inspectorScroll = await page.getByLabel("对象参数").evaluate((panel) => ({
clientHeight: panel.clientHeight,
overflowY: getComputedStyle(panel).overflowY,
scrollHeight: panel.scrollHeight,
}));
if (!selectedBounds) throw new Error("Canvas geometry is unavailable after selecting text.");
expect(Math.abs(selectedBounds.y - bounds.y)).toBeLessThanOrEqual(1);
expect(inspectorScroll.overflowY).toBe("auto");
expect(inspectorScroll.scrollHeight).toBeGreaterThan(inspectorScroll.clientHeight);
await page.mouse.move(clientX + 1, clientY);
await page.mouse.up();
await expect(page.getByLabel("字体覆盖")).toBeVisible();
await page.waitForTimeout(800);
expect(backend.canvas.elements[0]?.position).toEqual(positionBefore);
expect(backend.saves).toBe(savesBefore);
});