Files
openidea/e2e/commit.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

76 lines
3.2 KiB
TypeScript

/**
* Committing from the Commit tool window. Git is stubbed at the IPC layer; the repository side is
* covered by `crates/ide-vcs` against real repositories.
*/
import type { Page } from "@playwright/test";
import { expect, ipcCalls, openFromTree, stubDesktop, test } from "./fixtures";
const ROOT = "/dev/acme-api";
/** A repository with a modified tracked file and an untracked one; `vcs_commit` clears both. */
async function stubRepository(page: Page) {
await stubDesktop(page);
await page.evaluate(async (root) => {
let committed = false;
const changes = [
{
path: `${root}/build.gradle.kts`,
relPath: "build.gradle.kts",
staged: null,
unstaged: "modified",
renamedFrom: null,
},
{ path: `${root}/notes.txt`, relPath: "notes.txt", staged: null, unstaged: "untracked", renamedFrom: null },
];
const h = window.__ipc.handlers;
h.vcs_roots = () => [{ root, operation: null, head: "main", headCommit: "1111111" }];
h.vcs_branch_info = () => ({
head: "main",
headCommit: "1111111",
upstream: null,
ahead: 0,
behind: 0,
operation: null,
});
h.vcs_status = () => (committed ? [] : changes);
h.vcs_stage = () => null;
h.vcs_unstage = () => null;
h.vcs_commit = () => {
committed = true;
return "2222222";
};
const vcsModule = "/src/features/vcs/store.ts";
const { useVcs, refreshNow } = await import(/* @vite-ignore */ vcsModule);
useVcs.setState({ available: true, root, repo: root, branchesLoaded: false, stashesLoaded: false });
await refreshNow();
}, ROOT);
}
test("⌘K commits the checked changes with the typed message", async ({ workbench: page }) => {
await openFromTree(page, "build.gradle.kts");
await stubRepository(page);
await page.keyboard.press("Meta+k");
const panel = page.getByRole("region", { name: "Commit", exact: true });
const commit = panel.getByRole("button", { name: "Commit", exact: true });
const changes = panel.getByRole("tree", { name: "Changes" });
// Tracked changes start included; unversioned files start excluded.
await expect(changes.getByRole("checkbox", { name: "Include build.gradle.kts in commit" })).toBeChecked();
await expect(changes.getByRole("checkbox", { name: "Include Unversioned Files in commit" })).not.toBeChecked();
const message = panel.getByRole("textbox", { name: "Commit message" });
await expect(message).toBeFocused();
// Committing without a message is refused.
await commit.click();
await expect(panel.getByRole("alert")).toHaveText("Specify commit message");
expect(await ipcCalls(page, "vcs_commit")).toHaveLength(0);
await message.fill("Return order DTOs from create");
await commit.click();
await expect(page.getByText(/1 file committed: Return order DTOs from create/)).toBeVisible();
const [committed] = await ipcCalls(page, "vcs_commit");
expect(committed).toMatchObject({ repo: ROOT, message: "Return order DTOs from create" });
const staged = (await ipcCalls(page, "vcs_stage")).flatMap((a) => a.paths as string[]);
expect(staged).toEqual([`${ROOT}/build.gradle.kts`]);
await expect(changes.getByRole("checkbox", { name: "Include build.gradle.kts in commit" })).toBeHidden();
});