summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/testing
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-13 08:56:48 -0500
committerGitHub <[email protected]>2026-03-13 08:56:48 -0500
commitc9e9dbeee1ceb5af3d1b1ce292317390286fe7a0 (patch)
treee679df64078db58eadb3cba2d1ac65b170175360 /packages/app/src/testing
parentb88b323049ed7ad7bf41fbec6ce66247ec4047ab (diff)
downloadopencode-c9e9dbeee1ceb5af3d1b1ce292317390286fe7a0.tar.gz
opencode-c9e9dbeee1ceb5af3d1b1ce292317390286fe7a0.zip
fix(app): terminal cloning without retry (#17354)
Diffstat (limited to 'packages/app/src/testing')
-rw-r--r--packages/app/src/testing/terminal.ts63
1 files changed, 48 insertions, 15 deletions
diff --git a/packages/app/src/testing/terminal.ts b/packages/app/src/testing/terminal.ts
index aa1974404..4c179dee3 100644
--- a/packages/app/src/testing/terminal.ts
+++ b/packages/app/src/testing/terminal.ts
@@ -2,21 +2,28 @@ export const terminalAttr = "data-pty-id"
export type TerminalProbeState = {
connected: boolean
+ connects: number
rendered: string
settled: number
}
+type TerminalProbeControl = {
+ disconnect?: VoidFunction
+}
+
export type E2EWindow = Window & {
__opencode_e2e?: {
terminal?: {
enabled?: boolean
terminals?: Record<string, TerminalProbeState>
+ controls?: Record<string, TerminalProbeControl>
}
}
}
const seed = (): TerminalProbeState => ({
connected: false,
+ connects: 0,
rendered: "",
settled: 0,
})
@@ -25,15 +32,28 @@ const root = () => {
if (typeof window === "undefined") return
const state = (window as E2EWindow).__opencode_e2e?.terminal
if (!state?.enabled) return
+ return state
+}
+
+const terms = () => {
+ const state = root()
+ if (!state) return
state.terminals ??= {}
return state.terminals
}
+const controls = () => {
+ const state = root()
+ if (!state) return
+ state.controls ??= {}
+ return state.controls
+}
+
export const terminalProbe = (id: string) => {
const set = (next: Partial<TerminalProbeState>) => {
- const terms = root()
- if (!terms) return
- terms[id] = { ...(terms[id] ?? seed()), ...next }
+ const state = terms()
+ if (!state) return
+ state[id] = { ...(state[id] ?? seed()), ...next }
}
return {
@@ -41,24 +61,37 @@ export const terminalProbe = (id: string) => {
set(seed())
},
connect() {
- set({ connected: true })
+ const state = terms()
+ if (!state) return
+ const prev = state[id] ?? seed()
+ state[id] = {
+ ...prev,
+ connected: true,
+ connects: prev.connects + 1,
+ }
},
render(data: string) {
- const terms = root()
- if (!terms) return
- const prev = terms[id] ?? seed()
- terms[id] = { ...prev, rendered: prev.rendered + data }
+ const state = terms()
+ if (!state) return
+ const prev = state[id] ?? seed()
+ state[id] = { ...prev, rendered: prev.rendered + data }
},
settle() {
- const terms = root()
- if (!terms) return
- const prev = terms[id] ?? seed()
- terms[id] = { ...prev, settled: prev.settled + 1 }
+ const state = terms()
+ if (!state) return
+ const prev = state[id] ?? seed()
+ state[id] = { ...prev, settled: prev.settled + 1 }
+ },
+ control(next: Partial<TerminalProbeControl>) {
+ const state = controls()
+ if (!state) return
+ state[id] = { ...(state[id] ?? {}), ...next }
},
drop() {
- const terms = root()
- if (!terms) return
- delete terms[id]
+ const state = terms()
+ if (state) delete state[id]
+ const control = controls()
+ if (control) delete control[id]
},
}
}