Files
openidea/e2e/terminal-clipboard.spec.ts
l0ng-ai 915fec598f test(e2e): wait for xterm to open before pasting into the terminal
xterm now opens on a later frame, once its pane has a size, so the clipboard
test queried the helper textarea before it existed.
2026-11-05 21:30:14 +08:00

53 lines
2.6 KiB
TypeScript

import { expect, test } from "@playwright/test";
test("local terminal stores clipboard media and pastes one shell-quoted argument", async ({ page }) => {
await page.goto("/");
const observed = await page.evaluate(async () => {
const ipcPath = "/src/platform/ipc.ts";
const sessionPath = "/src/features/terminal/session.ts";
const { commands } = await import(ipcPath);
const { TerminalSession } = await import(sessionPath);
Object.defineProperty(window, "__TAURI_INTERNALS__", {
configurable: true,
value: { transformCallback: () => 1 },
});
const stored: { id: number; data: number[]; mime: string }[] = [];
const writes: string[] = [];
commands.termSpawn = async () => ({ status: "ok", data: { id: 838, title: "pwsh", pid: 1 } });
commands.clipboardFileList = async () => ({ status: "ok", data: [] });
commands.termStoreImage = async (id: number, data: number[], mime: string) => {
stored.push({ id, data, mime });
return { status: "ok", data: "C:\\Temp\\a'b c\\image.png" };
};
commands.termWrite = async (_id: number, data: string) => writes.push(data);
commands.termResize = async () => undefined;
commands.termKill = async () => undefined;
const container = document.createElement("div");
container.style.cssText = "position:fixed;inset:0;z-index:99999";
document.body.append(container);
const session = new TerminalSession({ key: "clipboard", cwd: "C:/Temp", onChange() {}, onFocus() {} });
try {
session.attach(container);
await session.start();
// xterm opens on a later frame, once the pane has a size.
const openDeadline = Date.now() + 5000;
while (!container.querySelector("textarea") && Date.now() < openDeadline) {
await new Promise((resolve) => requestAnimationFrame(resolve));
}
const transfer = new DataTransfer();
transfer.items.add(new File([new Uint8Array([137, 80, 78, 71])], "image.png", { type: "image/png" }));
const event = new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: transfer });
container.querySelector("textarea")!.dispatchEvent(event);
const deadline = Date.now() + 5000;
while (!writes.length && Date.now() < deadline) await new Promise((resolve) => requestAnimationFrame(resolve));
return { stored, writes, claimed: event.defaultPrevented };
} finally {
session.dispose();
container.remove();
}
});
expect(observed.claimed).toBe(true);
expect(observed.stored).toEqual([{ id: 838, data: [137, 80, 78, 71], mime: "image/png" }]);
expect(observed.writes).toEqual(["'C:\\Temp\\a''b c\\image.png'"]);
});