fix(app): make session rename reachable in the mobile sessions dropdown (#2924)
* fix(app): make session rename reachable in the mobile sessions dropdown The per-session actions menu in the mobile tab switcher (a gorhom bottom sheet) opened as an anchored popover, which on native renders a second RN Modal stacked on the sheet — the fragile nested-overlay case docs/floating-panels.md warns about. The actions menu (incl. Rename) never appeared on native, so sessions could not be renamed from the dropdown. Give the menu compactMode="sheet" like every other mobile menu in the file, so it stacks as a gorhom sheet on a gorhom sheet (the supported path). Extract the accessory into workspace-tab-trailing-accessory.tsx and add a reachability test that fails if the sheet presentation regresses. * test(app): cover compact session rename via the tab switcher e2e Adds a Playwright spec that drives the mobile-viewport sessions dropdown -> per-session actions sheet -> Rename, exercising the real gorhom sheet interaction the fix restores (the desktop rename specs only cover the right-click context menu, and the unit test mocks the menu engine). --------- Co-authored-by: Klaude <klaude@Klaudes-MacBook-Pro.local> Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
co-authored by
Klaude
Mohamed Boudra
parent
1e0ce69c54
commit
49b257c55a
@@ -0,0 +1,76 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { test, expect } from "../support/fixtures";
|
||||
import { openAgentRoute, seedMockAgentWorkspace } from "../support/helpers/mock-agent";
|
||||
import { renameModalInput, renameModalSubmit } from "../support/helpers/rename";
|
||||
import type { SeedDaemonClient } from "../support/helpers/seed-client";
|
||||
|
||||
const MOBILE_VIEWPORT = { width: 390, height: 844 };
|
||||
|
||||
async function fetchAgentTitle(client: SeedDaemonClient, agentId: string): Promise<string | null> {
|
||||
const result = await client.fetchAgents({ scope: "active" });
|
||||
return result.entries.find((entry) => entry.agent.id === agentId)?.agent.title ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compact "sessions dropdown" rename path. The desktop rename specs drive the right-click
|
||||
* `workspace-tab-context-*` menu, which portals into overlay-root and was never broken. This
|
||||
* exercises the tab switcher's per-session actions on a phone-sized viewport — the path that
|
||||
* regressed when the actions menu presented as a popover instead of a bottom sheet.
|
||||
*/
|
||||
test.describe("Workspace session rename (compact tab switcher)", () => {
|
||||
test("renames an agent session from the switcher's per-session actions sheet", async ({
|
||||
page,
|
||||
}) => {
|
||||
test.setTimeout(120_000);
|
||||
|
||||
await page.setViewportSize(MOBILE_VIEWPORT);
|
||||
const initialTitle = `switcher-rename-${randomUUID().slice(0, 8)}`;
|
||||
const session = await seedMockAgentWorkspace({
|
||||
repoPrefix: "workspace-switcher-rename-",
|
||||
title: initialTitle,
|
||||
});
|
||||
|
||||
try {
|
||||
await openAgentRoute(page, session);
|
||||
await expect(page.getByTestId("workspace-tab-switcher-trigger")).toBeVisible({
|
||||
timeout: 30_000,
|
||||
});
|
||||
|
||||
// Open the sessions dropdown (a bottom sheet on compact).
|
||||
await page.getByRole("button", { name: /Switch tabs/ }).click();
|
||||
await expect(page.getByRole("button", { name: "Bottom sheet backdrop" }).first()).toBeVisible(
|
||||
{
|
||||
timeout: 10_000,
|
||||
},
|
||||
);
|
||||
|
||||
// Open this session's "…" actions. Before the fix this tried to open a popover-Modal
|
||||
// that never surfaced over the sheet on native; it now opens as a stacked sheet.
|
||||
const menuBase = `workspace-tab-menu-agent_${session.agentId}`;
|
||||
const actionsTrigger = page.getByTestId(`${menuBase}-trigger`);
|
||||
await expect(actionsTrigger).toBeVisible({ timeout: 15_000 });
|
||||
await actionsTrigger.click();
|
||||
|
||||
const renameItem = page.getByTestId(`${menuBase}-rename`);
|
||||
await expect(renameItem).toBeVisible({ timeout: 10_000 });
|
||||
await renameItem.click();
|
||||
|
||||
const modalPrefix = `workspace-tab-rename-modal-agent-${session.agentId}`;
|
||||
const input = renameModalInput(page, modalPrefix);
|
||||
await expect(input).toBeVisible({ timeout: 10_000 });
|
||||
await expect(input).toHaveValue(initialTitle);
|
||||
|
||||
const renamed = "Renamed from the dropdown";
|
||||
await input.fill(renamed);
|
||||
await renameModalSubmit(page, modalPrefix).click();
|
||||
|
||||
await expect(input).toHaveCount(0, { timeout: 15_000 });
|
||||
await expect(page.getByTestId("workspace-tab-switcher-trigger")).toContainText(renamed, {
|
||||
timeout: 15_000,
|
||||
});
|
||||
await expect.poll(() => fetchAgentTitle(session.client, session.agentId)).toBe(renamed);
|
||||
} finally {
|
||||
await session.cleanup();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user