Files
paseo/packages/app/e2e/browser/workspace-tab-switcher-rename.spec.ts
T
49b257c55a 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>
2026-08-08 21:12:16 +00:00

77 lines
3.2 KiB
TypeScript

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();
}
});
});