Files

113 lines
6.6 KiB
Markdown

# Speech queue verification
Ordinary output always appends. Cancellation belongs to configured interruption keys,
reader command dispatch and explicit stop requests. An announcement arriving
later from the same action must let earlier speech finish. This includes focus,
selection, state, notification and delayed review output. Accepted Tentacle
speech follows the same rule when its originating focus/session retires;
admission still rejects stale replies and Braille retains its own ownership.
External `SpeakText` announcements also queue regardless of their interrupt
flag; `CancelSpeech` remains an explicit stop request.
Run:
```sh
go test ./internal/app ./internal/input ./internal/speech -count=1
python3 tests/check_speech.py
go build -o /tmp/cthulhu-radio-sound ./cmd/cthulhu
CTHULHU_BINARY=/tmp/cthulhu-radio-sound CTHULHU_PREFS_RADIO_RUNTIME_ONLY=1 /usr/bin/python3 tests/native_preferences.py
```
The required radio-selection test sends Laptop focus and checked-state events
through the event loop and speech worker, with a controlled backend that fails
on an unexpected cancellation. Existing tests cover the cancellation barrier,
Say All, key echo voice ordering, initiating-key timestamps, title repeats,
screen lock, internal UI and Tentacle output. These checks establish software
ordering, without proving audible completion or physical input on a Pi.
The private GTK radio test drives Right/Left between Desktop and Laptop. It
requires one selected sound per move, with the label retained. It uses private
Xvfb, D-Bus and a fake speech server; GStreamer auto audio is restricted to the
fake audio sink in the child reader. It never uses the desktop speech server or
audio devices. Debug sound records identify playback attempts, not audible
output. GStreamer's Python bindings and `fakeaudiosink` are required.
Unchecked radio focus sounds wait up to 250 milliseconds for a following
checked event. That event replaces the pending sound immediately. Speech and
Braille remain immediate, and a radio that stays unchecked gets its original
unchecked cue. Fresh input, changed focus/window, lock and handoff retire the
pending cue. Native state-only snapshots retain the owned mnemonic so a
repeated focus event does not replay the selected sound and label.
Before submission, review the diff and rebuild the reader. Restart the active
reader only with the user's authorization. Then listen on the target desktop
and Pi:
1. In keyboard preferences, change Desktop to Laptop, release the key and wait.
Laptop should finish, followed by the role/state announcements. Repeat in
the other direction and test radio buttons, checkboxes and combo boxes.
2. With All keys interrupt selected, during a long announcement, press Control.
Repeat with typing, an arrow,
Tab and a reader command. Old speech and its queued feedback should stop;
the new action should speak normally. Releasing keys should leave speech
alone. Test rapid presses and held arrows, including automatic titles.
3. Leave a long announcement playing while a notification or terminal output
arrives. Both should finish in order. Repeat during Say All, then stop it
with a fresh key and check that the reading position has stopped advancing.
4. With a custom echo voice, press Right in an entry. The key name should finish
before the caret character. A new key should still stop stale feedback.
5. Exercise browser navigation, Where Am I, action/list dialogs and preferences
Apply. Check that each fresh command responds promptly and delayed results
preserve announcements from the same action. Check Braille focus/state and
confirmation restoration separately.
Screen lock still clears speech for privacy. Disabling speech, replacing its
configuration/backend and shutdown retain their existing behavior. Protected
Tentacle messages retain their explicit timeout and cancellation rules. The
bounded queue can discard pending requests on overflow and logs that loss.
## Interruption preferences
Build a separate binary and exercise the recorder on a private display:
```sh
go build -o /tmp/cthulhu-interruption-test ./cmd/cthulhu
CTHULHU_BINARY=/tmp/cthulhu-interruption-test CTHULHU_PREFS_INTERRUPTION_ONLY=1 /usr/bin/python3 tests/native_preferences.py
CTHULHU_BINARY=/tmp/cthulhu-interruption-test CTHULHU_PREFS_INTERRUPTION_RUNTIME_ONLY=1 /usr/bin/python3 tests/native_preferences.py
```
This checks all three choices, Tab and Shift+Tab around the new controls,
recording Tab/Enter/Space/Escape and separate modifiers, duplicate suppression,
Control+Enter finish, Control+Escape cancellation, replacement, empty-recording
rejection, Apply and reloading the accepted draft. Direct XTest modifier input
avoids extra Control presses synthesized by xdotool. Config tests separately
check disk persistence and application profiles. Application tests apply the
preference to the live settings and check that unselected keys preserve both
queued speech and Say All, while selected keys and reader commands cancel them.
The runtime check starts a private reader and fake speech server. It verifies
that the read-only summary's contents are spoken on focus and characters are
spoken while moving with Left and Right. The generic native text-label test
also covers read-only entries and keeps password contents excluded.
After reviewing the diff and authorizing a reader replacement, verify audibly:
1. Select All keys interrupt and Apply. During long speech, press a letter,
Tab, an arrow, Shift and Control separately; each should stop old speech.
2. Select Control, Enter, Space, and Escape and Apply. Letters, arrows, Tab and
Shift should let speech continue. Both Control keys, both Enter keys, Space
and Escape should stop it. Repeat during Say All.
3. Select Define interruption keys. Record Tab, Enter, Escape and Right Control,
finishing with Control+Enter. Confirm Left Control was not added. Check the
result field, Apply, close, reopen and confirm the list persists. Test each
chosen key during long speech and confirm unchosen keys let it continue.
4. Record a different list and cancel with Control+Escape; the previous list
should remain. Cancel the whole Preferences window and confirm unapplied
changes do not alter runtime behavior.
5. Tab and Shift+Tab through the interruption group, recorder button, defined
keys and speech history. Check spoken instructions and Braille in recording,
normal typing/key echo, browser navigation, reader commands, automatic title
repeats, and selected/unselected held keys after applying each mode.
The private checks do not establish live speech, physical keyboard, physical
Braille or Wayland compositor acceptance.