Spectre¶
Spectre is a Kotlin library for driving live Compose Desktop UIs from automated tests. It reads the Compose semantics tree, drives mouse and keyboard input either through real OS-level events or through synthetic AWT events dispatched straight into the window hierarchy, and records what happens on screen — against IDE-hosted Compose surfaces (IntelliJ, Jewel) and standalone desktop apps alike.
If you've used UI Automator on Android or Espresso for that matter, the shape will feel familiar — Spectre brings the same "find a node, do a thing, assert" loop to Compose Desktop.
Pre-release
Spectre is in bootstrap. There are no published Maven artifacts yet, the public API is still settling, and parts of the codebase are explicitly flagged as not yet hand-audited in the README. Treat anything here as a moving target until a tagged release lands.
Why Spectre¶
- Real Compose Desktop, not a simulator. Spectre runs against your actual application windows. Semantics, layout, focus, popups, and HiDPI all come from the running UI rather than a parallel test harness.
- In-process or cross-JVM. Use
ComposeAutomator.inProcess()for the simple case, or use theservermodule to drive a UI hosted in a different JVM (e.g., an IDE under test). - Real or synthetic input.
ComposeAutomator.inProcess()defaults to OS-leveljava.awt.Robotevents. Swap inRobotDriver.synthetic(...)and AWT events go directly into the window hierarchy — useful when tests run in parallel and can't fight over OS focus. - Recording built in. Region capture via
ffmpeg, plus window-targeted capture (ScreenCaptureKit on macOS,gdigrabon Windows, x11grab/portal on Linux). TheAutoRecorderpicks the right backend per call. - JUnit-friendly. Drop-in extension and rule for JUnit 5 and JUnit 4 manage a per-test automator instance for you.
Where to start¶
- Getting started — Install Spectre and write your first test.
- The automator — Concepts: semantics surfaces, queries vs. interactions, why there is no auto-wait.
- Finding nodes —
findByTestTag,findByText,findByContentDescription,findByRole, and theprintTree()debugger. - Synchronization
—
waitForIdle,waitForVisualIdle,waitForNode, and the EDT rule. - Recording — Region and window-targeted capture across macOS, Windows, and Linux.
- Cross-JVM — Drive a UI hosted in another JVM process via the embedded HTTP transport.