diff options
| author | Dax Raad <[email protected]> | 2026-04-14 23:10:07 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2026-04-14 23:10:25 -0400 |
| commit | 627159acac04409d7697a6739e2c572c2a010943 (patch) | |
| tree | 5f87465ea69f41aff0cd96ae5411fe438da480b3 /packages/app/e2e/projects | |
| parent | f44aa02e2677b2b89a1a9f517c0ff8990383deaa (diff) | |
| download | opencode-627159acac04409d7697a6739e2c572c2a010943.tar.gz opencode-627159acac04409d7697a6739e2c572c2a010943.zip | |
delete all e2e tests (#22501)
Cherry-picked from ea463e604cdd2a3e83e1c286e39b789455f0d413
Diffstat (limited to 'packages/app/e2e/projects')
| -rw-r--r-- | packages/app/e2e/projects/project-edit.spec.ts | 49 | ||||
| -rw-r--r-- | packages/app/e2e/projects/projects-close.spec.ts | 49 | ||||
| -rw-r--r-- | packages/app/e2e/projects/projects-switch.spec.ts | 94 | ||||
| -rw-r--r-- | packages/app/e2e/projects/workspace-new-session.spec.ts | 78 | ||||
| -rw-r--r-- | packages/app/e2e/projects/workspaces.spec.ts | 368 |
5 files changed, 0 insertions, 638 deletions
diff --git a/packages/app/e2e/projects/project-edit.spec.ts b/packages/app/e2e/projects/project-edit.spec.ts deleted file mode 100644 index 1ffe4219d..000000000 --- a/packages/app/e2e/projects/project-edit.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, expect } from "../fixtures" -import { clickMenuItem, openProjectMenu, openSidebar } from "../actions" - -test("dialog edit project updates name and startup script", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - await project.open() - await openSidebar(page) - - const open = async () => { - const menu = await openProjectMenu(page, project.slug) - await clickMenuItem(menu, /^Edit$/i, { force: true }) - - const dialog = page.getByRole("dialog") - await expect(dialog).toBeVisible() - await expect(dialog.getByRole("heading", { level: 2 })).toHaveText("Edit project") - return dialog - } - - const name = `e2e project ${Date.now()}` - const startup = `echo e2e_${Date.now()}` - - const dialog = await open() - - const nameInput = dialog.getByLabel("Name") - await nameInput.fill(name) - - const startupInput = dialog.getByLabel("Workspace startup script") - await startupInput.fill(startup) - - await dialog.getByRole("button", { name: "Save" }).click() - await expect(dialog).toHaveCount(0) - - await expect - .poll( - async () => { - await page.reload() - await openSidebar(page) - const reopened = await open() - const value = await reopened.getByLabel("Name").inputValue() - const next = await reopened.getByLabel("Workspace startup script").inputValue() - await reopened.getByRole("button", { name: "Cancel" }).click() - await expect(reopened).toHaveCount(0) - return `${value}\n${next}` - }, - { timeout: 30_000 }, - ) - .toBe(`${name}\n${startup}`) -}) diff --git a/packages/app/e2e/projects/projects-close.spec.ts b/packages/app/e2e/projects/projects-close.spec.ts deleted file mode 100644 index 75e6f2ce6..000000000 --- a/packages/app/e2e/projects/projects-close.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, expect } from "../fixtures" -import { createTestProject, cleanupTestProject, openSidebar, clickMenuItem, openProjectMenu } from "../actions" -import { projectSwitchSelector } from "../selectors" -import { dirSlug } from "../utils" - -test("closing active project navigates to another open project", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - const other = await createTestProject() - const otherSlug = dirSlug(other) - - try { - await project.open({ extra: [other] }) - await openSidebar(page) - - const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() - await expect(otherButton).toBeVisible() - await otherButton.click() - - await expect(page).toHaveURL(new RegExp(`/${otherSlug}/session`)) - - const menu = await openProjectMenu(page, otherSlug) - await clickMenuItem(menu, /^Close$/i, { force: true }) - - await expect - .poll( - () => { - const pathname = new URL(page.url()).pathname - if (new RegExp(`^/${project.slug}/session(?:/[^/]+)?/?$`).test(pathname)) return "project" - if (pathname === "/") return "home" - return "" - }, - { timeout: 15_000 }, - ) - .toMatch(/^(project|home)$/) - - await expect(page).not.toHaveURL(new RegExp(`/${otherSlug}/session(?:[/?#]|$)`)) - await expect - .poll( - async () => { - return await page.locator(projectSwitchSelector(otherSlug)).count() - }, - { timeout: 15_000 }, - ) - .toBe(0) - } finally { - await cleanupTestProject(other) - } -}) diff --git a/packages/app/e2e/projects/projects-switch.spec.ts b/packages/app/e2e/projects/projects-switch.spec.ts deleted file mode 100644 index 67d09afd1..000000000 --- a/packages/app/e2e/projects/projects-switch.spec.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { base64Decode } from "@opencode-ai/util/encode" -import { test, expect } from "../fixtures" -import { - defocus, - createTestProject, - cleanupTestProject, - openSidebar, - setWorkspacesEnabled, - waitSession, - waitSlug, -} from "../actions" -import { projectSwitchSelector, workspaceItemSelector, workspaceNewSessionSelector } from "../selectors" -import { dirSlug, resolveDirectory } from "../utils" - -test("can switch between projects from sidebar", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - const other = await createTestProject() - const otherSlug = dirSlug(other) - - try { - await project.open({ extra: [other] }) - await defocus(page) - - const currentSlug = dirSlug(project.directory) - const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() - await expect(otherButton).toBeVisible() - await otherButton.click() - - await expect(page).toHaveURL(new RegExp(`/${otherSlug}/session`)) - - const currentButton = page.locator(projectSwitchSelector(currentSlug)).first() - await expect(currentButton).toBeVisible() - await currentButton.click() - - await expect(page).toHaveURL(new RegExp(`/${currentSlug}/session`)) - } finally { - await cleanupTestProject(other) - } -}) - -test("switching back to a project opens the latest workspace session", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - const other = await createTestProject() - const otherSlug = dirSlug(other) - try { - await project.open({ extra: [other] }) - await defocus(page) - await setWorkspacesEnabled(page, project.slug, true) - await openSidebar(page) - await expect(page.getByRole("button", { name: "New workspace" }).first()).toBeVisible() - - await page.getByRole("button", { name: "New workspace" }).first().click() - - const raw = await waitSlug(page, [project.slug]) - const dir = base64Decode(raw) - if (!dir) throw new Error(`Failed to decode workspace slug: ${raw}`) - const space = await resolveDirectory(dir) - const next = dirSlug(space) - project.trackDirectory(space) - await openSidebar(page) - - const item = page.locator(`${workspaceItemSelector(next)}, ${workspaceItemSelector(raw)}`).first() - await expect(item).toBeVisible() - await item.hover() - - const btn = page.locator(`${workspaceNewSessionSelector(next)}, ${workspaceNewSessionSelector(raw)}`).first() - await expect(btn).toBeVisible() - await btn.click({ force: true }) - - await waitSession(page, { directory: space }) - - const created = await project.user("test") - - await expect(page).toHaveURL(new RegExp(`/${next}/session/${created}(?:[/?#]|$)`)) - - await openSidebar(page) - - const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() - await expect(otherButton).toBeVisible() - await otherButton.click({ force: true }) - await waitSession(page, { directory: other }) - - const rootButton = page.locator(projectSwitchSelector(project.slug)).first() - await expect(rootButton).toBeVisible() - await rootButton.click({ force: true }) - - await waitSession(page, { directory: space, sessionID: created }) - await expect(page).toHaveURL(new RegExp(`/session/${created}(?:[/?#]|$)`)) - } finally { - await cleanupTestProject(other) - } -}) diff --git a/packages/app/e2e/projects/workspace-new-session.spec.ts b/packages/app/e2e/projects/workspace-new-session.spec.ts deleted file mode 100644 index d9d010b4d..000000000 --- a/packages/app/e2e/projects/workspace-new-session.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { Page } from "@playwright/test" -import { test, expect } from "../fixtures" -import { - openSidebar, - resolveSlug, - sessionIDFromUrl, - setWorkspacesEnabled, - waitDir, - waitSession, - waitSlug, -} from "../actions" -import { workspaceItemSelector, workspaceNewSessionSelector } from "../selectors" - -function item(space: { slug: string; raw: string }) { - return `${workspaceItemSelector(space.slug)}, ${workspaceItemSelector(space.raw)}` -} - -function button(space: { slug: string; raw: string }) { - return `${workspaceNewSessionSelector(space.slug)}, ${workspaceNewSessionSelector(space.raw)}` -} - -async function waitWorkspaceReady(page: Page, space: { slug: string; raw: string }) { - await openSidebar(page) - await expect(page.locator(item(space)).first()).toBeVisible({ timeout: 60_000 }) -} - -async function createWorkspace(page: Page, root: string, seen: string[]) { - await openSidebar(page) - await page.getByRole("button", { name: "New workspace" }).first().click() - - const next = await resolveSlug(await waitSlug(page, [root, ...seen])) - await waitDir(page, next.directory) - return next -} - -async function openWorkspaceNewSession(page: Page, space: { slug: string; raw: string; directory: string }) { - await waitWorkspaceReady(page, space) - - const row = page.locator(item(space)).first() - await row.hover() - - const next = page.locator(button(space)).first() - await expect(next).toBeVisible() - await next.click({ force: true }) - - await waitSession(page, { directory: space.directory }) - await expect.poll(() => sessionIDFromUrl(page.url()) ?? "").toBe("") -} - -async function createSessionFromWorkspace( - project: Parameters<typeof test>[0]["project"], - page: Page, - space: { slug: string; raw: string; directory: string }, - text: string, -) { - await openWorkspaceNewSession(page, space) - return project.user(text) -} - -test("new sessions from sidebar workspace actions stay in selected workspace", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - await project.open() - await openSidebar(page) - await setWorkspacesEnabled(page, project.slug, true) - - const first = await createWorkspace(page, project.slug, []) - project.trackDirectory(first.directory) - await waitWorkspaceReady(page, first) - - const second = await createWorkspace(page, project.slug, [first.slug]) - project.trackDirectory(second.directory) - await waitWorkspaceReady(page, second) - - await createSessionFromWorkspace(project, page, first, `workspace one ${Date.now()}`) - await createSessionFromWorkspace(project, page, second, `workspace two ${Date.now()}`) - await createSessionFromWorkspace(project, page, first, `workspace one again ${Date.now()}`) -}) diff --git a/packages/app/e2e/projects/workspaces.spec.ts b/packages/app/e2e/projects/workspaces.spec.ts deleted file mode 100644 index 206baa47c..000000000 --- a/packages/app/e2e/projects/workspaces.spec.ts +++ /dev/null @@ -1,368 +0,0 @@ -import fs from "node:fs/promises" -import os from "node:os" -import path from "node:path" -import { base64Decode } from "@opencode-ai/util/encode" -import type { Page } from "@playwright/test" - -import { test, expect } from "../fixtures" - -test.describe.configure({ mode: "serial" }) -import { - cleanupTestProject, - clickMenuItem, - confirmDialog, - openSidebar, - openWorkspaceMenu, - resolveSlug, - setWorkspacesEnabled, - slugFromUrl, - waitDir, - waitSlug, -} from "../actions" -import { inlineInputSelector, workspaceItemSelector } from "../selectors" -import { dirSlug } from "../utils" - -async function setupWorkspaceTest(page: Page, project: { slug: string; trackDirectory: (directory: string) => void }) { - const rootSlug = project.slug - await openSidebar(page) - - await setWorkspacesEnabled(page, rootSlug, true) - - await page.getByRole("button", { name: "New workspace" }).first().click() - const next = await resolveSlug(await waitSlug(page, [rootSlug])) - await waitDir(page, next.directory) - project.trackDirectory(next.directory) - - await openSidebar(page) - - await expect - .poll( - async () => { - const item = page.locator(workspaceItemSelector(next.slug)).first() - try { - await item.hover({ timeout: 500 }) - return true - } catch { - return false - } - }, - { timeout: 60_000 }, - ) - .toBe(true) - - return { rootSlug, slug: next.slug, directory: next.directory } -} - -test("can enable and disable workspaces from project menu", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - - await openSidebar(page) - - await expect(page.getByRole("button", { name: "New session" }).first()).toBeVisible() - await expect(page.getByRole("button", { name: "New workspace" })).toHaveCount(0) - - await setWorkspacesEnabled(page, project.slug, true) - await expect(page.getByRole("button", { name: "New workspace" }).first()).toBeVisible() - await expect(page.locator(workspaceItemSelector(project.slug)).first()).toBeVisible() - - await setWorkspacesEnabled(page, project.slug, false) - await expect(page.getByRole("button", { name: "New session" }).first()).toBeVisible() - await expect(page.locator(workspaceItemSelector(project.slug))).toHaveCount(0) -}) - -test("can create a workspace", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - - await openSidebar(page) - await setWorkspacesEnabled(page, project.slug, true) - - await expect(page.getByRole("button", { name: "New workspace" }).first()).toBeVisible() - - await page.getByRole("button", { name: "New workspace" }).first().click() - const next = await resolveSlug(await waitSlug(page, [project.slug])) - await waitDir(page, next.directory) - project.trackDirectory(next.directory) - - await openSidebar(page) - - await expect - .poll( - async () => { - const item = page.locator(workspaceItemSelector(next.slug)).first() - try { - await item.hover({ timeout: 500 }) - return true - } catch { - return false - } - }, - { timeout: 60_000 }, - ) - .toBe(true) - - await expect(page.locator(workspaceItemSelector(next.slug)).first()).toBeVisible() -}) - -test("non-git projects keep workspace mode disabled", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - - const nonGit = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-e2e-project-nongit-")) - const nonGitSlug = dirSlug(nonGit) - - await fs.writeFile(path.join(nonGit, "README.md"), "# e2e nongit\n") - - try { - await project.open({ extra: [nonGit] }) - await page.goto(`/${nonGitSlug}/session`) - - await expect.poll(() => slugFromUrl(page.url()), { timeout: 30_000 }).not.toBe("") - - const activeDir = await resolveSlug(slugFromUrl(page.url())).then((item) => item.directory) - expect(path.basename(activeDir)).toContain("opencode-e2e-project-nongit-") - - await openSidebar(page) - await expect(page.getByRole("button", { name: "New workspace" })).toHaveCount(0) - await expect(page.getByRole("button", { name: "Create Git repository" })).toBeVisible() - } finally { - await cleanupTestProject(nonGit) - } -}) - -test("can rename a workspace", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - - const { slug } = await setupWorkspaceTest(page, project) - - const rename = `e2e workspace ${Date.now()}` - const menu = await openWorkspaceMenu(page, slug) - await clickMenuItem(menu, /^Rename$/i, { force: true }) - - await expect(menu).toHaveCount(0) - - const item = page.locator(workspaceItemSelector(slug)).first() - await expect(item).toBeVisible() - const input = item.locator(inlineInputSelector).first() - const shown = await input - .isVisible() - .then((x) => x) - .catch(() => false) - if (!shown) { - const retry = await openWorkspaceMenu(page, slug) - await clickMenuItem(retry, /^Rename$/i, { force: true }) - await expect(retry).toHaveCount(0) - } - await expect(input).toBeVisible() - await input.fill(rename) - await input.press("Enter") - await expect(item).toContainText(rename) -}) - -test("can reset a workspace", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - - const { slug, directory: createdDir } = await setupWorkspaceTest(page, project) - - const readme = path.join(createdDir, "README.md") - const extra = path.join(createdDir, `e2e_reset_${Date.now()}.txt`) - const original = await fs.readFile(readme, "utf8") - const dirty = `${original.trimEnd()}\n\nchange_${Date.now()}\n` - await fs.writeFile(readme, dirty, "utf8") - await fs.writeFile(extra, `created_${Date.now()}\n`, "utf8") - - await expect - .poll(async () => { - return await fs - .stat(extra) - .then(() => true) - .catch(() => false) - }) - .toBe(true) - - await expect - .poll(async () => { - const files = await project.sdk.file - .status({ directory: createdDir }) - .then((r) => r.data ?? []) - .catch(() => []) - return files.length - }) - .toBeGreaterThan(0) - - const menu = await openWorkspaceMenu(page, slug) - await clickMenuItem(menu, /^Reset$/i, { force: true }) - await confirmDialog(page, /^Reset workspace$/i) - - await expect - .poll( - async () => { - const files = await project.sdk.file - .status({ directory: createdDir }) - .then((r) => r.data ?? []) - .catch(() => []) - return files.length - }, - { timeout: 120_000 }, - ) - .toBe(0) - - await expect.poll(() => fs.readFile(readme, "utf8"), { timeout: 120_000 }).toBe(original) - - await expect - .poll(async () => { - return await fs - .stat(extra) - .then(() => true) - .catch(() => false) - }) - .toBe(false) -}) - -test("can reorder workspaces by drag and drop", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - const rootSlug = project.slug - - const listSlugs = async () => { - const nodes = page.locator('[data-component="sidebar-nav-desktop"] [data-component="workspace-item"]') - const slugs = await nodes.evaluateAll((els) => { - return els.map((el) => el.getAttribute("data-workspace") ?? "").filter((x) => x.length > 0) - }) - return slugs - } - - const waitReady = async (slug: string) => { - await expect - .poll( - async () => { - const item = page.locator(workspaceItemSelector(slug)).first() - try { - await item.hover({ timeout: 500 }) - return true - } catch { - return false - } - }, - { timeout: 60_000 }, - ) - .toBe(true) - } - - const drag = async (from: string, to: string) => { - const src = page.locator(workspaceItemSelector(from)).first() - const dst = page.locator(workspaceItemSelector(to)).first() - - const a = await src.boundingBox() - const b = await dst.boundingBox() - if (!a || !b) throw new Error("Failed to resolve workspace drag bounds") - - await page.mouse.move(a.x + a.width / 2, a.y + a.height / 2) - await page.mouse.down() - await page.mouse.move(b.x + b.width / 2, b.y + b.height / 2, { steps: 12 }) - await page.mouse.up() - } - - await openSidebar(page) - - await setWorkspacesEnabled(page, rootSlug, true) - - const workspaces = [] as { directory: string; slug: string }[] - for (const _ of [0, 1]) { - const prev = slugFromUrl(page.url()) - await page.getByRole("button", { name: "New workspace" }).first().click() - const next = await resolveSlug(await waitSlug(page, [rootSlug, prev])) - await waitDir(page, next.directory) - project.trackDirectory(next.directory) - workspaces.push(next) - - await openSidebar(page) - } - - if (workspaces.length !== 2) throw new Error("Expected two created workspaces") - - const a = workspaces[0].slug - const b = workspaces[1].slug - - await waitReady(a) - await waitReady(b) - - const list = async () => { - const slugs = await listSlugs() - return slugs.filter((s) => s !== rootSlug && (s === a || s === b)).slice(0, 2) - } - - await expect - .poll(async () => { - const slugs = await list() - return slugs.length === 2 - }) - .toBe(true) - - const before = await list() - const from = before[1] - const to = before[0] - if (!from || !to) throw new Error("Failed to resolve initial workspace order") - - await drag(from, to) - - await expect.poll(async () => await list()).toEqual([from, to]) -}) - -test("can delete a workspace", async ({ page, project }) => { - await page.setViewportSize({ width: 1400, height: 800 }) - await project.open() - - const rootSlug = project.slug - await openSidebar(page) - await setWorkspacesEnabled(page, rootSlug, true) - - const created = await project.sdk.worktree.create({ directory: project.directory }).then((res) => res.data) - if (!created?.directory) throw new Error("Failed to create workspace for delete test") - - const directory = created.directory - const slug = dirSlug(directory) - project.trackDirectory(directory) - - await page.reload() - await openSidebar(page) - await expect(page.locator(workspaceItemSelector(slug)).first()).toBeVisible({ timeout: 60_000 }) - - await expect - .poll( - async () => { - const worktrees = await project.sdk.worktree - .list() - .then((r) => r.data ?? []) - .catch(() => [] as string[]) - return worktrees.includes(directory) - }, - { timeout: 30_000 }, - ) - .toBe(true) - - const menu = await openWorkspaceMenu(page, slug) - await clickMenuItem(menu, /^Delete$/i, { force: true }) - await confirmDialog(page, /^Delete workspace$/i) - - await expect.poll(() => base64Decode(slugFromUrl(page.url()))).toBe(project.directory) - - await expect - .poll( - async () => { - const worktrees = await project.sdk.worktree - .list() - .then((r) => r.data ?? []) - .catch(() => [] as string[]) - return worktrees.includes(directory) - }, - { timeout: 60_000 }, - ) - .toBe(false) - - await openSidebar(page) - await expect(page.locator(workspaceItemSelector(slug))).toHaveCount(0, { timeout: 60_000 }) - await expect(page.locator(workspaceItemSelector(rootSlug)).first()).toBeVisible() -}) |
