|
| 1 | +#!/bin/bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +readonly ROOT_DIR="$PWD" |
| 5 | +readonly WORK_DIR="$ROOT_DIR/.midscene-omarchy" |
| 6 | +readonly HARNESS_DIR="$WORK_DIR/omarchy-iso" |
| 7 | +readonly ISO_PATH="$WORK_DIR/omarchy-4.0.3.iso" |
| 8 | +readonly BASE_DIR="$HARNESS_DIR/test-runs/omarchy-4.0.3" |
| 9 | +readonly SSH_KEY="$BASE_DIR/id_ed25519" |
| 10 | +readonly SSH_PORT=2222 |
| 11 | +readonly PLUGIN_DIR="/home/omarchy/.config/omarchy/plugins/md.lifeos.doubao-say" |
| 12 | +readonly SHIM_DIR="$(mktemp -d)" |
| 13 | + |
| 14 | +VM_PID="" |
| 15 | + |
| 16 | +cleanup() { |
| 17 | + if [[ -n $VM_PID ]]; then |
| 18 | + kill "$VM_PID" 2>/dev/null || true |
| 19 | + fi |
| 20 | + rm -rf "$SHIM_DIR" |
| 21 | +} |
| 22 | +trap cleanup EXIT |
| 23 | + |
| 24 | +ssh_guest() { |
| 25 | + ssh -i "$SSH_KEY" -p "$SSH_PORT" \ |
| 26 | + -o BatchMode=yes \ |
| 27 | + -o IdentitiesOnly=yes \ |
| 28 | + -o StrictHostKeyChecking=no \ |
| 29 | + -o UserKnownHostsFile=/dev/null \ |
| 30 | + -o ConnectTimeout=10 \ |
| 31 | + -o LogLevel=ERROR \ |
| 32 | + omarchy@127.0.0.1 "$@" |
| 33 | +} |
| 34 | + |
| 35 | +ssh_session() { |
| 36 | + local command="$1" |
| 37 | + ssh_guest "export XDG_RUNTIME_DIR=/run/user/\$(id -u); \ |
| 38 | + export DBUS_SESSION_BUS_ADDRESS=unix:path=\$XDG_RUNTIME_DIR/bus; \ |
| 39 | + export HYPRLAND_INSTANCE_SIGNATURE=\$(ls -t \$XDG_RUNTIME_DIR/hypr | head -1); \ |
| 40 | + export WAYLAND_DISPLAY=\$(find \$XDG_RUNTIME_DIR -maxdepth 1 -name 'wayland-*' ! -name '*.lock' -printf '%f\\n' | head -1); \ |
| 41 | + export OMARCHY_PATH=/usr/share/omarchy; \ |
| 42 | + export PATH=\$OMARCHY_PATH/bin:\$PATH; \ |
| 43 | + $command" </dev/null |
| 44 | +} |
| 45 | + |
| 46 | +test -s "$ISO_PATH" |
| 47 | +test -s "$BASE_DIR/base.qcow2" |
| 48 | +test -s "$SSH_KEY" |
| 49 | + |
| 50 | +# Reuse the pinned official harness's VM, login and session routines. Replace |
| 51 | +# only its post-login acceptance body so this job can hand the live desktop to |
| 52 | +# Midscene instead of running Omarchy's unrelated upstream acceptance suite. |
| 53 | +readonly SESSION_HARNESS="$HARNESS_DIR/bin/omarchy-midscene-session" |
| 54 | +cp "$HARNESS_DIR/bin/omarchy-iso-test" "$SESSION_HARNESS" |
| 55 | +sed -i '/^acceptance_phase() {/,/^}/c\ |
| 56 | +acceptance_phase() {\ |
| 57 | + log "Booting Omarchy session for Doubao Say Midscene E2E"\ |
| 58 | + qemu-img create -f qcow2 -b "$BASE_DISK" -F qcow2 "$RUN_DIR/run.qcow2" >/dev/null\ |
| 59 | + start_vm "$RUN_DIR/run.qcow2" "$RUN_DIR/serial.log"\ |
| 60 | + establish_session\ |
| 61 | + capture_console "success-session-ready-for-midscene"\ |
| 62 | +}' "$SESSION_HARNESS" |
| 63 | + |
| 64 | +printf '#!/bin/sh\nexit 0\n' >"$SHIM_DIR/omarchy-pkg-add" |
| 65 | +printf '#!/bin/sh\nexec convert "$@"\n' >"$SHIM_DIR/magick" |
| 66 | +chmod 0755 "$SHIM_DIR/omarchy-pkg-add" "$SHIM_DIR/magick" |
| 67 | + |
| 68 | +PATH="$SHIM_DIR:$PATH" "$SESSION_HARNESS" "$ISO_PATH" \ |
| 69 | + --reuse-base \ |
| 70 | + --keep-running \ |
| 71 | + --memory 4096 \ |
| 72 | + --no-preview |
| 73 | + |
| 74 | +readonly RUN_DIR="$(find "$BASE_DIR/runs" -mindepth 1 -maxdepth 1 -type d | sort | tail -1)" |
| 75 | +VM_PID="$(cat "$RUN_DIR/qemu.pid")" |
| 76 | +kill -0 "$VM_PID" |
| 77 | + |
| 78 | +# Put this exact checkout at its real Omarchy plugin location, validate the |
| 79 | +# manifest with Omarchy, then launch the deterministic GTK fixture in the |
| 80 | +# guest's actual Hyprland session. |
| 81 | +tar -C "$ROOT_DIR" --exclude='__pycache__' -cf - \ |
| 82 | + LICENSE README.md manifest.json install.sh install-user.sh setup-omarchy.sh start.sh \ |
| 83 | + omarchy src tests/midscene/gtk_fixture.py | \ |
| 84 | + ssh_guest "rm -rf '$PLUGIN_DIR' && mkdir -p '$PLUGIN_DIR' && tar -C '$PLUGIN_DIR' -xf -" |
| 85 | + |
| 86 | +ssh_session "omarchy plugin validate '$PLUGIN_DIR'" |
| 87 | +ssh_session "rm -rf /tmp/doubao-midscene-config; \ |
| 88 | + mkdir -p /tmp/doubao-midscene-config; \ |
| 89 | + export PYTHONPATH='$PLUGIN_DIR/src'; \ |
| 90 | + export XDG_CONFIG_HOME=/tmp/doubao-midscene-config; \ |
| 91 | + export PYTHONDONTWRITEBYTECODE=1; \ |
| 92 | + setsid -f python3 '$PLUGIN_DIR/tests/midscene/gtk_fixture.py' \ |
| 93 | + >/tmp/doubao-midscene-fixture.log 2>&1" |
| 94 | + |
| 95 | +for _attempt in $(seq 1 30); do |
| 96 | + if ssh_session "grep -q 'READY: synthetic Doubao Say GTK fixture' /tmp/doubao-midscene-fixture.log && \ |
| 97 | + hyprctl -j clients | jq -e '[.[] | select(.title == \"Doubao Say\")] | length == 1'" \ |
| 98 | + >/dev/null 2>&1; then |
| 99 | + break |
| 100 | + fi |
| 101 | + sleep 2 |
| 102 | +done |
| 103 | + |
| 104 | +ssh_session "grep -q 'READY: synthetic Doubao Say GTK fixture' /tmp/doubao-midscene-fixture.log" |
| 105 | +ssh_session "hyprctl -j clients | jq -e '[.[] | select(.title == \"Doubao Say\")] | length == 1'" |
| 106 | + |
| 107 | +OMARCHY_E2E=true npm --prefix tests/midscene test -- \ |
| 108 | + e2e/omarchy-onboarding.test.ts |
| 109 | + |
| 110 | +ssh_session "hyprctl -j clients | jq -e '[.[] | select(.title == \"Doubao Say\")] | length == 1'" |
0 commit comments