Skip to content

Commit 11156ef

Browse files
committed
fix(pty): Correct the snapshot tests for all ACP interactions
1 parent 3a81ba2 commit 11156ef

13 files changed

Lines changed: 212 additions & 60 deletions

codex-rs/tui-pty-e2e/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ fn codex_binary_path() -> String {
518518
}
519519

520520
pub const TIMEOUT: Duration = Duration::from_secs(5);
521+
pub const TIMEOUT_INPUT: Duration = Duration::from_millis(300);
521522

522523
/// Normalize dynamic content in screen output for snapshot testing
523524
pub fn normalize_for_snapshot(contents: String) -> String {

codex-rs/tui-pty-e2e/tests/input_handling.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use tui_pty_e2e::normalize_for_snapshot;
44
use tui_pty_e2e::Key;
55
use tui_pty_e2e::TuiSession;
66
use tui_pty_e2e::TIMEOUT;
7+
use tui_pty_e2e::TIMEOUT_INPUT;
78

89
#[test]
910
fn test_ctrl_c_clears_input() {
@@ -22,6 +23,7 @@ fn test_ctrl_c_clears_input() {
2223
.wait_for(|s| !s.contains("draft message"), TIMEOUT)
2324
.expect("Input was not cleared");
2425

26+
std::thread::sleep(TIMEOUT_INPUT);
2527
assert_snapshot!(
2628
"ctrl_c_clears",
2729
normalize_for_snapshot(session.screen_contents())
@@ -44,6 +46,7 @@ fn test_backspace() {
4446
session.wait_for_text("Hel", TIMEOUT).unwrap();
4547
session.wait_for(|s| !s.contains("Hello"), TIMEOUT).unwrap();
4648

49+
std::thread::sleep(TIMEOUT_INPUT);
4750
assert_snapshot!(
4851
"typing_and_backspace",
4952
normalize_for_snapshot(session.screen_contents())
@@ -65,6 +68,7 @@ fn test_arrows() {
6568
session.send_key(Key::Down).unwrap();
6669
std::thread::sleep(Duration::from_millis(100));
6770

71+
std::thread::sleep(TIMEOUT_INPUT);
6872
assert_snapshot!(
6973
"model_changed",
7074
normalize_for_snapshot(session.screen_contents())
Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use insta::assert_snapshot;
2-
use std::time::Duration;
32
use tui_pty_e2e::normalize_for_snapshot;
43
use tui_pty_e2e::Key;
54
use tui_pty_e2e::SessionConfig;
65
use tui_pty_e2e::TuiSession;
7-
8-
const TIMEOUT: Duration = Duration::from_secs(10);
6+
use tui_pty_e2e::TIMEOUT;
7+
use tui_pty_e2e::TIMEOUT_INPUT;
98

109
#[test]
1110
fn test_submit_prompt_default_response() {
@@ -15,22 +14,23 @@ fn test_submit_prompt_default_response() {
1514

1615
// Type prompt
1716
session.send_str("Hello").unwrap();
18-
std::thread::sleep(Duration::from_millis(100));
17+
std::thread::sleep(TIMEOUT_INPUT);
1918
session.wait_for_text("Hello", TIMEOUT).unwrap();
2019

2120
// Submit
2221
session.send_key(Key::Enter).unwrap();
23-
std::thread::sleep(Duration::from_millis(100));
22+
std::thread::sleep(TIMEOUT_INPUT);
2423

2524
// Wait for default mock responses
2625
// (extra long waits because the ACP can have retries, and we want the final err)
2726
session
28-
.wait_for_text("Test message 1", Duration::from_secs(25))
27+
.wait_for_text("Test message 1", TIMEOUT)
2928
.expect("Did not receive mock response");
3029
session
3130
.wait_for_text("Test message 2", TIMEOUT)
3231
.expect("Did not receive second mock response");
3332

33+
std::thread::sleep(TIMEOUT_INPUT);
3434
assert_snapshot!(
3535
"prompt_submitted",
3636
normalize_for_snapshot(session.screen_contents())
@@ -50,61 +50,68 @@ fn test_submit_prompt_missing_model() {
5050

5151
// Type prompt
5252
session.send_str("Hello").unwrap();
53-
std::thread::sleep(Duration::from_millis(100));
53+
std::thread::sleep(TIMEOUT_INPUT);
5454
session.wait_for_text("Hello", TIMEOUT).unwrap();
5555

5656
// Submit
5757
session.send_key(Key::Enter).unwrap();
58-
std::thread::sleep(Duration::from_millis(100));
58+
std::thread::sleep(TIMEOUT_INPUT);
5959

6060
session
6161
.wait_for_text(
6262
"Model 'nonexistent' has wire_api=acp but is not registered",
63-
Duration::from_secs(10),
63+
TIMEOUT,
6464
)
6565
.unwrap();
6666

67+
std::thread::sleep(TIMEOUT_INPUT);
6768
assert_snapshot!(
6869
"missing_model",
6970
normalize_for_snapshot(session.screen_contents())
7071
);
7172
}
7273

73-
// #[test]
74-
// fn test_submit_prompt_custom_response() {
75-
// let config = SessionConfig::new()
76-
// .with_mock_response("This is a custom test response from the mock agent.");
77-
//
78-
// let mut session = TuiSession::spawn_with_config(18, 80, config).expect("Failed to spawn codex");
79-
//
80-
// session.wait_for_text("? for shortcuts", TIMEOUT).unwrap();
81-
//
82-
// session.send_str("test prompt").unwrap();
83-
// std::thread::sleep(Duration::from_millis(100));
84-
// session.send_key(Key::Enter).unwrap();
85-
// std::thread::sleep(Duration::from_millis(100));
86-
//
87-
// session
88-
// .wait_for_text("This is a custom test response", Duration::from_secs(10))
89-
// .expect("Did not receive custom response");
90-
//
91-
// assert_snapshot!("custom_response", session.screen_contents());
92-
// }
93-
//
94-
// #[test]
95-
// fn test_multiline_input() {
96-
// let mut session = TuiSession::spawn(18, 80).unwrap();
97-
// session.wait_for_text("? for shortcuts", TIMEOUT).unwrap();
98-
//
99-
// // Type multiline prompt
100-
// session.send_str("Line 1").unwrap();
101-
// session.send_key(Key::Enter).unwrap();
102-
// session.send_str("Line 2").unwrap();
103-
// session.send_key(Key::Enter).unwrap();
104-
// session.send_str("Line 3").unwrap();
105-
//
106-
// // Verify all lines visible
107-
// session.wait_for_text("Line 1", TIMEOUT).unwrap();
108-
// session.wait_for_text("Line 2", TIMEOUT).unwrap();
109-
// session.wait_for_text("Line 3", TIMEOUT).unwrap();
110-
// }
74+
#[test]
75+
fn test_submit_prompt_custom_response() {
76+
let config = SessionConfig::new()
77+
.with_mock_response("This is a custom test response from the mock agent.");
78+
79+
let mut session = TuiSession::spawn_with_config(18, 80, config).expect("Failed to spawn codex");
80+
81+
session.wait_for_text("? for shortcuts", TIMEOUT).unwrap();
82+
83+
session.send_str("test prompt").unwrap();
84+
std::thread::sleep(TIMEOUT_INPUT);
85+
session.send_key(Key::Enter).unwrap();
86+
std::thread::sleep(TIMEOUT_INPUT);
87+
88+
session
89+
.wait_for_text("This is a custom test response", TIMEOUT)
90+
.expect("Did not receive custom response");
91+
92+
std::thread::sleep(TIMEOUT_INPUT);
93+
assert_snapshot!(
94+
"custom_response",
95+
normalize_for_snapshot(session.screen_contents())
96+
);
97+
}
98+
99+
#[test]
100+
fn test_multiline_input() {
101+
let mut session = TuiSession::spawn(30, 80).unwrap();
102+
session.wait_for_text("? for shortcuts", TIMEOUT).unwrap();
103+
104+
// Type multiline prompt
105+
session.send_str("Line 1\nLine 2\nLine 3").unwrap();
106+
107+
// Verify all lines visible
108+
session.wait_for_text("Line 1", TIMEOUT).unwrap();
109+
session.wait_for_text("Line 2", TIMEOUT).unwrap();
110+
session.wait_for_text("Line 3", TIMEOUT).unwrap();
111+
112+
std::thread::sleep(TIMEOUT_INPUT);
113+
assert_snapshot!(
114+
"multiline_input",
115+
normalize_for_snapshot(session.screen_contents())
116+
);
117+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
source: tui-pty-e2e/tests/prompt_flow.rs
3+
expression: normalize_for_snapshot(session.screen_contents())
4+
---
5+
To get started, describe a task or try one of these commands:
6+
7+
/init - create an AGENTS.md file with instructions for Codex
8+
/status - show current session configuration
9+
/approvals - choose what Codex can do without approval
10+
/model - choose what model and reasoning effort to use
11+
/review - review any changes and find issues
12+
13+
14+
test prompt
15+
16+
17+
This is a custom test response from the mock agent.
18+
19+
20+
› [DEFAULT_PROMPT]
21+
22+
100% context left · ? for shortcuts

codex-rs/tui-pty-e2e/tests/snapshots/prompt_flow__missing_model.snap

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
source: tui-pty-e2e/tests/prompt_flow.rs
33
expression: normalize_for_snapshot(session.screen_contents())
44
---
5-
To get started, describe a task or try one of these commands:
6-
7-
/init - create an AGENTS.md file with instructions for Codex
85
/status - show current session configuration
96
/approvals - choose what Codex can do without approval
107
/model - choose what model and reasoning effort to use
118
/review - review any changes and find issues
129

10+
11+
Hello
12+
13+
1314
Fatal error: Model 'nonexistent' has wire_api=acp but is not registered in the
1415
ACP registry
1516

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
source: tui-pty-e2e/tests/prompt_flow.rs
3+
expression: normalize_for_snapshot(session.screen_contents())
4+
---
5+
Line 1
6+
Line 2
7+
Line 3
8+
9+
100% context left

codex-rs/tui-pty-e2e/tests/snapshots/prompt_flow__prompt_submitted.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
source: tui-pty-e2e/tests/prompt_flow.rs
33
expression: normalize_for_snapshot(session.screen_contents())
44
---
5-
╰──────────────────────────────────────────╯
6-
75
To get started, describe a task or try one of these commands:
86

97
/init - create an AGENTS.md file with instructions for Codex
@@ -12,7 +10,9 @@ expression: normalize_for_snapshot(session.screen_contents())
1210
/model - choose what model and reasoning effort to use
1311
/review - review any changes and find issues
1412

15-
Worked for 0s ────────────────────────────────────────────────────────────────
13+
14+
Hello
15+
1616

1717
Test message 1Test message 2
1818

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: tui-pty-e2e/tests/startup.rs
3+
expression: normalize_for_snapshot(session.screen_contents())
4+
---
5+
╭──────────────────────────────────────────╮
6+
>_ OpenAI Codex (v0.0.0) │
7+
│ │
8+
model: mock-model /model to change
9+
directory: [TMP_DIR] │
10+
╰──────────────────────────────────────────╯
11+
12+
To get started, describe a task or try one of these commands:
13+
14+
/init - create an AGENTS.md file with instructions for Codex
15+
/status - show current session configuration
16+
/approvals - choose what Codex can do without approval
17+
/model - choose what model and reasoning effort to use
18+
/review - review any changes and find issues
19+
20+
21+
› [DEFAULT_PROMPT]
22+
23+
100% context left · ? for shortcuts
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
source: tui-pty-e2e/tests/startup.rs
3+
expression: normalize_for_snapshot(session.screen_contents())
4+
---
5+
                                      
6+
             _._:=++==+,_             
7+
         _=,/*\+/+\=||=_ _"+_         
8+
       ,|*|+**"^`   `"*`"~=~||+       
9+
      ;*_\*',,_            /*|;|,     
10+
     \^;/'^|\`\\            ".|\\,    
11+
    ~* +`  |*/;||,           '.\||,   
12+
   +^"-*    '\|*/"|_          ! |/|   
13+
   ||_|`     ,//|;|*            "`|   
14+
   |=~'`    ;||^\|".~++++++_+, =" |   
15+
    _~;*  _;+` /* |"|___.:,,,|/,/,|   
16+
    \^_"^ ^\,./`   `^*''* ^*"/,;_/    
17+
     *^, ", `              ,'/*_|     
18+
       ^\,`\+_          _=_+|_+"      
19+
         ^*,\_!*+:;=;;.=*+_,|*        
20+
           `*"*|~~___,_;+*"           
21+
                                      
22+
23+
Welcome to Codex, OpenAI's command-line coding agent
24+
25+
Sign in with ChatGPT to use Codex as part of your paid plan
26+
or connect an API key for usage-based billing
27+
28+
> 1. Sign in with ChatGPT
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: tui-pty-e2e/tests/startup.rs
3+
expression: normalize_for_snapshot(session.screen_contents())
4+
---
5+
╭──────────────────────────────────────────╮
6+
>_ OpenAI Codex (v0.0.0) │
7+
│ │
8+
model: mock-model /model to change
9+
directory: [TMP_DIR] │
10+
╰──────────────────────────────────────────╯
11+
12+
To get started, describe a task or try one of these commands:
13+
14+
/init - create an AGENTS.md file with instructions for Codex
15+
/status - show current session configuration
16+
/approvals - choose what Codex can do without approval
17+
/model - choose what model and reasoning effort to use
18+
/review - review any changes and find issues
19+
20+
21+
› [DEFAULT_PROMPT]
22+
23+
100% context left · ? for shortcuts

0 commit comments

Comments
 (0)