On the laptop the browser jumped behind the disc player the moment it was
opened. 0.2.4 caused that, and the cause is two lines of the stock applet:
main.qml:153 hideActivatedLaunchers: tasks.iconsOnly || ...
main.qml:155 launchInPlace: tasks.iconsOnly && sortingStrategy === 1
For an icons-only bar the first is always true — a launcher is hidden the
instant its application starts — and the second is what puts the running
window back where the launcher was. It only does that at sortingStrategy
1. 0.2.4 set it to 0 to stop teachers dragging the icons about, so the
launcher vanished and the window was appended after the others.
Reproduced in the lab with a real Chrome window before changing anything,
and the bar read off the screen: Wonder Ink, the player, then the
browser. With 1 it is Wonder Ink, the browser, the player, through
opening, a second window, another application opening beside it, and
every close.
The launcher identity was suspected and cleared: only one browser button
appears, because google-chrome.desktop already carries Chrome's own file
name and StartupWMClass for exactly this reason.
THE COST, AND IT IS REAL. Manual sorting is also the only mode in which
MouseHandler.qml accepts a reordering drop, so a teacher who knows to drag
can rearrange the bar again. There is no value that gives both and no
Kiosk key that separates them. classroom-desktop-reset already rebuilds
the bar from the package at every login, so a drag never outlives the
session. docs/testing.md states the trade rather than burying it, and the
configuration escape is written down there too as still open.
tools/lab/order-check is the test this needed and did not have. 0.2.4
passed a full set of configuration assertions while the bar did something
else, so this one opens real application windows and reads the panel
strip as pixels — there is no image library in the lab, so it captures
PPM and names each icon by colour. Six checks, all of them behaviour.
Co-Authored-By: Claude Opus 5 <[email protected]>
447 lines
20 KiB
Markdown
447 lines
20 KiB
Markdown
# Classroom test checklist
|
|
|
|
Run against the exact artifact published to canary, on the real endpoint,
|
|
before promoting to stable with `./update_stable.sh`.
|
|
|
|
## Boot
|
|
|
|
- [ ] Cold boot reaches the classroom shell with no terminal or window junk
|
|
- [ ] Reboot does the same
|
|
- [ ] Wallpaper appears
|
|
- [ ] Dock appears, centred
|
|
- [ ] Clock appears, bottom right
|
|
|
|
## Provisioning
|
|
|
|
- [ ] `journalctl -u ekklesia-classroom-provision` shows a clean run
|
|
- [ ] Google Chrome is installed on a machine that never had it
|
|
- [ ] A second boot does not reinstall anything
|
|
- [ ] A machine with no network still boots to a working shell, and
|
|
provisioning succeeds at a later boot once it is online
|
|
|
|
## Networking
|
|
|
|
- [ ] `nmtui` is installed and `NetworkManager.service` is enabled
|
|
- [ ] An Ethernet interface declared in `/etc/network/interfaces` remains
|
|
managed by ifupdown and keeps its existing address
|
|
- [ ] `sudo nmtui` can save and activate a Wi-Fi connection
|
|
- [ ] The saved Wi-Fi connection reconnects after reboot
|
|
- [ ] A machine with no Wi-Fi adapter reaches the classroom normally without
|
|
an online-wait delay or NetworkManager failure
|
|
- [ ] Ethernet-only operation is unchanged
|
|
|
|
## Printing
|
|
|
|
- [ ] `cups.service` is enabled and `lpstat -r` reports that the scheduler runs
|
|
- [ ] `lpinfo -m` contains the generic color PCL 6/PCL XL driver documented in
|
|
[printing.md](printing.md)
|
|
- [ ] `sudo classroom-printer-setup` creates only `Elmer`, enables it, and
|
|
makes it the system default
|
|
- [ ] Provisioning creates Elmer automatically at
|
|
`socket://10.10.0.155:9100` with description `Elmer`
|
|
- [ ] `lpoptions -p Elmer -l` shows `*Normal` for `PrintoutMode` and `*Color`
|
|
for `ColorModel`
|
|
- [ ] An upgrade removes the old `Classroom_Color` queue
|
|
- [ ] Repeating provisioning reports Elmer already configured and does not
|
|
rewrite the queue
|
|
- [ ] Chrome opens the system print dialog and shows only Elmer
|
|
- [ ] `lpstat -e` prints only `Elmer`; neither the Brother label printer nor a
|
|
discovered duplicate Ricoh appears
|
|
- [ ] `avahi-daemon.service` and `avahi-daemon.socket` are masked
|
|
- [ ] The CUPS test page prints in color on the Ricoh MP C3502
|
|
- [ ] With the Ricoh powered off, the classroom still boots normally and a job
|
|
simply remains queued
|
|
|
|
## Secondary Chrome windows
|
|
|
|
- [ ] The first Chrome top-level remains maximised, tiled and borderless
|
|
- [ ] A second `google-chrome` top-level floats instead of splitting the main
|
|
browser
|
|
- [ ] It is centred at roughly three quarters of the logical display
|
|
- [ ] Its red Close button is visible and mouse-accessible
|
|
- [ ] Close removes only the secondary and reveals the untouched main browser
|
|
- [ ] Changing either page title does not change the main/secondary roles
|
|
- [ ] A third Chrome top-level also floats and Close targets the newest one
|
|
- [ ] Chrome minimise/restore and the dock Browser button still behave normally
|
|
|
|
## UI scale
|
|
|
|
UI_SCALE sets sway's output scale, so it scales the whole session.
|
|
Change it, then `sudo systemctl restart getty@tty1`.
|
|
|
|
- [ ] `UI_SCALE=1.0` is identical to a session with no scaling
|
|
- [ ] `swaymsg -t get_outputs` shows the mode still 1920x1080 at every
|
|
scale, with only the logical size changing
|
|
- [ ] At 1.25 and 1.5, **Chrome** grows: tabs, omnibox, toolbar icons,
|
|
menus and page content
|
|
- [ ] Chrome's buttons are still easy to hit with the mouse
|
|
- [ ] Dock, clock, notifications and the DVD bar grow by the same
|
|
amount — once, not twice
|
|
- [ ] Dock icons stay crisp at 1.25 and 1.5 on a normal-density monitor,
|
|
not just from across the room: compare an icon against the clock
|
|
text beside it
|
|
- [ ] DVD control bar icons are crisp at the same scales
|
|
- [ ] `UI_SCALE=0.8` shrinks everything together
|
|
- [ ] A nonsense value (`UI_SCALE=banana`) still gives a working shell
|
|
- [ ] An extreme value (`UI_SCALE=9`) is clamped, not obeyed
|
|
- [ ] `journalctl` or the sway log shows `classroom-scale: session scale N`
|
|
|
|
## Reserved bottom shell (regression)
|
|
|
|
The bottom strip is one full-width layer-shell surface with a 76px
|
|
exclusive zone. Dock and clock live inside it. Do not split them back
|
|
into separate layer-shell windows.
|
|
|
|
- [ ] A maximised Chrome window stops above the bottom strip
|
|
- [ ] The clock does not float over Chrome
|
|
- [ ] Dock stays centred, clock stays bottom right
|
|
- [ ] Wallpaper shows through the unused parts of the strip
|
|
- [ ] Every dock button still responds to clicks
|
|
- [ ] A fullscreen application covers the whole display, dock included
|
|
|
|
## Browser
|
|
|
|
- [ ] First Browser click launches Chrome
|
|
- [ ] Chrome opens on Wonder Ink (https://app.wonderink.org/)
|
|
- [ ] Clicking Browser while Chrome is focused minimises it
|
|
- [ ] Clicking Browser again restores it **maximised, not floating or draggable**
|
|
- [ ] Clicking Browser while Chrome is running but unfocused focuses it
|
|
- [ ] `Super+M` minimises the focused window
|
|
- [ ] `Super+Shift+M` restores the most recently minimised window
|
|
- [ ] Normal navigation to any other site works
|
|
- [ ] The Home button returns to Wonder Ink
|
|
- [ ] Fullscreen YouTube video uses the whole display
|
|
- [ ] Leaving fullscreen restores the correct geometry above the dock
|
|
- [ ] The main Chrome window has **no sway title bar** — it starts at Chrome's
|
|
own tab strip, and Chrome's tabs and address bar are still there
|
|
- [ ] Chrome still maximises and minimises as before
|
|
- [ ] After a reboot, no "Restore pages? Chrome didn't shut down
|
|
correctly" bubble
|
|
- [ ] Chrome does not offer to save passwords
|
|
- [ ] Chrome shows no way to sign into the browser itself
|
|
- [ ] No "Add profile" and no Guest entry in the profile menu
|
|
- [ ] No profile picker at startup
|
|
- [ ] Wonder Ink signs in normally during a session
|
|
- [ ] After closing Chrome fully and reopening, Wonder Ink is signed out
|
|
(see browser.md — this is the unverified one)
|
|
- [ ] YouTube is still signed into the church account after that
|
|
- [ ] `chrome://policy` lists PasswordManagerEnabled as an applied
|
|
managed policy
|
|
- [ ] Website logins still persist across a reboot
|
|
- [ ] Clicking Browser when Chrome is closed shows a throbber on the
|
|
dock button until the window appears
|
|
- [ ] Clicking Browser when Chrome is already open feels immediate,
|
|
with no throbber
|
|
- [ ] The pointer shows a busy cursor while it is over the dock
|
|
- [ ] No first-run, default-browser or sign-in nag appears
|
|
- [ ] `chrome://policy` lists the Ekklesia policies as applied, with no
|
|
"unknown policy" entries
|
|
- [ ] Chrome does not start by itself at boot
|
|
- [ ] After a reboot, cookies and site logins are still there
|
|
- [ ] After an OTA update, cookies and site logins are still there
|
|
|
|
Known limitation: Chrome's own minimise button in its title bar does
|
|
nothing. Sway ignores the Wayland minimise request and gives no event to
|
|
hook. Minimising is the dock's Browser button or `Super+M`.
|
|
|
|
## Notifications
|
|
|
|
- [ ] `classroom-notify-test` renders with the classroom styling:
|
|
dark translucent, rounded, white text, top right
|
|
- [ ] `classroom-notify-test --critical "Parent Call" "Room 3 needs a parent."`
|
|
renders in the critical style and does not time out
|
|
- [ ] Notifications appear over a fullscreen video
|
|
|
|
Over SSH from an administrator account, run it with sudo:
|
|
|
|
```
|
|
sudo classroom-notify-test --dry-run # show the session it resolved
|
|
sudo classroom-notify-test # send into the classroom desktop
|
|
```
|
|
|
|
The classroom desktop belongs to the classroom user, and mako sits on
|
|
that user's D-Bus session. A plain notify-send from an SSH session lands
|
|
in the administrator's own session, where nothing owns
|
|
org.freedesktop.Notifications, so D-Bus tries to start a second mako with
|
|
no display and the call times out with NoReply. The script finds the
|
|
running sway process for the classroom user and delivers into its
|
|
session instead. It never starts mako.
|
|
|
|
- [ ] `sudo classroom-notify-test` from an SSH session displays on the
|
|
classroom screen
|
|
- [ ] `sudo classroom-notify-test --dry-run` reports the resolved
|
|
XDG_RUNTIME_DIR, bus address and Wayland display
|
|
- [ ] Running it as an unprivileged admin account explains it needs sudo
|
|
- [ ] `tests/test-classroom-notify-test.sh` passes (also run by the build)
|
|
|
|
## Audio
|
|
|
|
The room prefers the television. `AUDIO_OUTPUT` in device.conf decides:
|
|
`auto` (prefer a connected HDMI or DisplayPort set, fall back to the
|
|
jack), `hdmi`, or `analog`. A machine with no digital output at all — a
|
|
laptop, when one arrives — is correct on `auto` without any change here.
|
|
|
|
Two test suites cover this, and both run in the build:
|
|
|
|
- [ ] `tests/test-classroom-audio.sh` — the decision itself, against the
|
|
shapes real pactl emits
|
|
- [ ] `tests/test-classroom-audio-daemon.sh` — the real daemon driven
|
|
through every situation a room gets into, against a pactl that
|
|
answers the way PipeWire does
|
|
|
|
On a machine:
|
|
|
|
- [ ] `classroom-audio show` lists the outputs, what it chose, the
|
|
profile it would set and whether it is `settled`
|
|
- [ ] `journalctl --user -u ekklesia-classroom-audio` shows one
|
|
`output is ...` line per real change and nothing in between
|
|
- [ ] Leaving the room alone for an hour adds no further lines and no
|
|
measurable CPU time
|
|
|
|
### The television switched on after the computer
|
|
|
|
This is the scenario that silenced River Kids on 0.2.2 and the one no lab
|
|
can produce: ALSA reports a television through the HDMI port's
|
|
availability, and no loopback or dummy sound driver has such a port. The
|
|
suites above play it through a mock, and the mock is faithful to the real
|
|
server as far as it was measured — but a mock cannot prove the real
|
|
ALSA jack change arrives. **Do not take a passing build as evidence that
|
|
this works.** It has to be done at a machine, once, per release:
|
|
|
|
1. Switch the television **off** at the set, not the remote.
|
|
2. Reboot the computer and let it reach the classroom desktop.
|
|
3. Leave it at least two minutes, so any startup settling is over.
|
|
4. `journalctl --user -u ekklesia-classroom-audio` — expect one
|
|
`output is ...` line. In a room with nothing in the analog jack it
|
|
names the HDMI port even now, which is right: there is nowhere
|
|
better for the sound to go, and the set is then already correct
|
|
when it comes on.
|
|
5. Open Wonder Ink and Chrome and start something playing.
|
|
6. Switch the television **on**.
|
|
7. Sound should arrive within about a minute, in both applications,
|
|
**without closing or reopening either one**.
|
|
8. `wpctl status` should show the HDMI sink as default, and
|
|
`classroom-audio show` should say `settled=True`.
|
|
9. Switch the television off and on again. Sound should come back.
|
|
10. Check the volume is where the teacher left it, and that an output
|
|
muted on purpose is still muted.
|
|
|
|
If step 7 fails, the jack change is not reaching PipeWire at all; capture
|
|
`pactl subscribe` and `classroom-audio show` with the set off and then on,
|
|
which is what distinguishes that from a policy fault.
|
|
|
|
## Device features
|
|
|
|
Every optional application is its own setting in device.conf, and
|
|
`DEVICE_TYPE` decides none of them. A laptop can take children's church
|
|
and a tower can be a Bible study.
|
|
|
|
```
|
|
DEVICE_TYPE=desktop|laptop what the hardware IS
|
|
WONDERINK_ENABLED=true|false
|
|
DVD_ENABLED=true|false a drive is still required as well
|
|
PARENT_CALL_ENABLED=true|false
|
|
NETWORK_PREFERENCE=wired|wifi
|
|
DISPLAY_MODE=all|external-only
|
|
```
|
|
|
|
All default to the classroom's existing behaviour, so an upgrade changes
|
|
nothing until somebody edits the file. `classroom-desktop-layout` writes
|
|
the answers into the packaged layout; the bar is rebuilt from it at the
|
|
next login.
|
|
|
|
- [ ] `tests/test-classroom-desktop-layout.sh` passes (also run by the build)
|
|
- [ ] After changing a setting, `classroom-desktop-layout` then a
|
|
logout/login shows the new bar
|
|
- [ ] A disabled application leaves no gap: the remaining launchers close up
|
|
- [ ] The launcher order is the same on two machines with the same
|
|
features enabled
|
|
- [ ] The order survives launching and closing applications, logout/login
|
|
and a reboot — run `tools/lab/order-check` against a live session,
|
|
which opens real windows and reads the bar off the screen
|
|
- [ ] Right-clicking a launcher offers no Pin or Unpin
|
|
|
|
### Two things the bar cannot do at once
|
|
|
|
Stock Plasma 6.3 ties them together, and this is the trade the classroom
|
|
makes. Both halves are measured, not inferred:
|
|
|
|
main.qml:153 hideActivatedLaunchers: tasks.iconsOnly || ...
|
|
main.qml:155 launchInPlace: tasks.iconsOnly && sortingStrategy === 1
|
|
MouseHandler.qml:74 accepts a reordering drop only when
|
|
sortMode === SortManual
|
|
|
|
For an icons-only bar the launcher is ALWAYS hidden once its application
|
|
starts. Only `sortingStrategy = 1` puts the running window back in the
|
|
launcher's place — and 1 is also the only value at which a drag can
|
|
reorder anything.
|
|
|
|
* `sortingStrategy = 0` — no dragging, but the browser jumps behind the
|
|
disc player when it opens. That was 0.2.4, and it is the bug.
|
|
* `sortingStrategy = 1` — the order holds through every open and close,
|
|
and a teacher who knows to drag can rearrange the bar within a
|
|
session. This is what ships.
|
|
|
|
There is no third value and no Kiosk key that separates them.
|
|
`classroom-desktop-reset` rebuilds the bar from the package at every
|
|
login, so a drag never outlives the session.
|
|
|
|
- [ ] KNOWN: a drag can still rearrange the bar until the next login
|
|
- [ ] After logging out and back in, the packaged order is back
|
|
|
|
### The configuration escape (unresolved)
|
|
|
|
Right-clicking a launcher offers **Configure Icons-Only Task Manager…**,
|
|
and that dialog opens and reaches the sorting setting. Measured on the
|
|
lab session with the desktop locked: `plasma/plasmashell/unlockedDesktop`
|
|
reads false, `evaluateScript` answers "Widgets are locked", Pin and Unpin
|
|
are correctly hidden — and Configure is not gated by any of it. There is
|
|
no `allow_configure_when_locked` key in Plasma 6.3; it was searched for
|
|
in the shipped libraries and does not exist.
|
|
|
|
Closing it means overriding stock `ContextMenu.qml`, which is a fork of a
|
|
file that changes between Plasma releases. Not done.
|
|
|
|
- [ ] KNOWN: a teacher who opens that dialog can change the sorting, and
|
|
the next login puts it back
|
|
- [ ] The bar is right at 1080p/100% and 4K/200%
|
|
|
|
## The Bible study laptop
|
|
|
|
A laptop installed as a fixed appliance: AC power, battery out, lid shut,
|
|
one television on HDMI, Wi-Fi.
|
|
|
|
```
|
|
DEVICE_TYPE=laptop
|
|
DISPLAY_MODE=external-only
|
|
NETWORK_PREFERENCE=wifi
|
|
WONDERINK_ENABLED=false
|
|
PARENT_CALL_ENABLED=false
|
|
DVD_ENABLED=false
|
|
```
|
|
|
|
Nothing about `DEVICE_TYPE=laptop` turns those applications off; they are
|
|
off because those lines say so.
|
|
|
|
### Physical verification — a real lid and a real television
|
|
|
|
The lab has no lid and no HDMI hotplug, so none of this is proven by a
|
|
passing build. Do it once at the machine:
|
|
|
|
1. With the lid **open** and the television on, check
|
|
`classroom-display-mode` reports the panel switched off and the
|
|
television on, and that only the television is lit.
|
|
2. Close the lid. The machine must keep running: the television stays on,
|
|
audio keeps playing, SSH stays up. `systemctl is-system-running`
|
|
still answers, and `loginctl` shows the session active.
|
|
3. Leave it closed for ten minutes. It must not suspend, hibernate, log
|
|
out or lock. `journalctl -b | grep -i -E "suspend|hibernate|lid"`
|
|
should show nothing acting.
|
|
4. With the lid still closed, switch the television **off** and on again.
|
|
The picture must come back. **Known limitation of 0.2.4:** the display
|
|
mode is applied at login, not continuously, so if KWin re-enables the
|
|
internal panel on that power cycle it stays enabled until the next
|
|
login. Check whether it does, and report it — that decides whether the
|
|
follow-up needs an event-driven applier like the audio policy's.
|
|
5. Unplug and replug HDMI, lid closed. Same check.
|
|
6. Reboot with the lid closed and the television on. It must come back to
|
|
the classroom desktop on the television.
|
|
7. Confirm Wi-Fi reconnects on its own, with nobody typing a password.
|
|
8. Confirm the HDMI audio policy still works (see Audio, above).
|
|
|
|
## Messaging
|
|
|
|
- [ ] With `MQTT_ENABLED=false`, `journalctl -u ekklesia-classroom-mqtt`
|
|
shows one line and the service is inactive — and the room is
|
|
completely normal
|
|
- [ ] With a broker configured, the service connects and
|
|
`mosquitto_sub -t 'classroom/status/#' -v` shows the room online
|
|
- [ ] A published notification appears on the classroom screen in the
|
|
classroom styling
|
|
- [ ] `urgency: critical` renders in the critical style
|
|
- [ ] Killing the broker leaves the room entirely usable
|
|
- [ ] The service reconnects on its own when the broker returns
|
|
- [ ] Rebooting with the broker **down** boots normally to the dock
|
|
- [ ] A retained notification left on the broker does not appear at boot
|
|
|
|
## DVD
|
|
|
|
With `DVD_ENABLED=false`:
|
|
|
|
- [ ] No DVD button in the dock
|
|
|
|
With `DVD_ENABLED=true`:
|
|
|
|
- [ ] Drive unplugged: button present, icon held back, friendly notification on click
|
|
- [ ] Drive present, no disc: friendly notification on click, nothing crashes
|
|
- [ ] Inserting a disc produces one **DVD Ready** notification
|
|
- [ ] The DVD icon comes up to full strength while a disc is in
|
|
- [ ] Nothing plays until the button is pressed
|
|
- [ ] Clicking plays the disc
|
|
- [ ] Menus work
|
|
- [ ] Audio works
|
|
- [ ] Chapter navigation works
|
|
- [ ] Fullscreen works
|
|
- [ ] `Super+M` minimises the player, the DVD button restores it
|
|
- [ ] Closing the player works
|
|
- [ ] Ejecting is detected, the icon goes back
|
|
- [ ] Reinserting is detected again
|
|
- [ ] Commercial CSS disc plays without anyone having run codec setup
|
|
by hand
|
|
|
|
## Sanctuary LIVE capability
|
|
|
|
With `LIVE_ENABLED=false`:
|
|
|
|
- [ ] No LIVE button or spacing hole appears in the dock
|
|
- [ ] No live-specific service or process starts
|
|
|
|
With `LIVE_ENABLED=true`:
|
|
|
|
- [ ] LIVE appears after DVD when DVD is enabled, and after Browser otherwise
|
|
- [ ] Clicking it shows the existing placeholder notification
|
|
- [ ] No live playback is attempted
|
|
|
|
### DVD mode
|
|
|
|
- [ ] Pressing DVD covers the **whole** display immediately, dock and
|
|
clock included — no wallpaper visible anywhere, at any point
|
|
- [ ] A spinner and "Loading DVD…" show while the disc spins up
|
|
- [ ] No partial VLC window is ever visible against the wallpaper
|
|
- [ ] The loading surface stays up until the disc menu is actually
|
|
showing — VLC's tiled black startup window is never visible
|
|
- [ ] Video or the disc menu replaces the loading surface when ready
|
|
- [ ] A disc that never opens still gives the desktop back (20s)
|
|
- [ ] No VLC chrome anywhere: no menu bar, no fullscreen controller,
|
|
no cone, no sway title bar
|
|
- [ ] Wallpaper is never visible around VLC
|
|
- [ ] Moving the mouse to the bottom slides the classroom bar up
|
|
- [ ] It hides again shortly after the mouse leaves it
|
|
- [ ] While hidden, clicking a disc menu item near the bottom still
|
|
reaches the menu
|
|
- [ ] Play/pause toggles and the icon follows the actual state
|
|
- [ ] Previous and next chapter work
|
|
- [ ] The menu button returns to the disc menu
|
|
- [ ] Space pauses; arrow keys and Enter navigate the disc menu
|
|
- [ ] Arrow keys do **not** change volume, and no key reaches crop,
|
|
aspect ratio, subtitles, audio tracks or deinterlacing
|
|
- [ ] Esc leaves DVD mode cleanly, with no black window left behind
|
|
- [ ] Close leaves DVD mode cleanly
|
|
- [ ] Eject leaves DVD mode and opens the tray
|
|
- [ ] Killing VLC by hand also returns to the classroom desktop
|
|
- [ ] Pressing DVD twice quickly does not start two sessions
|
|
- [ ] The bar is sized by UI_SCALE like the dock
|
|
|
|
## OTA
|
|
|
|
- [ ] `./update_canary.sh` publishes package first, manifest last
|
|
- [ ] The endpoint on the canary channel picks the update up
|
|
- [ ] SHA-256 verification passes
|
|
- [ ] Install succeeds and the endpoint reboots
|
|
- [ ] Everything above still works after the update
|
|
- [ ] Upgrade from 0.1.36 preserves every existing `device.conf` value
|
|
- [ ] `LIVE_ENABLED=false` is appended exactly once on upgrade and remains
|
|
single after reinstall
|
|
- [ ] `tools/validate-trixie-release.sh` passes against the 0.1.37 package and
|
|
the 0.1.36 package
|