Commit Graph

1 Commits

Author SHA1 Message Date
Ignacy Łątka 05e619e55d ci: device E2E smoke tests for every hosted-CI platform (#371)
## What

`wayland-e2e.yml` boots an Android AVD on Linux under headless Weston
and asserts the full pipeline works without a display. It guards exactly
one cell of the support matrix. This adds the same
boot→screenshot→gesture-tap smoke test for every other (target × host)
cell that can run on GitHub-hosted runners.

| target | host | job | status |
|---|---|---|---|
| Android emulator | Linux (KVM) | `wayland-e2e.yml` (existing) | ✅ |
| iOS simulator | macOS | `ios-sim-macos` | ✅ |
| Chromium / Electron | Linux (Xvfb) | `chromium-linux` | ✅ |
| Chromium / Electron | macOS | `chromium-macos` | ✅ |

## How

- **`scripts/e2e/drive-device.sh`** — shared driver. Boots one device
through the tool-server, then asserts `booted:true` → screenshot has
real (non-blank) pixels → `gesture-tap` round-trips. Every tool takes
the device id as `udid` and screenshots come back as the same
`data.image.hostPath` envelope on all platforms, so the body is uniform;
each job just supplies the cell-specific boot JSON + device id.
- **`packages/tool-server/test/fixtures/electron-smoke-app/`** — minimal
self-contained Electron app the Chromium jobs point `electronAppPath`
at. It vendors its own electron via its own lockfile (kept out of the
repo root lockfile); CI `npm ci`s it so `boot-electron` resolves
`./node_modules/.bin/electron`.
- **`.github/workflows/e2e-device-smoke.yml`** — three jobs,
`workflow_dispatch` + path-filtered `pull_request`. iOS downloads the
darwin native binaries (injection must succeed for `bootIos` to report
`booted:true`); Chromium-Linux runs under Xvfb with `--no-sandbox`. The
tool-server is started with `TS_NODE_TRANSPILE_ONLY=1` so cold ts-node
startup doesn't flakily exceed the readiness poll on loaded macOS
runners (types are still enforced by the typecheck job).

## Known gaps (supported on real machines, not runnable on hosted
runners)

- **Android emulator on macOS** — the arm64 emulator needs HVF
(`-enable-hvf`), but hosted macOS runners are themselves VMs with no
nested virtualization. Confirmed by running it: qemu dies with `HVF
error: HV_UNSUPPORTED` ~18s into boot, regardless of GPU mode or RAM.
The Android boot/screenshot/tap path is already regression-guarded on
Linux via KVM (`wayland-e2e.yml`), so macOS adds no runnable coverage.
- **Physical devices** — real iOS (CoreDevice HID) and real Android
(adb-USB) have no attached hardware on hosted runners.

Both would need self-hosted runners (a Mac exposing HVF / wired-up
devices). Documented in the workflow header.

## Verification

- All checks green: the 3 device jobs + ESLint + Prettier + Unit tests.
- Locally (before CI): ran `drive-device.sh` end-to-end against a real
tool-server → boot `booted:true`, screenshot **142 KB** (floor 20 KB),
tap `tapped:true`, exit 0; and confirmed via the Argent stack that a tap
at (0.5, 0.5) lands on the fixture's centered button and increments its
counter.
2026-06-26 17:44:17 +02:00