Fix styled switch-back repaint
This commit is contained in:
@@ -3,6 +3,7 @@ package harness
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -74,6 +75,43 @@ func runStep(s *Session, step Step, results map[string]json.RawMessage) error {
|
||||
return fmt.Errorf("screen does not contain %q:\n%s", step.Contains, screen)
|
||||
}
|
||||
return nil
|
||||
case "assert_not_contains":
|
||||
screen, err := s.Screen()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(screen, step.Contains) {
|
||||
return fmt.Errorf("screen contains %q:\n%s", step.Contains, screen)
|
||||
}
|
||||
return nil
|
||||
case "mark_raw":
|
||||
if step.SaveAs == "" {
|
||||
return fmt.Errorf("mark_raw requires save_as")
|
||||
}
|
||||
raw, err := json.Marshal(s.RawOffset())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
results[step.SaveAs] = raw
|
||||
return nil
|
||||
case "assert_raw_since_regex":
|
||||
raw, ok := results[step.From]
|
||||
if !ok {
|
||||
return fmt.Errorf("no saved result %q", step.From)
|
||||
}
|
||||
var offset int
|
||||
if err := json.Unmarshal(raw, &offset); err != nil {
|
||||
return fmt.Errorf("saved result %q is not a raw offset: %w", step.From, err)
|
||||
}
|
||||
re, err := regexp.Compile(step.Regex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b := s.RawSince(offset)
|
||||
if !re.Match(b) {
|
||||
return fmt.Errorf("raw output since %q does not match %q:\n%s", step.From, step.Regex, string(b))
|
||||
}
|
||||
return nil
|
||||
case "assert_regex":
|
||||
return s.WaitForRegex(step.Regex, timeoutMS(step.TimeoutMS))
|
||||
case "wait_text":
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "switch_replay_clears_viewport",
|
||||
"cols": 80,
|
||||
"rows": 24,
|
||||
"scripts": [
|
||||
{
|
||||
"name": "blanktop",
|
||||
"body": "#!/bin/sh\nprintf '\\033[2;1HFIRST-ROW-TWO\\n'\nsleep 5\n"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "spawn_process",
|
||||
"params": { "kind": "command", "argv": ["blanktop"], "name": "first" },
|
||||
"save_as": "first"
|
||||
},
|
||||
{ "type": "wait_text", "contains": "FIRST-ROW-TWO", "timeout_ms": 5000 },
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "spawn_process",
|
||||
"params": { "kind": "command", "argv": ["sh", "-lc", "echo SECOND READY; sleep 5"], "name": "second" },
|
||||
"save_as": "second"
|
||||
},
|
||||
{ "type": "wait_text", "contains": "SECOND READY", "timeout_ms": 5000 },
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "select_process",
|
||||
"params": { "process_id": "{{first.process_id}}" }
|
||||
},
|
||||
{ "type": "wait_stable", "timeout_ms": 5000 },
|
||||
{ "type": "assert_contains", "contains": "FIRST-ROW-TWO" },
|
||||
{ "type": "assert_not_contains", "contains": "SECOND READY" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "switch_replay_preserves_color",
|
||||
"cols": 80,
|
||||
"rows": 24,
|
||||
"scripts": [
|
||||
{
|
||||
"name": "color-frame",
|
||||
"body": "#!/bin/sh\nprintf '\\033[31mREDMARK\\033[0m\\n'\nsleep 5\n"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "spawn_process",
|
||||
"params": { "kind": "command", "argv": ["color-frame"], "name": "color" },
|
||||
"save_as": "color"
|
||||
},
|
||||
{ "type": "wait_text", "contains": "REDMARK", "timeout_ms": 5000 },
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "spawn_process",
|
||||
"params": { "kind": "command", "argv": ["sh", "-lc", "echo SECOND READY; sleep 5"], "name": "second" },
|
||||
"save_as": "second"
|
||||
},
|
||||
{ "type": "wait_text", "contains": "SECOND READY", "timeout_ms": 5000 },
|
||||
{ "type": "mark_raw", "save_as": "before_switch_back" },
|
||||
{
|
||||
"type": "mcp_call",
|
||||
"method": "select_process",
|
||||
"params": { "process_id": "{{color.process_id}}" }
|
||||
},
|
||||
{ "type": "wait_stable", "timeout_ms": 5000 },
|
||||
{ "type": "assert_contains", "contains": "REDMARK" },
|
||||
{ "type": "assert_raw_since_regex", "from": "before_switch_back", "regex": "\u001b\\[[0-9;]*38;2;[^m]*mREDMARK" }
|
||||
]
|
||||
}
|
||||
@@ -262,3 +262,23 @@ func (s *Session) rawBytes() []byte {
|
||||
copy(out, s.bytes)
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *Session) RawOffset() int {
|
||||
s.bytesMu.Lock()
|
||||
defer s.bytesMu.Unlock()
|
||||
return len(s.bytes)
|
||||
}
|
||||
|
||||
func (s *Session) RawSince(offset int) []byte {
|
||||
s.bytesMu.Lock()
|
||||
defer s.bytesMu.Unlock()
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
if offset > len(s.bytes) {
|
||||
offset = len(s.bytes)
|
||||
}
|
||||
out := make([]byte, len(s.bytes)-offset)
|
||||
copy(out, s.bytes[offset:])
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user