Files
ElyOffice/tests/scripts/panels.sh
T
ZacharyZhang-NY b7fca0146d Ely Office: six offline-first desktop apps in Rust and GPUI
ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git),
ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
2026-10-08 21:20:08 -04:00

129 lines
5.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Side panels: narrower by default, dragged wider, kept on restart.
set -euo pipefail
root=$(cd "$(dirname "$0")/../.." && pwd)
[ "$(uname)" = Darwin ] || { echo "SKIP: macOS only"; exit 0; }
work=$(mktemp -d)
# Keeps the run's own status; the app's SIGTERM is expected.
cleanup() {
local status=$?
if [ -n "${pid:-}" ]; then
kill "$pid" 2>/dev/null || true
wait "$pid" 2>/dev/null || true
fi
[ "$status" = 0 ] && rm -rf "$work" || echo "kept $work" >&2
exit "$status"
}
trap cleanup EXIT
fail() {
echo "FAIL: $*" >&2
exit 1
}
cargo build -q -p ely-lok --bins -p ely-doc --manifest-path "$root/Cargo.toml"
for tool in ax-values ax-press drag; do swiftc -O -o "$work/$tool" "$root/tests/scripts/$tool.swift"; done
[ "$("$work/ax-values" $$ | head -n 1)" != untrusted ] || { echo "SKIP: needs Accessibility permission"; exit 0; }
home="$work/home"
mkdir -p "$home"
prefs="$home/Library/Application Support/ElyOffice/ely-doc/settings.json"
start() {
ELY_SMOKE=hold ELY_LOCALE=en HOME="$home" perl -e 'alarm 120; exec @ARGV' "$root/target/debug/ely-doc" >"$work/out" 2>&1 &
pid=$!
for _ in $(seq 100); do "$work/ax-values" "$pid" | grep -q 'title=Back' && break; sleep 0.3; done
osascript -e "tell application \"System Events\" to set frontmost of (first process whose unix id is $pid) to true" >/dev/null
sleep 1
}
# The window's left edge and Back's center.
edges() {
local window back
window=$(osascript -e "tell application \"System Events\" to get position of first window of (first process whose unix id is $pid)" | cut -d, -f1)
back=$("$work/ax-values" "$pid" | grep -m 1 'title=Back' | sed 's/.*at=//' | cut -d, -f1)
echo "$window $back"
}
start
read -r left back <<<"$(edges)"
# Back is centered in the left panel: half its width.
[ $(( (back - left) * 2 )) -le 230 ] || fail "the left panel starts at $(( (back - left) * 2 )) points"
y=$(( $(osascript -e "tell application \"System Events\" to get position of first window of (first process whose unix id is $pid)" | cut -d, -f2 | tr -d ' ') + 400 ))
edge=$(( left + (back - left) * 2 - 1 ))
keys() { osascript -e 'tell application "System Events"' -e "$1" -e 'end tell' >/dev/null; }
quit() {
keys 'keystroke "q" using command down'
for _ in $(seq 40); do kill -0 "$pid" 2>/dev/null || break; sleep 0.25; done
! kill -0 "$pid" 2>/dev/null || fail "Cmd+Q did not quit"
wait "$pid" 2>/dev/null || true
}
# Waits until the app's AX tree holds $1.
seen() {
for _ in $(seq 40); do "$work/ax-values" "$pid" | grep -q -- "$1" && return 0; sleep 0.25; done
return 1
}
# Dragged, then quit at once: the width is still kept.
"$work/drag" "$edge" "$y" $(( edge + 80 )) "$y"
read -r _ wide <<<"$(edges)"
[ $(( wide - back )) -ge 30 ] || fail "the panel did not widen: Back moved $(( wide - back ))"
quit
grep -q '"left": [0-9]' "$prefs" || fail "a quit right after the drag lost the width: $(cat "$prefs" 2>/dev/null)"
start
read -r left again <<<"$(edges)"
[ $(( again - wide )) -le 2 ] && [ $(( wide - again )) -le 2 ] || fail "the width did not come back: $again, not $wide"
quit
# A bad stored width is shown, not silently replaced.
python3 - "$prefs" <<'PY'
import json, sys
path = sys.argv[1]
fields = json.load(open(path))
fields["panels"] = {"left": "broken", "right": 320}
open(path, "w").write(json.dumps(fields))
PY
start
keys 'keystroke "," using command down'
seen "settings cannot be read" || fail "the bad width is not shown"
# A dragged width mends it; the message goes.
osascript -e "tell application \"System Events\" to click button 1 of (first window of (first process whose unix id is $pid) whose name is \"Settings\")" >/dev/null
sleep 0.5
read -r left back <<<"$(edges)"
edge=$(( left + (back - left) * 2 - 1 ))
"$work/drag" "$edge" "$y" $(( edge + 30 )) "$y"
for _ in $(seq 20); do grep -q '"left": [0-9]' "$prefs" 2>/dev/null && break; sleep 0.25; done
grep -q '"left": [0-9]' "$prefs" || fail "the mending width is not kept"
keys 'keystroke "," using command down'
seen "title=Dark" || fail "the settings page did not load"
! "$work/ax-values" "$pid" | grep -q "cannot be read" || fail "the mended width still shows as unreadable"
quit
# A failed save is shown.
printf '{"version":1}' >"$prefs"
start
read -r left back <<<"$(edges)"
edge=$(( left + (back - left) * 2 - 1 ))
rm "$prefs"
mkdir "$prefs"
"$work/drag" "$edge" "$y" $(( edge + 60 )) "$y"
sleep 1
keys 'keystroke "," using command down'
seen "was not saved" || fail "the failed save is not shown"
# Another kind of save succeeding leaves this failure shown.
"$work/ax-press" "$pid" Dark >/dev/null
sleep 1.5
grep -q '"appearance": "dark"' "$home/Library/Application Support/ElyOffice/settings.json" || fail "Dark was not saved"
seen "was not saved" || fail "the panel failure vanished on another save"
# Once the panel save works again, the failure goes.
rmdir "$prefs"
# Out of the way: the settings window covers the edge.
osascript -e "tell application \"System Events\" to click button 1 of (first window of (first process whose unix id is $pid) whose name is \"Settings\")" >/dev/null
sleep 0.5
read -r left back <<<"$(edges)"
edge=$(( left + (back - left) * 2 - 1 ))
"$work/drag" "$edge" "$y" $(( edge + 30 )) "$y"
for _ in $(seq 20); do grep -q '"left": [0-9]' "$prefs" 2>/dev/null && break; sleep 0.25; done
grep -q '"left": [0-9]' "$prefs" || fail "the retried width is not kept"
keys 'keystroke "," using command down'
# The page's own controls first: an empty tree proves nothing.
seen "title=Dark" || fail "the settings page did not load"
! "$work/ax-values" "$pid" | grep -q "was not saved" || fail "the fixed failure still shows"
quit
echo "ok: panels"