mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-10-30 00:27:43 +09:00
Improves CLI and MCP reliability across project synchronization, asset editing, imports, audits, and clipboard workflows. ## Changes - Keeps asset filename and description updates after session refresh. - Prevents intermittent Immer patch errors during consecutive MCP mutations. - Prevents false edit conflicts caused by stale local session state. - Preserves asset uploads without treating them as redundant metadata updates. - Exposes editable asset filenames consistently through MCP. - Imports project assets correctly when copying projects between environments. - Supports refreshing partially available project snapshots. - Keeps MCP operations working when optional project data is unavailable. - Produces clearer compatibility errors when the API and CLI versions differ. - Makes rendered audits more resilient when individual screenshots fail. - Prevents rendered audits from hanging while starting browser captures. - Handles denied clipboard permissions without uncaught browser errors. - Improves copy and paste reliability for pages, components, styles, and animations. ## Verification - Asset uploader tests and typechecking pass. - Focused asset workflow E2E passes. - Complete E2E shard 1 passes. - Realistic MCP subagent test confirms: - Asset filename and description persist after refresh. - Consecutive mutations work without manual refresh. - No Immer patch error occurs. - No false conflict occurs. - Original asset values can be restored successfully.
36 lines
1.0 KiB
TypeScript
36 lines
1.0 KiB
TypeScript
import { afterEach, expect, test, vi } from "vitest";
|
|
import { initBuilderApi } from "./builder-api";
|
|
import { readClipboardText } from "./clipboard";
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
test("reads clipboard text", async () => {
|
|
vi.stubGlobal("navigator", {
|
|
clipboard: { readText: vi.fn().mockResolvedValue("clipboard text") },
|
|
});
|
|
|
|
await expect(readClipboardText()).resolves.toBe("clipboard text");
|
|
});
|
|
|
|
test("reports denied clipboard access without rejecting", async () => {
|
|
initBuilderApi();
|
|
const toastError = vi.fn();
|
|
window.__webstudio__$__builderApi.toast.error = toastError;
|
|
vi.stubGlobal("navigator", {
|
|
clipboard: {
|
|
readText: vi
|
|
.fn()
|
|
.mockRejectedValue(
|
|
new DOMException("Permission denied", "NotAllowedError")
|
|
),
|
|
},
|
|
});
|
|
|
|
await expect(readClipboardText()).resolves.toBeUndefined();
|
|
expect(toastError).toHaveBeenCalledWith(
|
|
"Webstudio cannot read the clipboard. Allow clipboard access in your browser, then try again."
|
|
);
|
|
});
|