Файли
openidea/e2e/toolwindows.spec.ts
T
l0ng-ai aa33d2eeab test(e2e): cover the core editing, code intelligence, VCS, run and debug flows (#1277)
Adds a `stubDesktop` fixture that switches the browser-mode workbench to
desktop mode over a stubbed IPC layer: tests answer the commands they need,
push Channel messages and IdeEvents, and assert on the commands invoked.
Unstubbed commands fail as unavailable; documents keep the in-memory backend.

New flows covered:
- editing: modified marker and ⌘S save, ⌘R Replace All with one undo step
- code intelligence: completion, ⌘B to another file, Find Usages, in-place
  rename, diagnostics with an ⌥⏎ quick fix
- VCS: ⌘K commit with message validation and default inclusion
- run: ⌃R output streaming and exit, ⌘F2 stop
- debug: breakpoint, stop with frames and variables, step over, resume
- search: Find in Files results opening at the match line; the Search
  Everywhere file case no longer needs fixme
- terminal: typed command reaches the shell and its output renders
- project: Close Project to Welcome, trust prompt, open a recent project
2026-11-04 22:52:48 +08:00

127 рядки
5.9 KiB
TypeScript

import { expect, ipcCalls, stubDesktop, test, visibleToolWindows } from "./fixtures";
test("⌘1 focuses, hides and re-shows the Project tool window", async ({ workbench: page }) => {
const project = page.getByRole("region", { name: "Project" });
await page.keyboard.press("Meta+1");
await expect(page.getByRole("tree", { name: "Project" })).toBeFocused();
await page.keyboard.press("Meta+1");
await expect(project).toBeHidden();
await page.keyboard.press("Meta+1");
await expect(project).toBeVisible();
});
test("⌘4 toggles Run; Shift+Escape hides the active tool window", async ({ workbench: page }) => {
const run = page.getByRole("region", { name: "Run" });
await page.keyboard.press("Meta+4");
await expect(run).toBeVisible();
await page.keyboard.press("Meta+4");
await expect(run).toBeHidden();
await page.keyboard.press("Meta+4");
await expect(run).toBeVisible();
await page.keyboard.press("Shift+Escape");
await expect(run).toBeHidden();
});
test("⌥F12 opens the Terminal tool window and toggles it closed", async ({ workbench: page }) => {
const terminal = page.getByRole("region", { name: "Terminal" });
await page.keyboard.press("Alt+F12");
await expect(terminal).toBeVisible();
expect(await visibleToolWindows(page)).toContain("Terminal");
await page.keyboard.press("Alt+F12");
await expect(terminal).toBeHidden();
});
test("Split Right gives the Terminal a tab group with its own header; Unsplit merges it back", async ({
workbench: page,
}) => {
const terminal = page.getByRole("region", { name: "Terminal" });
const strips = terminal.getByRole("tablist", { name: "Terminal sessions" });
await page.keyboard.press("Alt+F12");
await expect(strips.getByRole("tab", { name: "Local" })).toBeVisible();
await strips.getByRole("tab", { name: "Local" }).click({ button: "right" });
await page.getByRole("menuitem", { name: /^Split Right/ }).click();
await expect(strips).toHaveCount(2);
await expect(strips.nth(1).getByRole("tab", { name: "Local (2)" })).toHaveAttribute("aria-selected", "true");
// One header per group: the title in the first, the window's buttons in the last.
await expect(terminal.locator("header")).toHaveCount(2);
await expect(terminal.locator("header").nth(0)).toContainText("Terminal");
await expect(terminal.locator("header").nth(1).getByRole("button", { name: "Options", exact: true })).toHaveCount(1);
await expect(terminal.locator("header").nth(0).getByRole("button", { name: "Options", exact: true })).toHaveCount(0);
if (process.env.OPENIDEA_E2E_SHOTS) await terminal.screenshot({ path: process.env.OPENIDEA_E2E_SHOTS });
await strips.nth(1).getByRole("tab", { name: "Local (2)" }).click({ button: "right" });
await page.getByRole("menuitem", { name: "Unsplit" }).click();
await expect(strips).toHaveCount(1);
await expect(strips.getByRole("tab")).toHaveText(["Local", "Local (2)"]);
await expect(terminal.locator("header")).toHaveCount(1);
});
test("closing the last tab of a terminal group focuses its neighbour", async ({ workbench: page }) => {
const terminal = page.getByRole("region", { name: "Terminal" });
const strips = terminal.getByRole("tablist", { name: "Terminal sessions" });
await page.keyboard.press("Alt+F12");
await strips.getByRole("tab", { name: "Local" }).click({ button: "right" });
await page.getByRole("menuitem", { name: /^Split Right/ }).click();
await expect(strips).toHaveCount(2);
await strips.nth(1).getByRole("button", { name: "Close Tab", exact: true }).click();
await expect(strips).toHaveCount(1);
await expect(terminal.locator(".xterm-helper-textarea")).toBeFocused();
await page.keyboard.press("Meta+t");
await expect(strips.getByRole("tab")).toHaveCount(2);
});
test("⌘⇧F12 hides all tool windows and restores them", async ({ workbench: page }) => {
await page.keyboard.press("Meta+6");
await expect(page.getByRole("region", { name: "Problems" })).toBeVisible();
await page.keyboard.press("Meta+Shift+F12");
expect(await visibleToolWindows(page)).toEqual([]);
await page.keyboard.press("Meta+Shift+F12");
await expect(page.getByRole("region", { name: "Project" })).toBeVisible();
await expect(page.getByRole("region", { name: "Problems" })).toBeVisible();
});
test("the Terminal sends typed commands to the shell and shows its output", async ({ workbench: page }) => {
// The shell is stubbed at the IPC layer: it echoes input and answers `echo`.
await stubDesktop(page);
await page.evaluate(() => {
let output: unknown = null;
let line = "";
const out = (text: string) => window.__ipc.send(output, text);
const h = window.__ipc.handlers;
h.term_default_shell = () => "/bin/zsh";
h.term_available_shells = () => ["/bin/zsh"];
h.term_spawn = (args) => {
output = args.onOutput;
setTimeout(() => out("acme-api % "), 20);
return { id: 5, title: "zsh", pid: 99 };
};
h.term_resize = () => null;
h.term_is_busy = () => false;
h.term_write = (args) => {
for (const ch of String(args.data)) {
if (ch === "\r") {
const said = /^echo (.*)$/.exec(line);
out(`\r\n${said ? `${said[1]}\r\n` : ""}acme-api % `);
line = "";
} else {
line += ch;
out(ch);
}
}
return null;
};
});
await page.keyboard.press("Alt+F12");
const terminal = page.getByRole("region", { name: "Terminal", exact: true });
const rows = terminal.locator(".xterm-rows");
await expect(rows).toContainText("acme-api %");
await terminal.locator(".xterm-screen").click();
await expect(terminal.getByRole("textbox", { name: "Terminal input" })).toBeFocused();
await page.keyboard.type("echo hello from e2e");
await page.keyboard.press("Enter");
await expect(rows.locator("div", { hasText: /^hello from e2e\s*$/ })).toHaveCount(1);
const written = (await ipcCalls(page, "term_write")).map((a) => a.data).join("");
expect(written).toBe("echo hello from e2e\r");
});