import type { Page } from "@playwright/test"; import { expect, test } from "./fixtures"; /** Supply detected configurations without launching desktop processes. */ async function configure(page: Page, extra = 0) { await page.evaluate(async (extra) => { const storePath = "/src/features/run/store.ts"; const projectPath = "/src/platform/project.ts"; const { useRun } = await import(storePath); const { useProject } = await import(projectPath); localStorage.setItem(`openidea.services.runTypes:${useProject.getState().project.root}`, '["spring-boot","npm"]'); useRun.setState({ configs: [ ["gateway", "spring-boot"], ["portal", "spring-boot"], ["web", "npm"], ["worker", "npm"], ...Array.from({ length: extra }, (_, i) => [`app-${i}`, "spring-boot"]), ].map(([id, kind]) => ({ id, name: id, kind, command: kind, args: [], env: {}, cwd: null, detected: true, isTest: false, debugAdapter: null, })), }); }, extra); if (!(await page.getByRole("tree", { name: "Services", exact: true }).isVisible())) await page.keyboard.press("Meta+8"); await expect(page.getByRole("tree", { name: "Services", exact: true })).toBeVisible(); } async function move(page: Page, source: string, target: string) { const tree = page.getByRole("tree", { name: "Services", exact: true }); const sourceRow = tree.getByRole("treeitem", { name: source, exact: true }); await sourceRow.click(); const from = await sourceRow.boundingBox(); const to = await tree.getByRole("treeitem", { name: target, exact: true }).boundingBox(); if (!from || !to) throw new Error("Service row is not visible"); await page.mouse.move(from.x + 70, from.y + from.height / 2); await page.mouse.down(); await page.mouse.move(to.x + 70, to.y + 3, { steps: 8 }); await page.mouse.up(); } test("service pointer ordering works for Java and npm and survives reload", async ({ workbench: page }) => { await configure(page); const tree = page.getByRole("tree", { name: "Services", exact: true }); await move(page, "portal", "gateway"); await expect(tree.getByRole("treeitem")).toHaveText(["Spring Boot", "portal", "gateway", "npm", "web", "worker"]); await expect(tree.getByRole("treeitem", { name: "portal", exact: true })).toHaveAttribute("aria-selected", "true"); await move(page, "worker", "web"); await expect(tree.getByRole("treeitem")).toHaveText(["Spring Boot", "portal", "gateway", "npm", "worker", "web"]); await page.reload(); await expect(page.getByRole("tree", { name: "Project" })).toBeVisible(); await configure(page); await expect(tree.getByRole("treeitem")).toHaveText(["Spring Boot", "portal", "gateway", "npm", "worker", "web"]); await tree.getByRole("treeitem", { name: "web", exact: true }).click(); await page.getByRole("button", { name: "Move Up", exact: true }).click(); await expect(tree.getByRole("treeitem")).toHaveText(["Spring Boot", "portal", "gateway", "npm", "web", "worker"]); }); test("service dragging scrolls across virtual rows without losing source identity", async ({ workbench: page }) => { await configure(page, 100); const tree = page.getByRole("tree", { name: "Services", exact: true }); const source = tree.getByRole("treeitem", { name: "portal", exact: true }); await source.click(); const from = await source.boundingBox(); const bounds = await tree.boundingBox(); if (!from || !bounds) throw new Error("Service rows are not visible"); await page.mouse.move(from.x + 70, from.y + from.height / 2); await page.mouse.down(); await page.mouse.move(bounds.x + 100, bounds.y + bounds.height - 5, { steps: 8 }); await expect.poll(() => tree.evaluate((el) => el.scrollTop)).toBeGreaterThan(1000); const target = tree.getByRole("treeitem", { name: "app-99", exact: true }); await target.scrollIntoViewIfNeeded(); const to = await target.boundingBox(); if (!to) throw new Error("Drop target is not visible"); await page.mouse.move(to.x + 70, to.y + to.height - 3); await page.mouse.up(); await expect(source).toHaveAttribute("aria-selected", "true"); await expect .poll(() => page.evaluate(() => { const key = Object.keys(localStorage).find((k) => k.startsWith("openidea.services.runOrder:")); return key ? JSON.parse(localStorage.getItem(key)!)["spring-boot"].slice(-2) : []; }), ) .toEqual(["app-99", "portal"]); });