summaryrefslogtreecommitdiffhomepage
path: root/packages/app/e2e/terminal
diff options
context:
space:
mode:
authorFilip <[email protected]>2026-03-07 00:08:59 +0100
committerGitHub <[email protected]>2026-03-06 17:08:59 -0600
commitc4fd677785392aa27d0bd3e01cc185d24d7bc7fd (patch)
treeaad2c01f3167a30b38fb5d8f964456358e74d778 /packages/app/e2e/terminal
parent770cb66628244373305f40915409f6cf3522b43e (diff)
downloadopencode-c4fd677785392aa27d0bd3e01cc185d24d7bc7fd.tar.gz
opencode-c4fd677785392aa27d0bd3e01cc185d24d7bc7fd.zip
tests(app): e2e tests part 67 (#16406)
Diffstat (limited to 'packages/app/e2e/terminal')
-rw-r--r--packages/app/e2e/terminal/terminal-tabs.spec.ts120
1 files changed, 120 insertions, 0 deletions
diff --git a/packages/app/e2e/terminal/terminal-tabs.spec.ts b/packages/app/e2e/terminal/terminal-tabs.spec.ts
new file mode 100644
index 000000000..f76a86cf7
--- /dev/null
+++ b/packages/app/e2e/terminal/terminal-tabs.spec.ts
@@ -0,0 +1,120 @@
+import type { Page } from "@playwright/test"
+import { test, expect } from "../fixtures"
+import { terminalSelector } from "../selectors"
+import { terminalToggleKey, workspacePersistKey } from "../utils"
+
+type State = {
+ active?: string
+ all: Array<{
+ id: string
+ title: string
+ titleNumber: number
+ buffer?: string
+ }>
+}
+
+async function open(page: Page) {
+ const terminal = page.locator(terminalSelector)
+ const visible = await terminal.isVisible().catch(() => false)
+ if (!visible) await page.keyboard.press(terminalToggleKey)
+ await expect(terminal).toBeVisible()
+ await expect(terminal.locator("textarea")).toHaveCount(1)
+}
+
+async function run(page: Page, cmd: string) {
+ const terminal = page.locator(terminalSelector)
+ await expect(terminal).toBeVisible()
+ await terminal.click()
+ await page.keyboard.type(cmd)
+ await page.keyboard.press("Enter")
+}
+
+async function store(page: Page, key: string) {
+ return page.evaluate((key) => {
+ const raw = localStorage.getItem(key)
+ if (raw) return JSON.parse(raw) as State
+
+ for (let i = 0; i < localStorage.length; i++) {
+ const next = localStorage.key(i)
+ if (!next?.endsWith(":workspace:terminal")) continue
+ const value = localStorage.getItem(next)
+ if (!value) continue
+ return JSON.parse(value) as State
+ }
+ }, key)
+}
+
+test("terminal tab buffers persist across tab switches", async ({ page, withProject }) => {
+ await withProject(async ({ directory, gotoSession }) => {
+ const key = workspacePersistKey(directory, "terminal")
+ const one = `E2E_TERM_ONE_${Date.now()}`
+ const two = `E2E_TERM_TWO_${Date.now()}`
+ const tabs = page.locator('#terminal-panel [data-slot="tabs-trigger"]')
+
+ await gotoSession()
+ await open(page)
+
+ await run(page, `echo ${one}`)
+
+ await page.getByRole("button", { name: /new terminal/i }).click()
+ await expect(tabs).toHaveCount(2)
+
+ await run(page, `echo ${two}`)
+
+ await tabs
+ .filter({ hasText: /Terminal 1/ })
+ .first()
+ .click()
+
+ await expect
+ .poll(
+ async () => {
+ const state = await store(page, key)
+ const first = state?.all.find((item) => item.titleNumber === 1)?.buffer ?? ""
+ const second = state?.all.find((item) => item.titleNumber === 2)?.buffer ?? ""
+ return first.includes(one) && second.includes(two)
+ },
+ { timeout: 30_000 },
+ )
+ .toBe(true)
+ })
+})
+
+test("closing the active terminal tab falls back to the previous tab", async ({ page, withProject }) => {
+ await withProject(async ({ directory, gotoSession }) => {
+ const key = workspacePersistKey(directory, "terminal")
+ const tabs = page.locator('#terminal-panel [data-slot="tabs-trigger"]')
+
+ await gotoSession()
+ await open(page)
+
+ await page.getByRole("button", { name: /new terminal/i }).click()
+ await expect(tabs).toHaveCount(2)
+
+ const second = tabs.filter({ hasText: /Terminal 2/ }).first()
+ await second.click()
+ await expect(second).toHaveAttribute("aria-selected", "true")
+
+ await second.hover()
+ await page
+ .getByRole("button", { name: /close terminal/i })
+ .nth(1)
+ .click({ force: true })
+
+ const first = tabs.filter({ hasText: /Terminal 1/ }).first()
+ await expect(tabs).toHaveCount(1)
+ await expect(first).toHaveAttribute("aria-selected", "true")
+ await expect
+ .poll(
+ async () => {
+ const state = await store(page, key)
+ return {
+ count: state?.all.length ?? 0,
+ first: state?.all.some((item) => item.titleNumber === 1) ?? false,
+ }
+ },
+ { timeout: 15_000 },
+ )
+ .toEqual({ count: 1, first: true })
+ })
+})