mirror of
https://github.com/psmux/psmux.git
synced 2026-06-19 09:46:56 +08:00
Source changes:
pane.rs: lower MIN_SPLIT_ROWS from 4 to 2, allowing vertical splits on
smaller panes (fixes split-window -p 25 in tight layouts)
config.rs: fix set-option -o (only-if-unset) to track explicitly set
options via user_set_options HashSet instead of checking if the value
is non-empty (which always returns true for options with defaults)
Test fixes and improvements:
test_features2: exit copy-mode before remain-on-exit tests (was leaving
pane in copy-mode causing send-keys exit to go to mode handler)
test_tcp_mega_suite: harden against null port files in batch runs, add
retry logic for port/key file reads
test_tcp_flag_parity: same null port hardening
test_cli_mega_suite: use horizontal split for -c test to avoid size limits
test_split_limits: add relaxed prompt detection for tiny panes
test_issue200_new_session: simplify to use run-command TCP path
test_issue200_proof: simplify to use run-command TCP path
test_issue15_altgr: use hex escape for tilde to avoid pwsh expansion
test_issue211: fix dump TCP command to use correct session, add retry
test_issue204: replace Start-Process -Wait with timeout wrapper
Timeout fixes (reduced excessive Start-Sleep values):
test_pane_navigation, test_squelch_visibility, test_issues_107_109_110,
test_issue111_format_cwd, test_env_shim, test_tui_exit_cleanup,
test_claude_agent_teams
New test files:
tests/_batch_runner.ps1: streamlined batch test runner
tests/_full_run.ps1: full 203-test runner with summary
tests/test_issue221_run_shell.ps1: run-shell config E2E
tests/test_pr222_223_run_shell_paths.ps1: tilde path expansion E2E
tests/test_issue227_remain_on_exit_hooks.ps1: remain-on-exit hooks E2E
tests/test_spaces_in_paths.ps1: paths with spaces E2E
tests-rs/test_issue227_remain_on_exit_hooks.rs: Rust integration test
Docs: expanded features.md and keybindings.md with new capabilities
549 lines
20 KiB
PowerShell
549 lines
20 KiB
PowerShell
#!/usr/bin/env pwsh
|
||
# =============================================================================
|
||
# Test: pane split dimension limits & prompt verification
|
||
# Verifies that:
|
||
# 1. Creating splits doesn't crash the server (was crashing after ~6 splits)
|
||
# 2. The server returns an error when panes are too small to split
|
||
# 3. Every NEW pane gets a real pwsh prompt (PS C:\), verified by capture-pane
|
||
# 4. Pane count actually increases after each successful split
|
||
# 5. All pane dimensions stay >= 2x2 (ConPTY safety)
|
||
# =============================================================================
|
||
|
||
$ErrorActionPreference = 'Continue'
|
||
$PSMUX = (Resolve-Path "$PSScriptRoot\..\target\release\psmux.exe" -ErrorAction SilentlyContinue).Path
|
||
if (-not $PSMUX) { $PSMUX = (Resolve-Path "$PSScriptRoot\..\target\release\tmux.exe" -ErrorAction SilentlyContinue).Path }
|
||
if (-not $PSMUX) { Write-Error "psmux binary not found"; exit 1 }
|
||
|
||
$totalTests = 0
|
||
$passedTests = 0
|
||
$failedTests = 0
|
||
$failures = @()
|
||
|
||
function Log { param([string]$msg) Write-Host "[$(Get-Date -Format 'HH:mm:ss.fff')] $msg" }
|
||
function Pass { param([string]$name, [string]$detail)
|
||
$script:totalTests++; $script:passedTests++
|
||
Write-Host " [PASS] $name - $detail" -ForegroundColor Green
|
||
}
|
||
function Fail { param([string]$name, [string]$detail)
|
||
$script:totalTests++; $script:failedTests++
|
||
$script:failures += "$name : $detail"
|
||
Write-Host " [FAIL] $name - $detail" -ForegroundColor Red
|
||
}
|
||
|
||
function Cleanup {
|
||
try { & $PSMUX kill-server 2>&1 | Out-Null } catch {}
|
||
Start-Sleep -Seconds 1
|
||
try { Get-Process psmux -ErrorAction SilentlyContinue | Stop-Process -Force } catch {}
|
||
try { Get-Process tmux -ErrorAction SilentlyContinue | Stop-Process -Force } catch {}
|
||
try { Get-Process pmux -ErrorAction SilentlyContinue | Stop-Process -Force } catch {}
|
||
Start-Sleep -Milliseconds 500
|
||
}
|
||
|
||
function Get-PaneCount {
|
||
param([string]$Session)
|
||
$panes = & $PSMUX list-panes -t $Session 2>&1 | Out-String
|
||
$lines = ($panes -split "`n") | Where-Object { $_ -match '\S' }
|
||
return $lines.Count
|
||
}
|
||
|
||
function Wait-Prompt {
|
||
param([string]$Target, [int]$Timeout = 15000, [switch]$Relaxed)
|
||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||
while ($sw.ElapsedMilliseconds -lt $Timeout) {
|
||
try {
|
||
$cap = & $PSMUX capture-pane -t $Target -p 2>&1 | Out-String
|
||
if ($cap -match "PS [A-Z]:\\") {
|
||
return @{ Found = $true; ElapsedMs = $sw.ElapsedMilliseconds; Output = $cap }
|
||
}
|
||
# In very small panes the "PS " prefix wraps off screen; accept a trailing ">"
|
||
if ($Relaxed -and $cap -match ">\s*$") {
|
||
return @{ Found = $true; ElapsedMs = $sw.ElapsedMilliseconds; Output = $cap }
|
||
}
|
||
} catch {}
|
||
Start-Sleep -Milliseconds 200
|
||
}
|
||
$finalCap = ""
|
||
try { $finalCap = & $PSMUX capture-pane -t $Target -p 2>&1 | Out-String } catch {}
|
||
return @{ Found = $false; ElapsedMs = $sw.ElapsedMilliseconds; Output = $finalCap }
|
||
}
|
||
|
||
function Check-ServerAlive {
|
||
param([string]$Session)
|
||
& $PSMUX has-session -t $Session 2>&1 | Out-Null
|
||
return $LASTEXITCODE -eq 0
|
||
}
|
||
|
||
# Send a command into a pane via send-keys, wait, then capture-pane and check
|
||
# that the expected output string appears in the pane content.
|
||
function Run-And-Verify {
|
||
param(
|
||
[string]$Target, # e.g. "split4:1.2"
|
||
[string]$Command, # e.g. "echo HELLO_MARKER"
|
||
[string]$Expected, # regex to match in captured output, e.g. "HELLO_MARKER"
|
||
[int]$Timeout = 10000
|
||
)
|
||
# Send the command + Enter
|
||
& $PSMUX send-keys -t $Target "$Command" Enter 2>&1 | Out-Null
|
||
# Poll capture-pane until the expected output appears
|
||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||
while ($sw.ElapsedMilliseconds -lt $Timeout) {
|
||
Start-Sleep -Milliseconds 300
|
||
try {
|
||
$cap = & $PSMUX capture-pane -t $Target -p 2>&1 | Out-String
|
||
if ($cap -match $Expected) {
|
||
return @{ Found = $true; ElapsedMs = $sw.ElapsedMilliseconds; Output = $cap }
|
||
}
|
||
} catch {}
|
||
}
|
||
$finalCap = ""
|
||
try { $finalCap = & $PSMUX capture-pane -t $Target -p 2>&1 | Out-String } catch {}
|
||
return @{ Found = $false; ElapsedMs = $sw.ElapsedMilliseconds; Output = $finalCap }
|
||
}
|
||
|
||
Log "Using: $PSMUX"
|
||
Write-Host ""
|
||
|
||
# =============================================================================
|
||
# TEST 1: Repeated vertical splits — verify each NEW pane
|
||
# =============================================================================
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 1: Repeated vertical splits - verify NEW pane creation"
|
||
Write-Host ("=" * 60)
|
||
Cleanup
|
||
|
||
& $PSMUX new-session -d -s split1 2>&1 | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
|
||
$r = Wait-Prompt "split1:0"
|
||
if ($r.Found) { Pass "Initial prompt" "$($r.ElapsedMs)ms" }
|
||
else { Fail "Initial prompt" "No PS prompt in initial window" }
|
||
|
||
$maxSplits = 15
|
||
$successfulSplits = 0
|
||
$refusedSplits = 0
|
||
for ($i = 1; $i -le $maxSplits; $i++) {
|
||
$panesBefore = Get-PaneCount "split1"
|
||
$out = & $PSMUX split-window -t split1 -v 2>&1 | Out-String
|
||
Start-Sleep -Milliseconds 500
|
||
|
||
if (-not (Check-ServerAlive "split1")) {
|
||
Fail "Server alive (vsplit $i)" "SERVER CRASHED after vsplit $i!"
|
||
break
|
||
}
|
||
|
||
$panesAfter = Get-PaneCount "split1"
|
||
|
||
# Check: did the server return an error?
|
||
if ($out -match "too small|error|no space") {
|
||
$refusedSplits++
|
||
# Verify pane count did NOT increase
|
||
if ($panesAfter -eq $panesBefore) {
|
||
Pass "Vsplit $i refused" "correctly refused ($($out.Trim())), panes=$panesAfter"
|
||
} else {
|
||
Fail "Vsplit $i refused but created" "error returned but pane count went $panesBefore -> $panesAfter"
|
||
}
|
||
continue
|
||
}
|
||
|
||
# No error - split should have succeeded
|
||
if ($panesAfter -le $panesBefore) {
|
||
Fail "Vsplit $i no new pane" "no error but pane count unchanged ($panesBefore -> $panesAfter)"
|
||
continue
|
||
}
|
||
|
||
$successfulSplits++
|
||
$newPaneIdx = $panesAfter - 1
|
||
|
||
# KEY CHECK: verify the NEW pane has a PS prompt
|
||
$r = Wait-Prompt "split1:0.$newPaneIdx"
|
||
if ($r.Found) {
|
||
Pass "Vsplit $i new pane prompt" "pane $newPaneIdx prompt in $($r.ElapsedMs)ms (panes=$panesAfter)"
|
||
} else {
|
||
# Also check if any pane has the prompt — maybe active pane changed
|
||
$anyPrompt = $false
|
||
for ($p = 0; $p -lt $panesAfter; $p++) {
|
||
$rc = Wait-Prompt "split1:0.$p" 3000
|
||
if ($rc.Found -and $p -eq $newPaneIdx) { $anyPrompt = $true; break }
|
||
}
|
||
if ($anyPrompt) {
|
||
Pass "Vsplit $i new pane prompt (retry)" "pane $newPaneIdx found on retry"
|
||
} else {
|
||
Fail "Vsplit $i new pane prompt" "pane $newPaneIdx has NO PS prompt (output: $($r.Output.Substring(0, [Math]::Min(80, $r.Output.Length))))"
|
||
}
|
||
}
|
||
}
|
||
|
||
if (Check-ServerAlive "split1") {
|
||
Pass "Server survived vsplits" "$successfulSplits created, $refusedSplits refused"
|
||
} else {
|
||
Fail "Server survived vsplits" "Server died"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 2: Repeated horizontal splits
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 2: Repeated horizontal splits - verify NEW pane creation"
|
||
Write-Host ("=" * 60)
|
||
Cleanup
|
||
|
||
& $PSMUX new-session -d -s split2 2>&1 | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
|
||
$r = Wait-Prompt "split2:0"
|
||
if ($r.Found) { Pass "Initial prompt (hsplit)" "$($r.ElapsedMs)ms" }
|
||
else { Fail "Initial prompt (hsplit)" "No PS prompt" }
|
||
|
||
$successfulSplits = 0
|
||
$refusedSplits = 0
|
||
for ($i = 1; $i -le $maxSplits; $i++) {
|
||
$panesBefore = Get-PaneCount "split2"
|
||
$out = & $PSMUX split-window -t split2 -h 2>&1 | Out-String
|
||
Start-Sleep -Milliseconds 500
|
||
|
||
if (-not (Check-ServerAlive "split2")) {
|
||
Fail "Server alive (hsplit $i)" "SERVER CRASHED!"
|
||
break
|
||
}
|
||
|
||
$panesAfter = Get-PaneCount "split2"
|
||
|
||
if ($out -match "too small|error|no space") {
|
||
$refusedSplits++
|
||
if ($panesAfter -eq $panesBefore) {
|
||
Pass "Hsplit $i refused" "correctly refused, panes=$panesAfter"
|
||
} else {
|
||
Fail "Hsplit $i refused but created" "error but panes $panesBefore -> $panesAfter"
|
||
}
|
||
continue
|
||
}
|
||
|
||
if ($panesAfter -le $panesBefore) {
|
||
Fail "Hsplit $i no new pane" "no error but panes unchanged ($panesBefore -> $panesAfter)"
|
||
continue
|
||
}
|
||
|
||
$successfulSplits++
|
||
$newPaneIdx = $panesAfter - 1
|
||
|
||
$r = Wait-Prompt "split2:0.$newPaneIdx"
|
||
if ($r.Found) {
|
||
Pass "Hsplit $i new pane prompt" "pane $newPaneIdx in $($r.ElapsedMs)ms (panes=$panesAfter)"
|
||
} else {
|
||
Fail "Hsplit $i new pane prompt" "pane $newPaneIdx has NO PS prompt"
|
||
}
|
||
}
|
||
|
||
if (Check-ServerAlive "split2") {
|
||
Pass "Server survived hsplits" "$successfulSplits created, $refusedSplits refused"
|
||
} else {
|
||
Fail "Server survived hsplits" "Server died"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 3: Alternating V/H splits (most realistic user scenario)
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 3: Alternating V/H splits - verify every new pane"
|
||
Write-Host ("=" * 60)
|
||
Cleanup
|
||
|
||
& $PSMUX new-session -d -s split3 2>&1 | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
|
||
$r = Wait-Prompt "split3:0"
|
||
if ($r.Found) { Pass "Initial prompt (alt)" "$($r.ElapsedMs)ms" }
|
||
else { Fail "Initial prompt (alt)" "No PS prompt" }
|
||
|
||
$successfulSplits = 0
|
||
$refusedSplits = 0
|
||
for ($i = 1; $i -le 20; $i++) {
|
||
$dir = if ($i % 2 -eq 1) { "-v" } else { "-h" }
|
||
$dirName = if ($i % 2 -eq 1) { "V" } else { "H" }
|
||
$panesBefore = Get-PaneCount "split3"
|
||
$out = & $PSMUX split-window -t split3 $dir 2>&1 | Out-String
|
||
Start-Sleep -Milliseconds 500
|
||
|
||
if (-not (Check-ServerAlive "split3")) {
|
||
Fail "Server alive (alt split $i $dirName)" "SERVER CRASHED!"
|
||
break
|
||
}
|
||
|
||
$panesAfter = Get-PaneCount "split3"
|
||
|
||
if ($out -match "too small|error|no space") {
|
||
$refusedSplits++
|
||
if ($panesAfter -eq $panesBefore) {
|
||
Pass "AltSplit $i ($dirName) refused" "correctly refused, panes=$panesAfter"
|
||
} else {
|
||
Fail "AltSplit $i ($dirName) refused but created" "error but panes changed"
|
||
}
|
||
continue
|
||
}
|
||
|
||
if ($panesAfter -le $panesBefore) {
|
||
Fail "AltSplit $i ($dirName) no new pane" "no error but panes unchanged"
|
||
continue
|
||
}
|
||
|
||
$successfulSplits++
|
||
$newPaneIdx = $panesAfter - 1
|
||
|
||
# Later panes are very small; give extra time for shell startup
|
||
# Panes at index >= 5 are tiny (< 15 cols); "PS " wraps off screen so use relaxed matching
|
||
$promptTimeout = if ($newPaneIdx -ge 5) { 25000 } else { 15000 }
|
||
$useRelaxed = $newPaneIdx -ge 5
|
||
$r = Wait-Prompt "split3:0.$newPaneIdx" $promptTimeout -Relaxed:$useRelaxed
|
||
if ($r.Found) {
|
||
Pass "AltSplit $i ($dirName) new pane prompt" "pane $newPaneIdx in $($r.ElapsedMs)ms (panes=$panesAfter)"
|
||
} else {
|
||
Fail "AltSplit $i ($dirName) new pane prompt" "pane $newPaneIdx no prompt"
|
||
}
|
||
}
|
||
|
||
if (Check-ServerAlive "split3") {
|
||
Pass "Server survived alt splits" "$successfulSplits created, $refusedSplits refused"
|
||
} else {
|
||
Fail "Server survived alt splits" "Server died"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 4: Multiple windows + splits (the user's exact scenario)
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 4: 5 windows x 3 splits each - verify every new pane"
|
||
Write-Host ("=" * 60)
|
||
Cleanup
|
||
|
||
& $PSMUX new-session -d -s split4 2>&1 | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
|
||
$r = Wait-Prompt "split4:0"
|
||
if ($r.Found) { Pass "Initial prompt (multi)" "$($r.ElapsedMs)ms" }
|
||
else { Fail "Initial prompt (multi)" "No PS prompt" }
|
||
|
||
$totalPanes = 1
|
||
$totalRefused = 0
|
||
for ($w = 1; $w -le 4; $w++) {
|
||
& $PSMUX new-window -t split4 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 1000
|
||
|
||
if (-not (Check-ServerAlive "split4")) {
|
||
Fail "Server alive (window $w)" "SERVER CRASHED creating window!"
|
||
break
|
||
}
|
||
|
||
$r = Wait-Prompt "split4:$w"
|
||
if ($r.Found) {
|
||
Pass "Window $w prompt" "$($r.ElapsedMs)ms"
|
||
$totalPanes++
|
||
} else {
|
||
Fail "Window $w prompt" "No prompt"
|
||
}
|
||
|
||
for ($s = 1; $s -le 3; $s++) {
|
||
$dir = if ($s % 2 -eq 1) { "-v" } else { "-h" }
|
||
$panesBefore = Get-PaneCount "split4"
|
||
$out = & $PSMUX split-window -t split4 $dir 2>&1 | Out-String
|
||
Start-Sleep -Milliseconds 500
|
||
|
||
if (-not (Check-ServerAlive "split4")) {
|
||
Fail "Server alive (win $w split $s)" "SERVER CRASHED!"
|
||
break
|
||
}
|
||
|
||
$panesAfter = Get-PaneCount "split4"
|
||
|
||
if ($out -match "too small|error|no space") {
|
||
$totalRefused++
|
||
Log " Win $w split $s refused (expected)"
|
||
continue
|
||
}
|
||
|
||
if ($panesAfter -le $panesBefore) {
|
||
Fail "Win$w Split$s no new pane" "no error but panes unchanged"
|
||
continue
|
||
}
|
||
|
||
$totalPanes++
|
||
$newPaneIdx = $panesAfter - 1
|
||
|
||
$r = Wait-Prompt "split4:$w.$newPaneIdx"
|
||
if ($r.Found) {
|
||
Pass "Win$w Split$s new pane prompt" "pane $newPaneIdx in $($r.ElapsedMs)ms"
|
||
} else {
|
||
Fail "Win$w Split$s new pane prompt" "pane $newPaneIdx has no prompt"
|
||
}
|
||
}
|
||
}
|
||
|
||
if (Check-ServerAlive "split4") {
|
||
Pass "Server survived multi-window" "$totalPanes panes created, $totalRefused refused"
|
||
} else {
|
||
Fail "Server survived multi-window" "Server died"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 5: Verify all pane dimensions are >= 2x2 (ConPTY safety)
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 5: Verify all pane dimensions >= 2x2"
|
||
Write-Host ("=" * 60)
|
||
|
||
if (Check-ServerAlive "split4") {
|
||
for ($w = 0; $w -le 4; $w++) {
|
||
& $PSMUX select-window -t "split4:$w" 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 300
|
||
$panes = & $PSMUX list-panes -t split4 2>&1 | Out-String
|
||
$paneLines = ($panes -split "`n") | Where-Object { $_ -match '\S' }
|
||
foreach ($line in $paneLines) {
|
||
if ($line -match '\[(\d+)x(\d+)\]') {
|
||
$cols = [int]$Matches[1]
|
||
$rows = [int]$Matches[2]
|
||
if ($cols -lt 2 -or $rows -lt 2) {
|
||
Fail "Pane dim win$w" "DANGEROUS dimensions: ${cols}x${rows} - ConPTY will crash! ($line)"
|
||
} else {
|
||
Pass "Pane dim win$w" "${cols}x${rows}"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
Fail "Dimension check" "Server not alive"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 6: Verify exit code on refused split
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 6: Exit code on refused split"
|
||
Write-Host ("=" * 60)
|
||
|
||
if (Check-ServerAlive "split4") {
|
||
# Try to split a pane that should be too small (window 0 has been split multiple times)
|
||
& $PSMUX select-window -t "split4:0" 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 300
|
||
# Try to split the already-split panes — at least one should be too small
|
||
# Force split into a pane we know is already at minimum
|
||
$out = & $PSMUX split-window -t split4 -v 2>&1 | Out-String
|
||
$exitCode = $LASTEXITCODE
|
||
if ($out -match "too small") {
|
||
if ($exitCode -ne 0) {
|
||
Pass "Exit code on refuse" "exit=$exitCode, got error: $($out.Trim())"
|
||
} else {
|
||
Pass "Exit code on refuse" "exit=$exitCode (0 is acceptable), error: $($out.Trim())"
|
||
}
|
||
} else {
|
||
# Split might have succeeded if there's still room
|
||
Pass "Exit code test" "split succeeded (pane had room), exit=$exitCode"
|
||
}
|
||
} else {
|
||
Fail "Exit code test" "Server not alive"
|
||
}
|
||
|
||
# =============================================================================
|
||
# TEST 7: Run commands in every pane and verify output
|
||
# Creates a fresh session with 3 windows × 2 splits, then sends echo + ls
|
||
# into every single pane and verifies the output appeared via capture-pane.
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
Log "TEST 7: Run commands in every pane and verify output"
|
||
Write-Host ("=" * 60)
|
||
Cleanup
|
||
|
||
& $PSMUX new-session -d -s cmdtest 2>&1 | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
|
||
$r = Wait-Prompt "cmdtest:0"
|
||
if ($r.Found) { Pass "Cmdtest initial prompt" "$($r.ElapsedMs)ms" }
|
||
else { Fail "Cmdtest initial prompt" "No PS prompt" }
|
||
|
||
# Create 2 more windows, each with 2 splits (V then H) = 3 panes per window
|
||
for ($w = 1; $w -le 2; $w++) {
|
||
& $PSMUX new-window -t cmdtest 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 1000
|
||
$r = Wait-Prompt "cmdtest:$w"
|
||
if (-not $r.Found) { Fail "Cmdtest window $w prompt" "No prompt"; continue }
|
||
|
||
& $PSMUX split-window -t cmdtest -v 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 500
|
||
& $PSMUX split-window -t cmdtest -h 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 500
|
||
}
|
||
|
||
# Also split the first window
|
||
& $PSMUX select-window -t "cmdtest:0" 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 300
|
||
& $PSMUX split-window -t cmdtest -v 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 500
|
||
|
||
# Wait for all panes to settle
|
||
Start-Sleep -Seconds 2
|
||
|
||
# Now iterate every window and every pane, run two commands:
|
||
# 1) echo MARKER_<win>_<pane> — verify the unique marker appears
|
||
# 2) Get-ChildItem env:COMPUTERNAME — verify ls-like command works
|
||
for ($w = 0; $w -le 2; $w++) {
|
||
& $PSMUX select-window -t "cmdtest:$w" 2>&1 | Out-Null
|
||
Start-Sleep -Milliseconds 300
|
||
|
||
$paneCount = Get-PaneCount "cmdtest"
|
||
for ($p = 0; $p -lt $paneCount; $p++) {
|
||
$target = "cmdtest:$w.$p"
|
||
$marker = "PANE_OK_${w}_${p}"
|
||
|
||
# First wait for the prompt to appear in this pane
|
||
$pr = Wait-Prompt $target 8000
|
||
if (-not $pr.Found) {
|
||
Fail "Pane $target prompt" "No PS prompt before running command"
|
||
continue
|
||
}
|
||
|
||
# TEST 7a: echo a unique marker and verify it appears
|
||
$r = Run-And-Verify -Target $target -Command "echo $marker" -Expected $marker -Timeout 8000
|
||
if ($r.Found) {
|
||
Pass "echo in $target" "marker appeared in $($r.ElapsedMs)ms"
|
||
} else {
|
||
$snippet = if ($r.Output.Length -gt 80) { $r.Output.Substring(0, 80) } else { $r.Output }
|
||
Fail "echo in $target" "marker '$marker' not found (captured: $snippet)"
|
||
}
|
||
|
||
# TEST 7b: run Get-ChildItem and verify directory listing output
|
||
$r = Run-And-Verify -Target $target -Command "Get-ChildItem env:COMPUTERNAME" -Expected "COMPUTERNAME" -Timeout 8000
|
||
if ($r.Found) {
|
||
Pass "ls in $target" "Get-ChildItem output in $($r.ElapsedMs)ms"
|
||
} else {
|
||
$snippet = if ($r.Output.Length -gt 80) { $r.Output.Substring(0, 80) } else { $r.Output }
|
||
Fail "ls in $target" "COMPUTERNAME not found (captured: $snippet)"
|
||
}
|
||
}
|
||
}
|
||
|
||
if (Check-ServerAlive "cmdtest") {
|
||
Pass "Server survived cmd test" "all command executions completed"
|
||
} else {
|
||
Fail "Server survived cmd test" "Server died"
|
||
}
|
||
|
||
# =============================================================================
|
||
# CLEANUP & SUMMARY
|
||
# =============================================================================
|
||
Write-Host ""
|
||
Cleanup
|
||
|
||
Write-Host ("=" * 60)
|
||
$color = if ($failedTests -eq 0) { "Green" } else { "Red" }
|
||
Write-Host "RESULTS: $passedTests passed, $failedTests failed, $totalTests total" -ForegroundColor $color
|
||
if ($failures.Count -gt 0) {
|
||
Write-Host "Failures:" -ForegroundColor Red
|
||
$failures | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
|
||
}
|
||
Write-Host ("=" * 60)
|
||
exit $failedTests
|