m9-scroll.sh
raw
#!/usr/bin/env bash
# M9 scroll-area test under quibble:
# 1. wheel scrolling moves the content (screenshots differ),
# 2. hit testing follows the offset: the same click point selects a
# different, correct row after scrolling,
# 3. scrolling far past the end clamps (top row identity proves it),
# 4. idle renders zero frames.
set -euo pipefail
cd "$(dirname "$0")/.."
cargo build -p guiduck --example m9_scroll
workdir=$(mktemp -d)
sock="$workdir/quibble.sock"
cleanup() {
quibblectl --socket "$sock" quit >/dev/null 2>&1 || true
rm -rf "$workdir"
}
trap cleanup EXIT
GUIDUCK_BACKEND=software GUIDUCK_TRACE_FRAMES=1 \
quibble --socket "$sock" --width 480 --height 360 \
target/debug/examples/m9_scroll \
>"$workdir/out.log" 2>"$workdir/err.log" &
for _ in $(seq 1 50); do
quibblectl --socket "$sock" ping >/dev/null 2>&1 && break
sleep 0.2
done
quibblectl --socket "$sock" wait-window --timeout-ms 30000 >/dev/null
sleep 1
frames() { grep -c '^guiduck-frame' "$workdir/err.log" || true; }
qc() { quibblectl --socket "$sock" "$@" >/dev/null; }
last_click() { grep '^clicked=' "$workdir/out.log" | tail -1; }
fail=0
# Layout: title ~y16..40, scroll area from y~48; rows are 36px.
# Row 0 spans y 48..84; the click point y=66 is inside row 0.
CLICK_X=100; CLICK_Y=66
# Baseline: the click hits row 0.
qc pointer-move $CLICK_X $CLICK_Y
qc click
sleep 0.3
v=$(last_click)
if [ "$v" = "clicked=Row 0" ]; then
echo "baseline click: $v"
else
echo "FAIL: baseline; got '$v'" >&2; fail=1
fi
# 1: wheel scrolling changes pixels.
quibblectl --socket "$sock" screenshot -o "$workdir/before.png" >/dev/null
qc axis vertical 108
sleep 0.4
quibblectl --socket "$sock" screenshot -o "$workdir/after.png" >/dev/null
if cmp -s "$workdir/before.png" "$workdir/after.png"; then
echo "FAIL: wheel scroll did not repaint" >&2; fail=1
else
echo "wheel scroll: pixels moved"
fi
# 2: the same point now hits a later row (scrolled by 108px = 3 rows).
qc pointer-move $CLICK_X $CLICK_Y
qc click
sleep 0.3
v=$(last_click)
if [ "$v" = "clicked=Row 3" ]; then
echo "hit test follows scroll: $v"
else
echo "FAIL: post-scroll click; got '$v' (expected Row 3)" >&2; fail=1
fi
# 3: scrolling far past the end clamps; content is 30*36=1080 in a ~296px
# viewport, so the top visible row after clamping is well past 20.
qc axis vertical 100000
sleep 0.4
qc pointer-move $CLICK_X $CLICK_Y
qc click
sleep 0.3
v=$(last_click)
case "$v" in
"clicked=Row 2"[0-9])
echo "clamped at end: $v" ;;
*)
echo "FAIL: clamped click; got '$v'" >&2; fail=1 ;;
esac
# 4: idle.
q0=$(frames); sleep 3; q1=$(frames)
echo "idle frames: $q0 -> $q1"
[ "$q0" = "$q1" ] || { echo "FAIL: rendering while idle" >&2; fail=1; }
[ "$fail" -eq 0 ] && echo "M9 scroll test PASSED"
exit $fail