From f5526b075c4438d9c582ba9cdaba6e415cf00ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Fri, 9 Oct 2026 07:51:39 -0400 Subject: [PATCH] Q185: switching company carries no focus, search or form from the previous company Co-Authored-By: Claude Opus 5.5 --- src/renderer/src/app/App.tsx | 6 +++-- src/renderer/src/shared/Shell.tsx | 3 ++- tests/e2e/company-switch.spec.ts | 41 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/company-switch.spec.ts diff --git a/src/renderer/src/app/App.tsx b/src/renderer/src/app/App.tsx index eef48c44..8158d1cc 100644 --- a/src/renderer/src/app/App.tsx +++ b/src/renderer/src/app/App.tsx @@ -29,7 +29,8 @@ const isRoute = oneOf(ROUTE_IDS); export function App() { const { snapshot, syncFailure, actions } = useSnapshot(); const [routeChoice, setRoute] = useState(null); - const [focus, setFocus] = useState(null); + // A focus belongs to the company it was opened in; another company's page never receives it. + const [focusChoice, setFocus] = useState<{ orgId: string | null; focus: Focus } | null>(null); // Leaving a page with input that would be lost asks first. const [leaving, setLeaving] = useState<{ proceed: () => void } | null>(null); const requestLeave = (proceed: () => void) => { @@ -40,7 +41,7 @@ export function App() { const navigate = (next: RouteId, nextFocus?: Focus) => requestLeave(() => { setRoute(next); writeViewState("route", next); - setFocus(nextFocus ?? null); + setFocus(nextFocus ? { orgId: snapshot?.activeOrgId ?? null, focus: nextFocus } : null); }); const avatarDirectory = useMemo(() => { // Scope the directory to the active organization: names are only unique @@ -97,6 +98,7 @@ export function App() { ); } + const focus = focusChoice && focusChoice.orgId === snapshot.activeOrgId ? focusChoice.focus : null; const pageProps = { snapshot, actions, navigate, focus }; const page = { home: , diff --git a/src/renderer/src/shared/Shell.tsx b/src/renderer/src/shared/Shell.tsx index 2e3747ac..90eae97b 100644 --- a/src/renderer/src/shared/Shell.tsx +++ b/src/renderer/src/shared/Shell.tsx @@ -123,7 +123,7 @@ export function Shell({ - {profileOpen && setProfileOpen(false)} />} + {profileOpen && setProfileOpen(false)} />}
{organization.name} @@ -159,6 +159,7 @@ export function Shell({
setSearchOpen(false)} diff --git a/tests/e2e/company-switch.spec.ts b/tests/e2e/company-switch.spec.ts new file mode 100644 index 00000000..062225d2 --- /dev/null +++ b/tests/e2e/company-switch.spec.ts @@ -0,0 +1,41 @@ +import { _electron as electron, expect, test } from "@playwright/test"; +import { mkdirSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import { randomUUID } from "node:crypto"; +import { seedBuiltinSkillsFixture } from "./builtin-skills-fixture"; +import { closeApp, onboard } from "./onboard"; + +test("switching company leaves nothing of the previous company on screen", async () => { + const profileDir = join(tmpdir(), `agentcompany-new-e2e-switch-${randomUUID()}`); + mkdirSync(profileDir, { recursive: true }); + const builtinDir = seedBuiltinSkillsFixture(join(tmpdir(), `agentcompany-new-e2e-switch-builtin-${randomUUID()}`)); + const app = await electron.launch({ + args: [resolve("out/main/index.js")], + env: { ...process.env, AGENTCOMPANY_NEW_PROFILE_DIR: profileDir, AGENTCOMPANY_NEW_AUTORUN: "0", AGENTCOMPANY_NEW_BUILTIN_SKILLS_DIR: builtinDir }, + }); + try { + const page = await app.firstWindow(); + await onboard(page, "Alpha Co"); + const searchBox = page.getByRole("dialog", { name: "Search" }).getByRole("textbox"); + await page.locator(".search-kbd").click(); + await searchBox.fill("Alpha search"); + await page.keyboard.press("Escape"); + + await page.getByRole("button", { name: "Alpha Co — switch organization" }).click(); + await page.getByRole("menuitem", { name: "New organization" }).click(); + await onboard(page, "Beta Co"); + await expect(page.getByRole("button", { name: "Beta Co — switch organization" })).toBeVisible(); + // Switching back keeps the shell on screen, yet search opens fresh in the other company. + await page.locator(".search-kbd").click(); + await searchBox.fill("Beta search"); + await page.keyboard.press("Escape"); + await page.getByRole("button", { name: "Beta Co — switch organization" }).click(); + await page.getByRole("menuitem", { name: /Alpha Co/ }).click(); + await expect(page.getByRole("button", { name: "Alpha Co — switch organization" })).toBeVisible(); + await page.locator(".search-kbd").click(); + await expect(searchBox).toHaveValue(""); + } finally { + await closeApp(app); + } +});