Files
DankMaterialShell/quickshell/tests
purian23 2747a75198 hyprland: bring up features parity overhaul w/0.56+ and upcoming stable releases
- new blur variants, glow, wobble, motion blur and groupbar support
- new inputs support for mouse, touchpad and keyboard settings
- greeter, cheatsheet and scroll capture dispatch in Lua
- scrolling workspace screenshot focus fix
- fix scrolling screenshots from being cut-off on fractional-scale displays
- workspaces are keyed by address on the beta branch and upcoming stable release where named workspaces have no id
- bind flags, per-device binds, new window-rule keys and effects
- outputs default to preferred/auto/auto and gate HDR/VRR on hardwareDetails
- new dms setup/installer systemd session support on hyprland-session.target
2026-10-09 05:14:55 -04:00
..
2026-10-08 16:44:10 -04:00

Shell tests

make test-qml runs three suites: logic (the *.test.mjs files here under node --test), qt (qmltestrunner over unit/) and lock (qmltestrunner over lock/ with the mocks in lock/mocks). It needs Python 3, Node.js, Lua, make and the Qt 6 qmltestrunner. The Nix development shell includes them.

The qml-tests pre-commit hook runs the same suites when shell code, tests or their configuration changes. CI runs that hook in the QML tests job.

prek run qml-tests --all-files
python3 quickshell/tests/run-qml.py logic
python3 quickshell/tests/run-qml.py qt
python3 quickshell/tests/run-qml.py lock

Set QMLTESTRUNNER to override the Qt 6 executable.

Writing a test

  • A test exercises a .js module, a function of a Services/ or Common/ singleton, or an IPC handler. Nothing under Modules/, Modals/ or Widgets/ is read, sliced or mocked. Those files change with every UI tweak, and tests over them only ever failed on the tweak.
  • No compositor, display server, running shell, timers or waits. Each suite finishes in well under a second.
  • A test must fail on the broken code. No defaults, no tables asserted against a copy of themselves, no "it instantiates".
  • When a test slices QML source, the mock has to honour the arguments the function passes. A mock that ignores them passes on the old code and fails on an equivalent rewrite.