aboutsummaryrefslogtreecommitdiff
path: root/tests/e2e.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tests/e2e.sh')
-rwxr-xr-xtests/e2e.sh73
1 files changed, 70 insertions, 3 deletions
diff --git a/tests/e2e.sh b/tests/e2e.sh
index 7f72e3c..e73dc73 100755
--- a/tests/e2e.sh
+++ b/tests/e2e.sh
@@ -285,13 +285,15 @@ cat >"$DIR/ext-harness.mjs" <<'JS'
// ("agent_start"), runs commands ("/importance high"), and asks for argument
// completions ("complete:importance h"). Custom session entries persist in
// $SESSION_ENTRIES, so a later run reads them back as the session; what the
-// extension shows and emits goes to $EXT_LOG.
+// extension shows and emits goes to $EXT_LOG. The input box holds
+// $EDITOR_TEXT; the session file is $SESSION_FILE.
import fs from "node:fs";
const ext = await import(process.env.EXTENSION);
const on = {}, commands = {};
const store = process.env.SESSION_ENTRIES;
const entries = store && fs.existsSync(store) ? JSON.parse(fs.readFileSync(store, "utf8")) : [];
const log = (line) => process.env.EXT_LOG && fs.appendFileSync(process.env.EXT_LOG, line + "\n");
+let editor = process.env.EDITOR_TEXT ?? "";
ext.default({
on: (name, fn) => (on[name] = fn),
registerCommand: (name, command) => (commands[name] = command),
@@ -304,8 +306,13 @@ ext.default({
const ctx = {
mode: "tui",
isIdle: () => true,
- sessionManager: { getEntries: () => entries, getSessionFile: () => undefined },
- ui: { setStatus: (key, text) => log(`status ${key} ${text ?? ""}`), notify: (text) => log(`notify ${text}`) },
+ sessionManager: { getEntries: () => entries, getSessionFile: () => process.env.SESSION_FILE },
+ ui: {
+ setStatus: (key, text) => log(`status ${key} ${text ?? ""}`),
+ notify: (text) => log(`notify ${text}`),
+ getEditorText: () => editor,
+ setEditorText: (text) => { editor = text; log(`editor ${text}`); },
+ },
};
for (const arg of process.argv.slice(2)) {
if (arg.startsWith("/")) {
@@ -1032,6 +1039,66 @@ expect "the menu: only those by hand, not clickable" "mb --print | grep '^⟳'"
"$(printf '⟳ %s Agents Need /reload\ttheir dingger extension is too old to reload them\t(disabled)' "$BY_HAND")"
t kill-session -t ext
+# --- 24. forgotten drafts -----------------------------------------------------
+# pi's extension reports the draft in its input box; dingger marks it where
+# the user is not looking, and keeps it in a file per session that comes back
+# with the session. (Typing into a real pi: tests/pi-live.sh.)
+echo "24. forgotten drafts"
+draft_report() { # pane draft
+ python3 - "$HOOK" "$1" "$2" <<'PY'
+import json, socket, sys
+params = {"pane_id": sys.argv[2], "agent": "pi", "draft": sys.argv[3]}
+s = socket.socket(socket.AF_UNIX)
+s.connect(sys.argv[1])
+s.sendall((json.dumps({"method": "pane.report_agent", "params": params}) + "\n").encode())
+s.close()
+PY
+}
+t new-session -d -s dr -n d1 -c "$DIR" "$DIR/bin/pi"
+t new-window -d -t dr: -n d2 -c "$DIR" "$DIR/bin/pi"
+t new-window -d -t dr: -n away -c "$DIR" "sleep 100000"
+D1=$(t display -p -t dr:d1 '#{pane_id}'); D2=$(t display -p -t dr:d2 '#{pane_id}')
+look "$(t display -p -t dr:away '#{pane_id}')"
+for p in "$D1" "$D2"; do report "$p" working ""; report "$p" idle ""; expect "dr: $p done" "opt $p @agent_state" done; done
+look "$D1"; sleep 1; look "$D2"; sleep 1; look "$(t display -p -t dr:away '#{pane_id}')"
+expect "dr: both idle" "opt $D1 @agent_state; opt $D2 @agent_state" "idle
+idle"
+draft_report "$D2" "$(printf 'fix the\n sidecar;')"
+expect "a draft, as one line, its trailing ; kept" "opt $D2 @dingger_draft" "fix the sidecar;"
+expect "pane options after it still written" "opt $D2 @agent_state" idle
+drow() { mb --print | grep -F "dr · $1 ·" | cut -f2; }
+expect "menu: marked ✎" "drow d2" "✎ pi"
+expect "first among idle agents" "mb --print | grep -F 'dr · d' | cut -f3 | cut -d' ' -f3 | tr '\n' ' '" "d2 d1 "
+expect "search finds it by its draft" "mb --print-search sidecar | head -1 | cut -f3" "dr · d2 · pi"
+expect "dingger status marks it" "$DINGGER status | grep -F 'dr · d2' | grep -c '✎ '" 1
+look "$D2"
+expect "where you look, no mark: you may be typing it" "drow d2" "pi"
+expect "nor in dingger status" "$DINGGER status | grep -F 'dr · d2' | grep -c '✎ '" 0
+look "$D1"
+draft_report "$D2" ""
+expect "a cleared draft: gone" "opt $D2 @dingger_draft" ""
+expect "menu: no mark" "drow d2" "pi"
+draft_report "$D2" ";"
+expect "a draft of just ;" "opt $D2 @dingger_draft" ";"
+report "$D2" working ""
+expect "a report without a draft keeps it" "opt $D2 @dingger_draft" ";"
+if command -v node >/dev/null; then
+ DRAFTS="$(dirname "$HOOK")/drafts"
+ EDITOR_TEXT="half a thought" SESSION_FILE="$DIR/sessions/s1.jsonl" iext "$D1" session_start
+ expect "the extension reports its draft" "opt $D1 @dingger_draft" "half a thought"
+ expect "and keeps it for the session" "cat $DRAFTS/s1.jsonl.draft" "half a thought"
+ : >"$EXTLOG"; SESSION_FILE="$DIR/sessions/s1.jsonl" iext "$D1" session_start
+ expect "the session again: its draft back in the input box" "grep '^editor' $EXTLOG" "editor half a thought"
+ expect "and reported" "opt $D1 @dingger_draft" "half a thought"
+ : >"$EXTLOG"; EDITOR_TEXT="typed meanwhile" SESSION_FILE="$DIR/sessions/s1.jsonl" iext "$D1" session_start
+ expect "an input box with text keeps it" "grep -c '^editor' $EXTLOG" 0
+ expect "and that is the draft now" "cat $DRAFTS/s1.jsonl.draft" "typed meanwhile"
+ : >"$EXTLOG"; SESSION_FILE="$DIR/sessions/s2.jsonl" iext "$D1" session_start
+ expect "another session: none of it" "grep -c '^editor' $EXTLOG" 0
+ expect "dr: no draft reported" "opt $D1 @dingger_draft" ""
+fi
+t kill-session -t dr
+
# Every daemon this run started must stop with it.
kill "$DAEMON_PID" "$DAEMON2_PID" 2>/dev/null
expect "the test daemons stop" "ps -o pid= -p $DAEMON_PID,$DAEMON2_PID | wc -l | tr -d ' '" 0