From 71417782fbf8db365d5c1a6f85e7f76b283fcbcf Mon Sep 17 00:00:00 2001 From: yetone Date: Sun, 2 Aug 2026 10:08:04 +0800 Subject: [PATCH] test(cli): close the raw/plain capture race in the e2e plain test (#299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit capture_plain_returns_text_not_escapes gated its byte-level asserts on the marker reaching the rendered capture, then asserted the raw capture already carried a CR. The two captures are separate snapshots taken in sequence, and on Windows ConPTY re-emits the echoed command in escape-laden bursts: the marker can render (from the typed input line) while the slightly earlier raw snapshot has yet to see a single CR — Enter's CRLF only arrives with the command's execution. CI hit exactly that window on x86_64-pc-windows-msvc. Make the CR part of the settle condition the loop polls for, alongside the marker, and name both in the timeout message so a genuine CR-stripping regression still reads as one. Co-authored-by: l0ng-ai --- crates/tty7-cli/tests/cli_e2e.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/tty7-cli/tests/cli_e2e.rs b/crates/tty7-cli/tests/cli_e2e.rs index 2c56c634..d6b189b5 100644 --- a/crates/tty7-cli/tests/cli_e2e.rs +++ b/crates/tty7-cli/tests/cli_e2e.rs @@ -544,11 +544,12 @@ fn capture_plain_returns_text_not_escapes(daemon: &Daemon) { loop { let raw = daemon.run_ok(&["capture", &address, "--scrollback"]); let plain = daemon.run_ok(&["capture", &address, "--scrollback", "--plain"]); - if plain.contains("tty7_e2e_plain_marker") { - assert!( - raw.contains('\r'), - "the default hands back the pane's bytes, CRLF included:\n{raw:?}" - ); + // The marker renders as soon as the shell echoes the typed command, + // which can be before the pane has seen a single CR — ConPTY repaints + // the input line in escape-laden bursts, and `raw` is a separate, + // slightly earlier snapshot besides. The CR is part of what must + // settle, not something the marker's arrival already proves. + if plain.contains("tty7_e2e_plain_marker") && raw.contains('\r') { assert!( !plain.contains('\r'), "a carriage return is an instruction to the grid, not text:\n{plain:?}" @@ -561,7 +562,8 @@ fn capture_plain_returns_text_not_escapes(daemon: &Daemon) { } assert!( Instant::now() < deadline, - "the sent text never showed up in the rendered capture; last was:\n{plain}" + "the captures never settled (marker rendered, CRLF in the raw \ + bytes); last plain was:\n{plain}\nlast raw was:\n{raw:?}" ); std::thread::sleep(Duration::from_millis(200)); }