mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 08:07:49 +00:00
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
115 lines
4.9 KiB
TypeScript
115 lines
4.9 KiB
TypeScript
import { doubleShift, expect, ipcCalls, stubDesktop, test } from "./fixtures";
|
|
|
|
test("double Shift opens Search Everywhere with its tabs; Escape closes it", async ({ workbench: page }) => {
|
|
await doubleShift(page);
|
|
const dialog = page.getByRole("dialog", { name: "Search Everywhere" });
|
|
await expect(dialog).toBeVisible();
|
|
await expect(dialog.getByRole("combobox")).toBeFocused();
|
|
for (const tab of ["All", "Classes", "Files", "Symbols", "Actions", "Text"]) {
|
|
await expect(dialog.getByRole("tab", { name: tab })).toBeVisible();
|
|
}
|
|
await page.keyboard.press("Escape");
|
|
await expect(dialog).toBeHidden();
|
|
});
|
|
|
|
test("Search Everywhere finds and runs an action", async ({ workbench: page }) => {
|
|
await doubleShift(page);
|
|
const dialog = page.getByRole("dialog", { name: "Search Everywhere" });
|
|
await dialog.getByRole("combobox").fill("Language Servers");
|
|
const option = dialog.getByRole("option", { name: /Language Servers/ }).first();
|
|
await expect(option).toBeVisible();
|
|
await page.keyboard.press("Enter");
|
|
await expect(page.getByRole("dialog", { name: "Settings" })).toBeVisible();
|
|
await expect(page.getByRole("list", { name: /language servers/i })).toBeVisible();
|
|
});
|
|
|
|
const ROOT = "/dev/acme-api";
|
|
const SERVICE = `${ROOT}/src/main/kotlin/com/acme/orders/service/OrderService.kt`;
|
|
|
|
test("Search Everywhere finds a file and opens it", async ({ workbench: page }) => {
|
|
// The project's file index is stubbed at the IPC layer.
|
|
await stubDesktop(page);
|
|
await page.evaluate((path) => {
|
|
window.__ipc.handlers.find_files = (args) =>
|
|
String(args.query).startsWith("OrderSer")
|
|
? [{ path, relPath: path.slice("/dev/acme-api/".length), score: 100, indices: [] }]
|
|
: [];
|
|
}, SERVICE);
|
|
await doubleShift(page);
|
|
const dialog = page.getByRole("dialog", { name: "Search Everywhere" });
|
|
await dialog.getByRole("combobox").fill("OrderService");
|
|
await expect(dialog.getByRole("option", { name: /OrderService\.kt/ })).toBeVisible();
|
|
await page.keyboard.press("Enter");
|
|
await expect(page.getByRole("tab", { name: "OrderService.kt" })).toHaveAttribute("aria-selected", "true");
|
|
await expect(page.getByRole("textbox", { name: `Editor for ${SERVICE}` })).toBeVisible();
|
|
});
|
|
|
|
test("Find in Files streams matches by file and opens the chosen one at its line", async ({ workbench: page }) => {
|
|
await stubDesktop(page);
|
|
await page.evaluate(
|
|
({ root, service }) => {
|
|
const match = (line: number, text: string, word: string) => ({
|
|
line,
|
|
text,
|
|
ranges: [[text.indexOf(word), text.indexOf(word) + word.length]],
|
|
textOffset: 0,
|
|
});
|
|
window.__ipc.handlers.search_validate = () => null;
|
|
window.__ipc.handlers.search_start = (args) => {
|
|
const send = (event: unknown) => window.__ipc.send(args.onEvent, event);
|
|
setTimeout(() => {
|
|
send({
|
|
type: "file",
|
|
file: {
|
|
path: `${root}/build.gradle.kts`,
|
|
relPath: "build.gradle.kts",
|
|
matches: [
|
|
match(7, "class OrderController(private val service: OrderService) {", "OrderService"),
|
|
match(3, "import com.acme.orders.service.OrderService", "OrderService"),
|
|
],
|
|
},
|
|
});
|
|
send({
|
|
type: "file",
|
|
file: {
|
|
path: service,
|
|
relPath: service.slice(root.length + 1),
|
|
matches: [match(0, "// OrderService", "OrderService")],
|
|
},
|
|
});
|
|
send({
|
|
type: "done",
|
|
summary: { files: 2, matches: 3, limitHit: false, cancelled: false, elapsedMs: 4 },
|
|
});
|
|
}, 20);
|
|
return null;
|
|
};
|
|
},
|
|
{ root: ROOT, service: SERVICE },
|
|
);
|
|
await page.keyboard.press("Meta+Shift+f");
|
|
const dialog = page.getByRole("dialog", { name: "Find in Files" });
|
|
await dialog.getByRole("textbox", { name: "Text to find" }).fill("OrderService");
|
|
const matches = dialog.getByRole("listbox", { name: "Matches" });
|
|
await expect(matches.getByRole("option")).toHaveCount(3);
|
|
await expect
|
|
.poll(async () => (await ipcCalls(page, "search_start")).at(-1)?.query)
|
|
.toMatchObject({
|
|
pattern: "OrderService",
|
|
});
|
|
await matches.getByRole("option", { name: /import com\.acme\.orders\.service\.OrderService/ }).dblclick();
|
|
await expect(page.getByRole("tab", { name: "build.gradle.kts" })).toHaveAttribute("aria-selected", "true");
|
|
const caretLine = () =>
|
|
page.evaluate((label) => {
|
|
const content = document.querySelector(`.cm-content[aria-label="${label}"]`) as unknown as {
|
|
cmTile: {
|
|
view: { state: { doc: { lineAt(pos: number): { text: string } }; selection: { main: { head: number } } } };
|
|
};
|
|
} | null;
|
|
if (!content) return null;
|
|
const { state } = content.cmTile.view;
|
|
return state.doc.lineAt(state.selection.main.head).text;
|
|
}, `Editor for ${ROOT}/build.gradle.kts`);
|
|
await expect.poll(caretLine).toBe("import com.acme.orders.service.OrderService");
|
|
});
|