import { expect, test } from "../support/fixtures"; import { gotoAppShell } from "../support/helpers/app"; import { getE2EDaemonPort } from "../support/helpers/daemon-port"; import { expectNewWorkspaceDraft, expectNewWorkspaceProjectSelected, fillNewWorkspaceDraft, openGlobalNewWorkspaceComposer, openNewWorkspaceComposer, selectNewWorkspaceHost, selectNewWorkspaceProject, } from "../support/helpers/new-workspace"; import { seedWorkspace, type SeededWorkspace } from "../support/helpers/seed-client"; import { getServerId } from "../support/helpers/server-id"; import { seedSavedSettingsHosts } from "../support/helpers/settings"; import { waitForSidebarHydration } from "../support/helpers/workspace-ui"; const DRAFT = `Please investigate the workspace startup failure. Trace the request from the app through the daemon, preserve the existing behavior, and explain the root cause before making changes.`; test.describe("New workspace composer draft", () => { test.describe.configure({ timeout: 240_000 }); test("keeps the draft when the project changes", async ({ page }) => { const firstProject: SeededWorkspace = await seedWorkspace({ repoPrefix: "new-workspace-draft-project-a-", }); const secondProject: SeededWorkspace = await seedWorkspace({ repoPrefix: "new-workspace-draft-project-b-", }); try { await gotoAppShell(page); await waitForSidebarHydration(page); await openNewWorkspaceComposer(page, { projectKey: firstProject.projectKey, projectDisplayName: firstProject.projectDisplayName, }); await expectNewWorkspaceProjectSelected(page, firstProject.projectDisplayName); await fillNewWorkspaceDraft(page, DRAFT); await selectNewWorkspaceProject(page, { projectKey: secondProject.projectKey, projectDisplayName: secondProject.projectDisplayName, }); await expectNewWorkspaceDraft(page, DRAFT); } finally { await secondProject.cleanup(); await firstProject.cleanup(); } }); test("keeps the draft when the host changes", async ({ page }) => { const project: SeededWorkspace = await seedWorkspace({ repoPrefix: "new-workspace-draft-host-", }); const secondaryServerId = "new-workspace-draft-secondary-host"; try { await seedSavedSettingsHosts(page, [ { serverId: getServerId(), label: "Primary host", endpoint: `127.0.0.1:${getE2EDaemonPort()}`, }, { serverId: secondaryServerId, label: "Secondary host", endpoint: "127.0.0.1:9", }, ]); await gotoAppShell(page); await waitForSidebarHydration(page); await openGlobalNewWorkspaceComposer(page); await fillNewWorkspaceDraft(page, DRAFT); await selectNewWorkspaceHost(page, "Secondary host"); await expectNewWorkspaceDraft(page, DRAFT); } finally { await project.cleanup(); } }); test("does not restore a submitted draft after deferred publication", async ({ page }) => { const project = await seedWorkspace({ repoPrefix: "new-workspace-submitted-draft-" }); try { await gotoAppShell(page); await waitForSidebarHydration(page); await openNewWorkspaceComposer(page, { projectKey: project.projectKey, projectDisplayName: project.projectDisplayName, }); const composer = page.getByRole("textbox", { name: "Message agent..." }); const createButton = page.getByTestId("workspace-create-submit"); await expect(composer).toBeEditable({ timeout: 30_000 }); await expect(createButton).toBeEnabled({ timeout: 30_000 }); await composer.evaluate((element, draft) => { if (!(element instanceof HTMLTextAreaElement)) { throw new Error("Composer input is not a textarea"); } const valueSetter = Object.getOwnPropertyDescriptor( HTMLTextAreaElement.prototype, "value", )?.set; if (!valueSetter) throw new Error("Textarea value setter is unavailable"); valueSetter.call(element, draft); element.dispatchEvent( new InputEvent("input", { bubbles: true, data: draft, inputType: "insertText", }), ); const button = document.querySelector('[data-testid="workspace-create-submit"]'); if (!(button instanceof HTMLElement)) { throw new Error("Create button is unavailable"); } button.click(); }, DRAFT); await page.waitForURL((url) => url.pathname.includes("/workspace/"), { timeout: 30_000 }); await openGlobalNewWorkspaceComposer(page); await expectNewWorkspaceDraft(page, ""); } finally { await project.cleanup(); } }); });