windowmaker-wl/tests/x11-smoke-test.sh

124 lines
4.0 KiB
Bash
Executable File

#!/bin/sh
# tests/smoke-test.sh
#
# Verifies that wmaker starts and is actually managing windows.
# Spawns its own Xwayland instance; no pre-existing display needed.
#
# Dependencies: Xwayland, xclock, xprop, xwininfo
# Optional (--input only): xdotool
#
# Usage: sh tests/smoke-test.sh [--input]
# --input also run the Phase 3/7 input delivery check
# (click titlebar -> verify _NET_ACTIVE_WINDOW)
#
# Exit 0 = PASS, non-zero = FAIL.
set -e
D=:98 # use a high display number unlikely to conflict
INPUT=0
[ "$1" = "--input" ] && INPUT=1
XWAYLAND_PID=""
WM_PID=""
CLIENT_PID=""
cleanup() {
kill $CLIENT_PID $WM_PID $XWAYLAND_PID 2>/dev/null
# Remove Xwayland lock file if it was left behind
rm -f /tmp/.X${D#:}-lock /tmp/.X11-unix/X${D#:}
}
trap cleanup EXIT INT TERM
die() {
echo "FAIL: $*" >&2
exit 1
}
# -- Spawn Xwayland ------------------------------------------------------
Xwayland "$D" &
XWAYLAND_PID=$!
# Wait until the display socket appears (up to 5s)
i=0
while [ $i -lt 50 ]; do
DISPLAY=$D xdpyinfo >/dev/null 2>&1 && break
sleep 0.1
i=$(( i + 1 ))
done
DISPLAY=$D xdpyinfo >/dev/null 2>&1 || die "Xwayland did not start on $D"
# -- Start wmaker --------------------------------------------------------
DISPLAY=$D src/wmaker &
WM_PID=$!
# Wait until WM announces itself (up to 5s)
i=0
while [ $i -lt 50 ]; do
kill -0 $WM_PID 2>/dev/null || die "wmaker exited during startup"
DISPLAY=$D xprop -root _NET_SUPPORTING_WM_CHECK 2>/dev/null | grep -q 'window id' && break
sleep 0.1
i=$(( i + 1 ))
done
kill -0 $WM_PID 2>/dev/null || die "wmaker is not running"
# 1. WM must have announced itself via EWMH
DISPLAY=$D xprop -root _NET_SUPPORTING_WM_CHECK | grep -q 'window id' \
|| die "_NET_SUPPORTING_WM_CHECK not set on root"
# WindowMaker sets _WINDOWMAKER_NOTICEBOARD on its info_window (does not use _NET_WM_NAME)
INFO_WIN=$(DISPLAY=$D xprop -root _NET_SUPPORTING_WM_CHECK | awk '{print $NF}')
DISPLAY=$D xprop -id "$INFO_WIN" _WINDOWMAKER_NOTICEBOARD 2>/dev/null | grep -q 'window id' \
|| die "_WINDOWMAKER_NOTICEBOARD not set on WM check window (not WindowMaker?)"
# -- Launch a test client ------------------------------------------------
DISPLAY=$D xclock &
CLIENT_PID=$!
# Wait for xclock to appear and be managed (up to 5s)
i=0
CLIENT=""
while [ $i -lt 50 ]; do
CLIENT=$(DISPLAY=$D xwininfo -name xclock 2>/dev/null | awk '/Window id:/{print $4}')
[ -n "$CLIENT" ] && \
DISPLAY=$D xprop -id "$CLIENT" WM_STATE 2>/dev/null | grep -q 'window state: Normal' && break
sleep 0.1
i=$(( i + 1 ))
done
[ -n "$CLIENT" ] || die "could not find xclock window after 5s"
# 2. WM_STATE must be NormalState
DISPLAY=$D xprop -id "$CLIENT" WM_STATE | grep -q 'window state: Normal' \
|| die "WM_STATE is not NormalState on client"
# 3. Client must have been reparented (parent != root)
ROOT_ID=$(DISPLAY=$D xwininfo -root | awk '/Window id:/{print $4}')
PARENT=$(DISPLAY=$D xwininfo -id "$CLIENT" | awk '/Parent window:/{print $3}')
[ "$PARENT" != "$ROOT_ID" ] \
|| die "client was not reparented into a frame (parent is still root)"
# 4. _NET_CLIENT_LIST must be non-empty
DISPLAY=$D xprop -root _NET_CLIENT_LIST | grep -qv 'not found' \
|| die "_NET_CLIENT_LIST is empty or missing"
# -- Optional: input delivery check (Phase 3 / Phase 7) -----------------
if [ "$INPUT" = "1" ]; then
# Click the titlebar (just above the client area) and verify the
# window becomes _NET_ACTIVE_WINDOW.
CLIENT_X=$(DISPLAY=$D xwininfo -id "$CLIENT" | awk '/Abs.*X:/{print $4; exit}')
CLIENT_Y=$(DISPLAY=$D xwininfo -id "$CLIENT" | awk '/Abs.*Y:/{print $4; exit}')
TITLEBAR_Y=$(( CLIENT_Y - 10 ))
DISPLAY=$D xdotool mousemove --sync "$CLIENT_X" "$TITLEBAR_Y"
DISPLAY=$D xdotool click 1
sleep 0.3
ACTIVE=$(DISPLAY=$D xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}')
[ "$ACTIVE" = "$CLIENT" ] \
|| die "titlebar click did not activate window (active=$ACTIVE want=$CLIENT)"
fi
# -- Done ----------------------------------------------------------------
echo "PASS"
exit 0