From dc5640d12742ba66aedd67b5dcf5813fed5b3e85 Mon Sep 17 00:00:00 2001 From: terminalchai Date: Mon, 13 Apr 2026 02:45:08 +0530 Subject: [PATCH] fix(app): preserve draft through permission prompts --- .../e2e/session/session-composer-dock.spec.ts | 52 +++++++++++++++++-- .../composer/session-composer-region.tsx | 9 +++- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/packages/app/e2e/session/session-composer-dock.spec.ts b/packages/app/e2e/session/session-composer-dock.spec.ts index ecacea83dcb8..f3a1f3e2b34b 100644 --- a/packages/app/e2e/session/session-composer-dock.spec.ts +++ b/packages/app/e2e/session/session-composer-dock.spec.ts @@ -77,7 +77,7 @@ async function setAutoAccept(page: any, enabled: boolean) { async function expectQuestionBlocked(page: any) { await expect(page.locator(questionDockSelector)).toBeVisible() - await expect(page.locator(promptSelector)).toHaveCount(0) + await expect(page.locator(promptSelector)).toBeHidden() } async function expectQuestionOpen(page: any) { @@ -87,7 +87,7 @@ async function expectQuestionOpen(page: any) { async function expectPermissionBlocked(page: any) { await expect(page.locator(permissionDockSelector)).toBeVisible() - await expect(page.locator(promptSelector)).toHaveCount(0) + await expect(page.locator(promptSelector)).toBeHidden() } async function expectPermissionOpen(page: any) { @@ -269,6 +269,9 @@ async function withMockPermission( } } +const promptText = async (page: any) => + ((await page.locator(promptSelector).textContent()) ?? "").replace(/\u200B/g, "").trim() + test("default dock shows prompt input", async ({ page, project }) => { await project.open() await withDockSession( @@ -486,6 +489,49 @@ test("blocked permission flow supports allow always", async ({ page, project }) ) }) +test("blocked permission flow preserves typed draft", async ({ page, project }) => { + await project.open() + await withDockSession( + project.sdk, + "e2e composer dock permission preserves draft", + async (session) => { + await project.gotoSession(session.id) + await setAutoAccept(page, false) + + const value = `followup ${Date.now()}` + const prompt = page.locator(promptSelector) + + await prompt.click() + await page.keyboard.type(value) + await expect.poll(() => promptText(page)).toBe(value) + + await withMockPermission( + page, + { + id: "per_e2e_preserve_draft", + sessionID: session.id, + permission: "bash", + patterns: ["/tmp/opencode-e2e-preserve-draft"], + metadata: { description: "Need permission while draft exists" }, + }, + undefined, + async (state) => { + await page.goto(page.url()) + await expectPermissionBlocked(page) + + await clearPermissionDock(page, /allow once/i) + await state.resolved() + await page.goto(page.url()) + + await expectPermissionOpen(page) + await expect.poll(() => promptText(page)).toBe(value) + }, + ) + }, + { trackSession: project.trackSession }, + ) +}) + test("child session question request blocks parent dock and unblocks after submit", async ({ page, llm, project }) => { const questions = [ { @@ -647,7 +693,7 @@ test("keyboard focus stays off prompt while blocked", async ({ page, llm, projec await page.locator("main").click({ position: { x: 5, y: 5 } }) await page.keyboard.type("abc") - await expect(page.locator(promptSelector)).toHaveCount(0) + await expect(page.locator(promptSelector)).toBeHidden() }) }, { trackSession: project.trackSession }, diff --git a/packages/app/src/pages/session/composer/session-composer-region.tsx b/packages/app/src/pages/session/composer/session-composer-region.tsx index 60447566ed01..f3864d82e549 100644 --- a/packages/app/src/pages/session/composer/session-composer-region.tsx +++ b/packages/app/src/pages/session/composer/session-composer-region.tsx @@ -249,7 +249,12 @@ export function SessionComposerRegion(props: { +
- +
} >