import { expect, test } from "@playwright/test"; test.use({ viewport: { width: 1600, height: 900 } }); async function openPreferences(page: import("@playwright/test").Page): Promise { await page.getByRole("button", { name: "编辑", exact: true }).click(); await page.getByRole("menuitem", { name: "偏好设置", exact: true }).click(); await page.getByTestId("preferences-window").waitFor({ timeout: 30_000 }); } test("Preferences persist through OPFS and keymap rebinding takes effect", async ({ page }) => { test.setTimeout(240_000); await page.goto("/?ui=web"); await page.locator("main.blender-app").waitFor({ timeout: 120_000 }); await openPreferences(page); await expect(page.getByTestId("preferences-window").getByRole("button", { name: "界面", exact: true })).toHaveClass(/active/); await expect(page.getByRole("dialog", { name: "Web Blender 偏好设置" }).locator("nav button")).toHaveCount(9); const statusToggle = page.getByLabel("显示状态栏", { exact: true }); if (await statusToggle.isChecked()) await statusToggle.uncheck(); await page.getByRole("button", { name: "保存偏好", exact: true }).click(); await expect(page.getByTestId("preferences-window").locator("header output")).toContainText("已保存到 OPFS", { timeout: 30_000 }); await page.getByRole("button", { name: "键位", exact: true }).click(); const row = page.locator('tr[data-action="edit.operatorSearch"]'); await row.getByRole("button", { name: "录制", exact: true }).click(); await page.keyboard.press("Shift+F3"); await expect(row.locator("code")).toHaveText("Shift + F3"); await page.getByRole("button", { name: "保存偏好", exact: true }).click(); await page.getByRole("button", { name: "关闭偏好设置", exact: true }).click(); await expect(page.locator("main.blender-app")).toHaveAttribute("data-hide-status", "true"); await page.keyboard.press("F3"); await expect(page.getByLabel("搜索 Blender 操作")).toHaveCount(0); await page.keyboard.press("Shift+F3"); await expect(page.getByLabel("搜索 Blender 操作")).toBeVisible({ timeout: 30_000 }); await page.keyboard.press("Escape"); await page.reload(); await page.locator("main.blender-app").waitFor({ timeout: 120_000 }); await openPreferences(page); await expect(page.getByLabel("显示状态栏", { exact: true })).not.toBeChecked(); await page.getByRole("button", { name: "键位", exact: true }).click(); await expect(page.locator('tr[data-action="edit.operatorSearch"] code')).toHaveText("Shift + F3"); const stored = await page.evaluate(async () => { const root = await navigator.storage.getDirectory(); const directory = await root.getDirectoryHandle("settings"); const file = await (await directory.getFileHandle("web-interface.json")).getFile(); return JSON.parse(await file.text()); }); expect(stored.preferences.keymap.bindings["edit.operatorSearch"]).toBe("Shift+F3"); expect(stored.preferences.interface.showStatus).toBe(false); }); test("Keymap conflict is rejected and unsupported preference rows are marked", async ({ page }) => { test.setTimeout(180_000); await page.goto("/?ui=web"); await page.locator("main.blender-app").waitFor({ timeout: 120_000 }); await openPreferences(page); await page.getByRole("button", { name: "键位", exact: true }).click(); await page.locator('tr[data-action="edit.undo"]').getByRole("button", { name: "录制", exact: true }).click(); await page.keyboard.press("Control+S"); await expect(page.getByTestId("preferences-window").locator("header output")).toContainText("冲突"); await page.getByRole("button", { name: "视口", exact: true }).click(); await expect(page.locator('.preference-row[data-setting="viewport.gizmoSize"]')).toHaveAttribute("data-unsupported", "true"); });