diff --git a/tests/e2e/terminal-attention.spec.ts b/tests/e2e/terminal-attention.spec.ts index d4f1caa87..e12061563 100644 --- a/tests/e2e/terminal-attention.spec.ts +++ b/tests/e2e/terminal-attention.spec.ts @@ -78,11 +78,13 @@ async function activateTerminalTab(page: Page, tabId: string): Promise { } async function emitBell(page: Page, ptyId: string): Promise { - // Why: `tput bel` is the canonical way to emit BEL from the shell — this is - // the exact command the user will run to reproduce the attention path. Prefer - // it over `node -e` so the test exercises the same PTY byte stream a real - // user sees. - await execInTerminal(page, ptyId, `tput bel`) + // Why: `printf '\a'` emits a raw BEL byte without depending on terminfo or + // PATH-resolved binaries. CI shells can launch with a stripped PATH that + // excludes `/usr/bin`, breaking `tput` and silently emitting nothing — + // the `bash: groups: command not found` startup output in failure + // snapshots is the same symptom. printf is a shell builtin, so it works + // even when the PATH is broken. + await execInTerminal(page, ptyId, `printf '\\a'`) } async function proveShellReadyWithSingleWrite(page: Page, ptyId: string): Promise { @@ -182,11 +184,9 @@ test.describe('Terminal attention', () => { // async PTY pipeline. await emitBell(orcaPage, activePtyId) const MARKER_TITLE = 'focused-tab-bell-marker' - await execInTerminal( - orcaPage, - activePtyId, - `node -e "process.stdout.write('\\u001b]0;${MARKER_TITLE}\\u0007')"` - ) + // Why: printf is a shell builtin so it works even when CI launches the + // shell with a stripped PATH (no /usr/bin → no `node` resolvable). + await execInTerminal(orcaPage, activePtyId, `printf '\\033]0;${MARKER_TITLE}\\007'`) await expect .poll(