ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git), ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
87 lines
3.4 KiB
Bash
Executable File
87 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Six apps at three widths: nothing passes the window's sides.
|
|
set -euo pipefail
|
|
|
|
root=$(cd "$(dirname "$0")/../.." && pwd)
|
|
[ "$(uname)" = Darwin ] || { echo "SKIP: macOS only"; exit 0; }
|
|
work=$(mktemp -d)
|
|
shots=${ELY_LAYOUT_SHOTS:-$work/shots}
|
|
cleanup() {
|
|
local status=$?
|
|
[ -n "${pid:-}" ] && { pkill -9 -P "$pid" 2>/dev/null || true; kill "$pid" 2>/dev/null || true; }
|
|
[ "$status" = 0 ] && [ -z "${ELY_LAYOUT_SHOTS:-}" ] && rm -rf "$work" || echo "kept $work" >&2
|
|
exit "$status"
|
|
}
|
|
trap cleanup EXIT
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
cargo build -q --release --manifest-path "$root/Cargo.toml" --bins -p ely-lok -p ely-pdf-engine \
|
|
-p ely-doc -p ely-table -p ely-show -p ely-pdf -p ely-tree -p ely-mark
|
|
swiftc -O -o "$work/ax-frames" "$root/tests/scripts/ax-frames.swift"
|
|
[ "$("$work/ax-frames" $$ | head -n 1)" != untrusted ] || { echo "SKIP: needs Accessibility permission"; exit 0; }
|
|
mkdir -p "$shots" "$work/repo"
|
|
git -C "$work/repo" init -q
|
|
printf '# Notes\n\nA paragraph long enough to wrap at a narrow width, with **bold** words.\n' >"$work/notes.md"
|
|
cp "$work/notes.md" "$work/repo/notes.md"
|
|
fixtures=$root/tests/fixtures/office
|
|
|
|
# Elements past the window's sides; scrolled rows may pass below.
|
|
outside() {
|
|
python3 - "$1" <<'PY'
|
|
import json, sys
|
|
rows = [json.loads(line) for line in open(sys.argv[1]) if line.startswith("{")]
|
|
window = next(row for row in rows if row["role"] == "AXWindow")
|
|
wx, wy, ww, wh = window["frame"]
|
|
for row in rows:
|
|
if "frame" not in row or row["role"] in ("AXWindow", "AXMenuBar", "AXMenuBarItem", "AXMenu", "AXMenuItem"):
|
|
continue
|
|
x, y, w, h = row["frame"]
|
|
if w <= 0 or h <= 0:
|
|
continue
|
|
if x < wx - 1 or x + w > wx + ww + 1:
|
|
print(f'{row["role"]} "{row["name"]}" at {x:.0f},{y:.0f} {w:.0f}x{h:.0f}; window {wx:.0f},{wy:.0f} {ww:.0f}x{wh:.0f}')
|
|
PY
|
|
}
|
|
|
|
window_id() {
|
|
swift -e 'import CoreGraphics; let l = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as! [[String: Any]]; for w in l where (w["kCGWindowOwnerPID"] as? Int) == Int(CommandLine.arguments[1])! && (w["kCGWindowLayer"] as? Int) == 0 { print(w["kCGWindowNumber"]!); break }' "$1"
|
|
}
|
|
|
|
check() { # slug, file
|
|
local slug=$1 file=$2 home=$work/home-$1
|
|
mkdir -p "$home"
|
|
HOME=$home ELY_SMOKE=hold ELY_NO_DIALOG=1 ELY_LOCALE=en "$root/target/release/$slug" "$file" >"$work/$slug.out" 2>&1 &
|
|
pid=$!
|
|
sleep 8
|
|
for width in 640 800 1100; do
|
|
osascript -e "tell application \"System Events\" to tell (first process whose unix id is $pid)" \
|
|
-e "set size of window 1 to {$width, 680}" -e "set position of window 1 to {80, 60}" \
|
|
-e "set frontmost to true" -e "end tell" >/dev/null
|
|
sleep 2
|
|
# GPUI builds its AX tree once asked.
|
|
"$work/ax-frames" "$pid" >/dev/null
|
|
sleep 1
|
|
"$work/ax-frames" "$pid" >"$work/$slug-$width.jsonl"
|
|
[ "$(grep -c '"frame"' "$work/$slug-$width.jsonl")" -gt 8 ] || fail "$slug at $width: no AX content"
|
|
screencapture -x -l"$(window_id "$pid")" "$shots/$slug-$width.png"
|
|
out=$(outside "$work/$slug-$width.jsonl")
|
|
[ -z "$out" ] || fail "$slug at $width leaves the window:
|
|
$out"
|
|
done
|
|
pkill -9 -P "$pid" 2>/dev/null || true
|
|
kill "$pid" 2>/dev/null || true
|
|
wait "$pid" 2>/dev/null || true
|
|
pid=
|
|
}
|
|
|
|
check ely-doc "$fixtures/t.docx"
|
|
check ely-table "$fixtures/t.xlsx"
|
|
check ely-show "$fixtures/t.pptx"
|
|
check ely-pdf "$fixtures/t.pdf"
|
|
check ely-tree "$work/repo"
|
|
check ely-mark "$work/notes.md"
|
|
echo "ok: layout (screenshots in $shots)"
|