import { base64Encode } from "@opencode-ai/core/util/encode" import { expect, test, type Page } from "@playwright/test" import { mockOpenCodeServer } from "../utils/mock-server" import { expectSessionTitle } from "../utils/waits" const directory = "C:/OpenCode/RequestDocks" const projectID = "proj_request_docks" const sessionID = "ses_request_docks" const title = "Request dock regression" test("shows a pending question dock", async ({ page }) => { await mockServer(page, { questions: [ { id: "question-request", sessionID, questions: [ { header: "Implementation", question: "Which implementation should be used?", options: [ { label: "Minimal", description: "Use the smallest correct change" }, { label: "Extended", description: "Include additional behavior" }, ], }, ], }, ], }) await page.goto(`/${base64Encode(directory)}/session/${sessionID}`) await expectSessionTitle(page, title) const question = page.locator('[data-component="dock-prompt"][data-kind="question"]') await expect(question).toBeVisible() await expect(question.getByText("Which implementation should be used?")).toBeVisible() await expect(question.getByRole("radio", { name: /Minimal/ })).toBeVisible() await expect(question.getByRole("radio", { name: /Extended/ })).toBeVisible() await expect(page.locator('[data-component="session-composer"]')).toHaveCount(0) const rejectRequests: string[] = [] page.on("request", (request) => { if (request.method() !== "POST") return if (new URL(request.url()).pathname === "/question/question-request/reject") rejectRequests.push(request.url()) }) await question.locator('[data-component="icon-button"][data-icon="chevron-down"]').click() await expect(question).toBeVisible() await expect(question.getByText("Which implementation should be used?")).toBeVisible() await expect(question.getByText("Select one answer")).toBeHidden() await expect(question.getByRole("radio", { name: /Minimal/ })).toBeHidden() await expect(question.getByRole("radio", { name: /Extended/ })).toBeHidden() await expect(question.getByRole("button", { name: "Dismiss" })).toBeVisible() await expect(question.getByRole("button", { name: "Submit" })).toBeVisible() await expect(page.locator('[data-component="question-minimized-dock"]')).toHaveCount(0) expect(rejectRequests).toEqual([]) await question.locator('[data-component="icon-button"][data-icon="chevron-down"]').click() await expect(question).toBeVisible() await expect(question.getByText("Which implementation should be used?")).toBeVisible() await expect(question.getByRole("radio", { name: /Minimal/ })).toBeVisible() expect(rejectRequests).toEqual([]) await question.getByRole("radio", { name: /Minimal/ }).click() const reply = page.waitForRequest( (request) => request.method() === "POST" && new URL(request.url()).pathname === "/question/question-request/reply", ) await question.getByRole("button", { name: "Submit" }).click() expect((await reply).postDataJSON()).toEqual({ answers: [["Minimal"]] }) }) test("shows a pending permission dock", async ({ page }) => { await mockServer(page, { permissions: [ { id: "permission-request", sessionID, permission: "bash", patterns: ["git status", "git diff"], metadata: {}, always: [], }, ], }) await page.goto(`/${base64Encode(directory)}/session/${sessionID}`) await expectSessionTitle(page, title) const permission = page.locator('[data-component="dock-prompt"][data-kind="permission"]') await expect(permission).toBeVisible() await expect(permission.getByText("git status")).toBeVisible() await expect(permission.getByText("git diff")).toBeVisible() await expect(permission.locator('[data-slot="permission-footer-actions"] button')).toHaveCount(3) await expect(page.locator('[data-component="session-composer"]')).toHaveCount(0) const reply = page.waitForRequest((request) => request.method() === "POST") await permission.getByRole("button", { name: "Allow once" }).click() const request = await reply expect(new URL(request.url()).pathname).toBe(`/session/${sessionID}/permissions/permission-request`) expect(request.postDataJSON()).toEqual({ response: "once" }) }) async function mockServer( page: Page, requests: { permissions?: unknown[] | (() => unknown[]) questions?: unknown[] | (() => unknown[]) }, ) { await mockOpenCodeServer(page, { directory, project: { id: projectID, worktree: directory, vcs: "git", name: "request-docks", time: { created: 1700000000000, updated: 1700000000000 }, sandboxes: [], }, provider: { all: [ { id: "opencode", name: "OpenCode", models: { "claude-opus-4-6": { id: "claude-opus-4-6", name: "Claude Opus 4.6", limit: { context: 200_000 }, }, }, }, ], connected: ["opencode"], default: { providerID: "opencode", modelID: "claude-opus-4-6" }, }, sessions: [ { id: sessionID, slug: "request-docks", projectID, directory, title, version: "dev", time: { created: 1700000000000, updated: 1700000000000 }, }, ], pageMessages: () => ({ items: [] }), permissions: requests.permissions, questions: requests.questions, }) await page.addInitScript(() => { localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: true } })) }) }