mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Searching the command center for a branch name like "master" returned a Workspaces list where every row looked identical: the title was the branch and the subtitle read "<hostname> · <branch>". On a single-host machine the hostname repeats on every row, so there was no way to tell which project each "master" workspace belonged to. Add the project name to the workspace subtitle (host · project · branch) and gate the host label behind multi-host, matching the Agents section. The host is dropped on single-host setups, so the subtitle reads "project · branch" and rows are distinguishable. Because searchText is derived from the subtitle, typing a project name now matches its workspaces too. Extract the shared join into joinSubtitleParts() and route both the workspace and agent subtitles through it, removing the duplicated filter/join the Agents section hand-rolled. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
151 lines
5.6 KiB
TypeScript
151 lines
5.6 KiB
TypeScript
import { execFileSync } from "node:child_process";
|
|
import { expect } from "@playwright/test";
|
|
import { test } from "./fixtures";
|
|
import { gotoAppShell } from "./helpers/app";
|
|
import { createIdleAgent } from "./helpers/archive-tab";
|
|
import { openCommandCenter } from "./helpers/command-center";
|
|
import { addOfflineHostAndReload } from "./helpers/hosts";
|
|
import { expectAppRoute } from "./helpers/route-assertions";
|
|
import { seedWorkspace } from "./helpers/seed-client";
|
|
import { getServerId } from "./helpers/server-id";
|
|
import { buildHostWorkspaceRoute } from "@/utils/host-routes";
|
|
|
|
const PRIMARY_HOST_LABEL = "Primary Host";
|
|
const SECONDARY_HOST_ID = "host-command-center-workspaces-secondary";
|
|
const WORKSPACE_TITLE = "Payments Refactor";
|
|
const WORKSPACE_BRANCH = "feature/cmd-k-workspaces";
|
|
const AGENT_TITLE = "Fix checkout retries";
|
|
|
|
test.describe("Command center workspaces", () => {
|
|
test.describe.configure({ timeout: 180_000 });
|
|
|
|
test("workspace results show their title, host, and branch and open the workspace", async ({
|
|
page,
|
|
}) => {
|
|
const seeded = await seedWorkspace({
|
|
repoPrefix: "command-center-workspace-",
|
|
title: WORKSPACE_TITLE,
|
|
});
|
|
|
|
try {
|
|
execFileSync("git", ["checkout", "-b", WORKSPACE_BRANCH], {
|
|
cwd: seeded.repoPath,
|
|
stdio: "ignore",
|
|
});
|
|
const refreshed = await seeded.client.checkoutRefresh(seeded.repoPath);
|
|
if (!refreshed.success) {
|
|
throw new Error(`Failed to refresh checkout: ${JSON.stringify(refreshed.error)}`);
|
|
}
|
|
const agent = await createIdleAgent(seeded.client, {
|
|
cwd: seeded.repoPath,
|
|
workspaceId: seeded.workspaceId,
|
|
title: AGENT_TITLE,
|
|
});
|
|
|
|
await gotoAppShell(page);
|
|
await addOfflineHostAndReload(page, {
|
|
serverId: SECONDARY_HOST_ID,
|
|
label: "Secondary Host",
|
|
primaryLabel: PRIMARY_HOST_LABEL,
|
|
});
|
|
|
|
const panel = await openCommandCenter(page);
|
|
const row = panel.getByTestId(
|
|
`command-center-workspace-${getServerId()}:${seeded.workspaceId}`,
|
|
);
|
|
await expect(row).toBeVisible({ timeout: 30_000 });
|
|
await expect(row).toContainText(WORKSPACE_TITLE);
|
|
await expect(row).toContainText(WORKSPACE_BRANCH);
|
|
|
|
// The subtitle disambiguates by project: host · project · branch (multi-host).
|
|
const subtitle = row.getByTestId("command-center-workspace-subtitle");
|
|
await expect(subtitle).toContainText(PRIMARY_HOST_LABEL);
|
|
await expect(subtitle).toContainText(seeded.projectDisplayName);
|
|
await expect(subtitle).toContainText(WORKSPACE_BRANCH);
|
|
|
|
// The agent subtitle is unchanged by the shared-helper refactor.
|
|
const agentRow = panel.getByTestId(`command-center-agent-${getServerId()}:${agent.id}`);
|
|
await expect(agentRow).toContainText(AGENT_TITLE);
|
|
await expect(agentRow).toContainText(PRIMARY_HOST_LABEL);
|
|
await expect(agentRow).toContainText(WORKSPACE_TITLE);
|
|
await expect(agentRow).not.toContainText(seeded.repoPath);
|
|
|
|
const workspaceSectionTop = await panel
|
|
.getByText("Workspaces", { exact: true })
|
|
.evaluate((element) => element.getBoundingClientRect().top);
|
|
const agentSectionTop = await panel
|
|
.getByText("Agents", { exact: true })
|
|
.evaluate((element) => element.getBoundingClientRect().top);
|
|
expect(workspaceSectionTop).toBeLessThan(agentSectionTop);
|
|
|
|
const input = panel.getByTestId("command-center-input");
|
|
await input.fill(PRIMARY_HOST_LABEL);
|
|
await expect(row).toBeVisible();
|
|
await expect(agentRow).toBeVisible();
|
|
|
|
await input.fill(WORKSPACE_BRANCH);
|
|
await expect(row).toBeVisible();
|
|
await expect(agentRow).not.toBeVisible();
|
|
|
|
await input.fill(WORKSPACE_TITLE);
|
|
await expect(row).toBeVisible();
|
|
await expect(agentRow).toBeVisible();
|
|
|
|
await input.fill(seeded.repoPath);
|
|
await expect(agentRow).toBeVisible();
|
|
await expect(row).not.toBeVisible();
|
|
|
|
// The project name is now part of the workspace searchText.
|
|
await input.fill(seeded.projectDisplayName);
|
|
await expect(row).toBeVisible();
|
|
|
|
await input.fill(AGENT_TITLE);
|
|
await expect(agentRow).toBeVisible();
|
|
await expect(row).not.toBeVisible();
|
|
|
|
await input.fill(WORKSPACE_TITLE);
|
|
await page.keyboard.press("Enter");
|
|
|
|
await expectAppRoute(page, buildHostWorkspaceRoute(getServerId(), seeded.workspaceId), {
|
|
timeout: 30_000,
|
|
});
|
|
} finally {
|
|
await seeded.cleanup();
|
|
}
|
|
});
|
|
|
|
test("single-host workspace subtitle omits the host and shows project · branch", async ({
|
|
page,
|
|
}) => {
|
|
const seeded = await seedWorkspace({
|
|
repoPrefix: "command-center-workspace-single-",
|
|
title: WORKSPACE_TITLE,
|
|
});
|
|
|
|
try {
|
|
execFileSync("git", ["checkout", "-b", WORKSPACE_BRANCH], {
|
|
cwd: seeded.repoPath,
|
|
stdio: "ignore",
|
|
});
|
|
const refreshed = await seeded.client.checkoutRefresh(seeded.repoPath);
|
|
if (!refreshed.success) {
|
|
throw new Error(`Failed to refresh checkout: ${JSON.stringify(refreshed.error)}`);
|
|
}
|
|
|
|
// No secondary host: with a single host, the host label is gated away.
|
|
await gotoAppShell(page);
|
|
|
|
const panel = await openCommandCenter(page);
|
|
const row = panel.getByTestId(
|
|
`command-center-workspace-${getServerId()}:${seeded.workspaceId}`,
|
|
);
|
|
await expect(row).toBeVisible({ timeout: 30_000 });
|
|
|
|
const subtitle = row.getByTestId("command-center-workspace-subtitle");
|
|
await expect(subtitle).toHaveText(`${seeded.projectDisplayName} · ${WORKSPACE_BRANCH}`);
|
|
} finally {
|
|
await seeded.cleanup();
|
|
}
|
|
});
|
|
});
|