From af0437e6df44d619ffa59343cf9f6d6664735c60 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 15 Jun 2026 21:06:35 +0700 Subject: [PATCH] Update terminal activity E2E for finished attention --- packages/app/e2e/helpers/terminal-dsl.ts | 15 ++++++++++++--- .../app/e2e/terminal-activity-indicators.spec.ts | 15 +++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/app/e2e/helpers/terminal-dsl.ts b/packages/app/e2e/helpers/terminal-dsl.ts index 00c40fdcb..90b521c6a 100644 --- a/packages/app/e2e/helpers/terminal-dsl.ts +++ b/packages/app/e2e/helpers/terminal-dsl.ts @@ -1,5 +1,5 @@ import type { Page } from "@playwright/test"; -import type { TerminalActivityState } from "@getpaseo/protocol/terminal-activity"; +import type { TerminalActivity, TerminalActivityState } from "@getpaseo/protocol/terminal-activity"; import { createTempGitRepo } from "./workspace"; import { navigateToTerminal, setupDeterministicPrompt } from "./terminal-perf"; import { connectSeedClient, type SeedDaemonClient } from "./seed-client"; @@ -84,6 +84,7 @@ export class TerminalE2EHarness { async waitForTerminalActivity(input: { terminalId: string; state: TerminalActivityState | null; + attentionReason?: TerminalActivity["attentionReason"] | null; timeoutMs?: number; }): Promise { const timeoutMs = input.timeoutMs ?? 10_000; @@ -91,13 +92,21 @@ export class TerminalE2EHarness { while (Date.now() < deadline) { const result = await this.client.listTerminals(this.tempRepo.path); const terminal = result.terminals.find((entry) => entry.id === input.terminalId); - if ((terminal?.activity?.state ?? null) === input.state) { + const activity = terminal?.activity ?? null; + const attentionMatches = + input.attentionReason === undefined || + (activity?.attentionReason ?? null) === input.attentionReason; + if ((activity?.state ?? null) === input.state && attentionMatches) { return; } await sleep(50); } + const attentionSuffix = + input.attentionReason === undefined + ? "" + : ` with attention ${input.attentionReason ?? "none"}`; throw new Error( - `Timed out waiting for terminal ${input.terminalId} activity state ${input.state ?? "unknown"}`, + `Timed out waiting for terminal ${input.terminalId} activity state ${input.state ?? "unknown"}${attentionSuffix}`, ); } diff --git a/packages/app/e2e/terminal-activity-indicators.spec.ts b/packages/app/e2e/terminal-activity-indicators.spec.ts index d0b938189..953611de1 100644 --- a/packages/app/e2e/terminal-activity-indicators.spec.ts +++ b/packages/app/e2e/terminal-activity-indicators.spec.ts @@ -4,7 +4,7 @@ import { test, expect, type Page } from "./fixtures"; import { TerminalE2EHarness, type TerminalInstance } from "./helpers/terminal-dsl"; type HookActivityState = "running" | "idle" | "needs-input"; -type TabStatusBucket = "running" | "needs_input" | "none"; +type TabStatusBucket = "running" | "needs_input" | "attention" | "none"; const TERMINAL_ACTIVITY_REPORTER_SCRIPT = ` const fs = require("node:fs"); @@ -52,16 +52,21 @@ async function reportActivity(state) { }); `; -function internalActivityState(state: HookActivityState): "working" | "idle" | "attention" { +function internalActivityState(state: HookActivityState): "working" | "idle" { if (state === "running") return "working"; - if (state === "needs-input") return "attention"; return "idle"; } function tabStatusBucket(state: HookActivityState): TabStatusBucket { if (state === "running") return "running"; if (state === "needs-input") return "needs_input"; - return "none"; + return "attention"; +} + +function expectedAttentionReason(state: HookActivityState): "finished" | "needs_input" | null { + if (state === "idle") return "finished"; + if (state === "needs-input") return "needs_input"; + return null; } function terminalTab(page: Page, terminalId: string) { @@ -96,6 +101,7 @@ class ControlledActivityTerminal { await this.harness.waitForTerminalActivity({ terminalId: this.terminal.id, state: internalActivityState(state), + attentionReason: expectedAttentionReason(state), timeoutMs: 15_000, }); } @@ -166,6 +172,7 @@ test.describe("Terminal activity indicators", () => { await harness.waitForTerminalActivity({ terminalId: activityTerminal.terminal.id, state: "idle", + attentionReason: null, timeoutMs: 15_000, }); await expectTerminalTabStatus(page, activityTerminal.terminal.id, "none");