Fix flaky terminal kill task test (#56194)

Ben Kunkle created

Failed CI run:
https://github.com/zed-industries/zed/actions/runs/25559568951/job/75027378760?pr=56181

test_kill_active_task_on_completed_task_is_noop was flaking on Linux.
It's sibling was just waiting 200ms for PTY events to be handled by
alacritty. This PR polls the PTY instead of waiting an arbitrary amount
of time

Release Notes:

- N/A

Change summary

crates/terminal/src/terminal.rs | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

Detailed changes

crates/terminal/src/terminal.rs 🔗

@@ -3341,6 +3341,27 @@ mod tests {
         });
     }
 
+    /// Polls the terminal content until `expected` appears, or panics after ~1s.
+    /// The PTY IO thread writes into the terminal grid independently of the
+    /// GPUI executor, so we need a real-time polling loop to synchronize.
+    async fn assert_content_eventually(
+        terminal: &Entity<Terminal>,
+        expected: &str,
+        cx: &mut TestAppContext,
+    ) {
+        let mut content = String::new();
+        for _ in 0..100 {
+            content = terminal.update(cx, |term, _| term.get_content());
+            if content.contains(expected) {
+                return;
+            }
+            cx.background_executor
+                .timer(Duration::from_millis(10))
+                .await;
+        }
+        panic!("Expected terminal content to contain {expected:?}, got: {content}");
+    }
+
     /// Test that kill_active_task properly terminates both the foreground process
     /// and the shell, allowing wait_for_completed_task to complete and output to be captured.
     #[cfg(unix)]
@@ -3353,10 +3374,7 @@ mod tests {
         let (terminal, completion_rx) =
             build_test_terminal(cx, "echo", &["test_output_before_kill; sleep 60"]).await;
 
-        // Wait a bit for the echo to execute and produce output
-        cx.background_executor
-            .timer(Duration::from_millis(200))
-            .await;
+        assert_content_eventually(&terminal, "test_output_before_kill", cx).await;
 
         // Kill the active task
         terminal.update(cx, |term, _cx| {
@@ -3400,6 +3418,8 @@ mod tests {
             .expect("Should receive exit status");
         assert_eq!(exit_status, Some(ExitStatus::default()));
 
+        assert_content_eventually(&terminal, "done", cx).await;
+
         // Now try to kill - should be a no-op since task already completed
         terminal.update(cx, |term, _cx| {
             term.kill_active_task();