Files
webstudio/apps/builder/app/shared/clipboard.test.ts
Oleg Isonen 7d781bdc86 fix: MCP fixes (#5870)
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.
2026-07-13 02:32:27 +02:00

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."
);
});