[QA] §D Element Call control-bar regression sweep (PTT, AFK auto-mute, denoise, screenshare audio, PiP badges) #173

Closed
opened 2026-09-17 23:24:06 -04:00 by jared · 2 comments
Owner

Migrated from LOTUS_TESTING.md §D on 2026-09-17 — the file is now reference-only.

How to report: tick each item as it passes; on FAIL comment with what you saw vs expected, browser/OS, web (chat.lotusguild.org) vs desktop (Tauri), theme, and any browser-console errors. Screenshots for anything visual.


The upstream bump changed EC's internals and DOM selectors; our call controls drive that iframe, so sweep them. In a live call with 2 people, confirm each of our control-bar buttons works:

  • Mic mute/unmute (icon + actual audio)
  • Camera on/off
  • Deafen / Sound toggle (your deafen key too)
  • Screenshare start/stop (and the "Share your screen?" confirm)
  • Screenshare audio mute toggle
  • Fullscreen toggle
  • ⋮ More menu → Spotlight/Grid, Reactions, Settings each open the right EC panel
  • End call leaves cleanly
  • PTT (push-to-talk) if enabled: hold key = transmit, release = mute; releasing on blur works
  • AFK auto-mute if enabled: goes muted after the timeout
  • PiP (picture-in-picture) mini window: drag, resize, fullscreen button, return-to-call; the "You muted" / "All muted" badges show on the right person
  • Denoise (if ML noise suppression enabled): call audio still flows, no silence

If any control does nothing, that usually means an EC DOM selector changed — capture the console and tell me which button.


_Migrated from `LOTUS_TESTING.md` §D on 2026-09-17 — the file is now reference-only._ **How to report:** tick each item as it passes; on FAIL comment with what you saw vs expected, browser/OS, web (chat.lotusguild.org) vs desktop (Tauri), theme, and any browser-console errors. Screenshots for anything visual. --- The upstream bump changed EC's internals and DOM selectors; our call controls drive that iframe, so sweep them. In a live call with 2 people, confirm **each** of our control-bar buttons works: - [ ] **Mic** mute/unmute (icon + actual audio) - [ ] **Camera** on/off - [ ] **Deafen / Sound** toggle (your deafen key too) - [ ] **Screenshare** start/stop (and the "Share your screen?" confirm) - [ ] **Screenshare audio** mute toggle - [ ] **Fullscreen** toggle - [ ] **⋮ More** menu → **Spotlight/Grid**, **Reactions**, **Settings** each open the right EC panel - [ ] **End** call leaves cleanly - [ ] **PTT** (push-to-talk) if enabled: hold key = transmit, release = mute; releasing on blur works - [ ] **AFK auto-mute** if enabled: goes muted after the timeout - [ ] **PiP** (picture-in-picture) mini window: drag, resize, fullscreen button, return-to-call; the "You muted" / "All muted" badges show on the right person - [ ] **Denoise** (if ML noise suppression enabled): call audio still flows, no silence If any control does nothing, that usually means an EC DOM selector changed — capture the console and tell me which button. ---
jared added this to the Manual QA backlog milestone 2026-09-17 23:24:06 -04:00
jared added the area: callsqa labels 2026-09-17 23:24:06 -04:00
Author
Owner

Verified in real two-party calls on a local stack (Synapse + LiveKit 1.13.7 + voice-limit-guard + the bundled EC fork; two headless Chromiums with fake mic/camera, a 440 Hz tone as the mic)

control result
Mic mute / unmute ✓ — the other side's tile flips data-muted, io.lotus.call_state.audioEnabled follows
Deafen / undeafen deafen mutes the mic ✓; undeafen left the mic muted — fixed (9fefd149), it now restores the mic it took away (Discord semantics)
Screenshare start / stop (+ confirm dialog) ✓ — remote sees the share tile; stop clears it
Fullscreen ✓ (document.fullscreenElement set, label → Exit Fullscreen)
End ✓ — membership removed, "N Live"/"N in call" drop, lobby returns
PTT (pttMode, Space) ✓ — joins muted; hold Space → audioEnabled:true on the fork; release → false
PiP when leaving the room in-app ✓ — mini window with Return to call, fullscreen, "You muted" badge; call status bar at the bottom
speaking indicators ✓ via io.lotus.call_state (50 messages in 12 s, speaking:true while the tone plays)
Reconnect (offline 10 s) still in call afterwards, call_state consistent ✓
Logout mid-call bug, fixed (230d147e) — see #29
Ring on two devices bug, fixed (50b4e2c1) — see #161
Camera on/off, ⋮ More menu items, AFK auto-mute, denoise by ear, screenshare-audio mute not exercised (camera is disabled by default in settings; AFK needs a silent mic for minutes; audio quality needs ears)
Voice-limit / call-permission guard see #174

Reload mid-call: no auto-rejoin (#118 still open); the leftover membership is cleaned by the MSC4140 delayed leave within ~30 s, so no long-lived ghost.

both
share
pip

The stack is scripts/dev-homeserver.sh calls now, so this sweep is repeatable. Leaving open only for the unexercised rows.

## Verified in real two-party calls on a local stack (Synapse + LiveKit 1.13.7 + voice-limit-guard + the bundled EC fork; two headless Chromiums with fake mic/camera, a 440 Hz tone as the mic) | control | result | |---|---| | **Mic** mute / unmute | ✓ — the other side's tile flips `data-muted`, `io.lotus.call_state.audioEnabled` follows | | **Deafen / undeafen** | deafen mutes the mic ✓; **undeafen left the mic muted — fixed (`9fefd149`)**, it now restores the mic it took away (Discord semantics) | | **Screenshare** start / stop (+ confirm dialog) | ✓ — remote sees the share tile; stop clears it | | **Fullscreen** | ✓ (`document.fullscreenElement` set, label → Exit Fullscreen) | | **End** | ✓ — membership removed, "N Live"/"N in call" drop, lobby returns | | **PTT** (pttMode, Space) | ✓ — joins muted; hold Space → `audioEnabled:true` on the fork; release → false | | **PiP** when leaving the room in-app | ✓ — mini window with *Return to call*, fullscreen, "You muted" badge; call status bar at the bottom | | speaking indicators | ✓ via `io.lotus.call_state` (50 messages in 12 s, `speaking:true` while the tone plays) | | **Reconnect** (offline 10 s) | still in call afterwards, call_state consistent ✓ | | **Logout mid-call** | **bug, fixed (`230d147e`)** — see #29 | | **Ring on two devices** | **bug, fixed (`50b4e2c1`)** — see #161 | | Camera on/off, ⋮ More menu items, AFK auto-mute, denoise by ear, screenshare-audio mute | not exercised (camera is disabled by default in settings; AFK needs a silent mic for minutes; audio quality needs ears) | | Voice-limit / call-permission guard | see #174 | Reload mid-call: no auto-rejoin (#118 still open); the leftover membership is cleaned by the MSC4140 delayed leave within ~30 s, so no long-lived ghost. ![both](https://code.lotusguild.org/attachments/ed14a8eb-f1d5-4efa-b019-afe545de8675) ![share](https://code.lotusguild.org/attachments/49f5737a-57f4-4a76-985f-4c53b3fc043c) ![pip](https://code.lotusguild.org/attachments/80829a47-57f8-4fb9-a6b8-c3200d5c886f) The stack is `scripts/dev-homeserver.sh calls` now, so this sweep is repeatable. Leaving open only for the unexercised rows.
Author
Owner

Swept end-to-end on the local calls stack (Synapse + LiveKit + JWT service + voice-limit-guard, two headless Chromium clients with fake mic/camera/desktop-capture; ground truth taken from the SFU's ListParticipants, the fork's io.lotus.call_state stream and the RemoteTrackPublication behind each <audio> element — not just from our button labels). Web/Chromium only; desktop (Tauri) is tracked in cinny-desktop.

Row Result Evidence
Mic mute/unmute label flips, SFU shows AUDIO/MICROPHONE(muted) / unmuted
Camera on/off VIDEO/CAMERA appears/disappears on the SFU; other side's call_state.videoEnabled follows
Deafen / Sound (+ key) all remote <audio> muted=true, server-side setEnabled(false); undeafen restores; key + new on/off switch verified in the Push-to-Deafen fix
Screenshare start/stop + "Share your screen?" confirm confirm dialog shown; VIDEO/SCREEN_SHARE + AUDIO/SCREEN_SHARE_AUDIO published; stop removes them
Screenshare audio mute after fix receive-side mute of others' share audio. Bug found: when the sharer stopped and re-shared (or someone else started sharing) the audio came back at full volume while the button still said "Unmute Screenshare Audio" — EC's own volume controls reset the setVolume(0) we used. Fixed in the fork (0.25.0-lotus.4, mute now rides the renderer's muted prop like deafen) and pinned in 68ce13f0. Verified: re-published track mounts enabled=false while muted, re-enables on unmute; deafen+undeafen keeps it muted; leaving the call resets it
Fullscreen verified in the earlier call batch
⋮ More → Spotlight/Grid, Reactions, Settings EC's input[value=spotlight] becomes checked and the item flips to "Grid View"; Reactions opens the picker ("Pick reaction 👍 🎉 …"); Settings opens EC's Audio/Video/Preferences dialog
End membership gone from m.call.member state immediately
PTT toggled mid-call via Settings: mic goes muted on enable; holding Space → SFU track unmuted; release → muted; disabling PTT restores the mic. (Release-on-blur not exercised headless.)
AFK auto-mute silent fake mic, 1-minute timeout: mic muted ~60 s after join, toast "Your microphone was muted after inactivity.", SFU shows (muted)
PiP: drag / resize / fullscreen button / return / badges drag moves it (150×120 px), NW-corner resize 278×156 → 410×248, "Fullscreen camera" button present, click and double-click return to the call room, badges "Your microphone is muted (alice)" and "All other participants are muted" appear on the right conditions pip
Denoise (ML) audio flows DeepFilterNet tier: lotusDenoiseSource=true, df_bg.wasm + model fetched, other side hears the mic (RMS 0.12–0.25 with a pure-tone input) and gets speaking=true; survives an SFU restart (audio back within ~2 s). By-ear quality is a human item → new issue

Extras found along the way:

  • EC load watchdog: blocked the EC document → "The call failed to load. Check your connection and try again." + Back after 25 s ; but every DOM-driven call hook threw SecurityError reading the now-cross-origin frame — fixed in 70620d4b (getCallDocument()). watchdog
  • After an SFU restart one participant's speaking indicator stays off until they toggle their mic (audio is fine) → filed in element-call.
  • PiP is see-through over the timeline → filed (polish).

Closing; the by-ear rows live in the new human-QA issue.

Swept end-to-end on the local calls stack (Synapse + LiveKit + JWT service + voice-limit-guard, two headless Chromium clients with fake mic/camera/desktop-capture; ground truth taken from the SFU's `ListParticipants`, the fork's `io.lotus.call_state` stream and the `RemoteTrackPublication` behind each `<audio>` element — not just from our button labels). Web/Chromium only; desktop (Tauri) is tracked in cinny-desktop. | Row | Result | Evidence | |---|---|---| | Mic mute/unmute | ✅ | label flips, SFU shows `AUDIO/MICROPHONE(muted)` / unmuted | | Camera on/off | ✅ | `VIDEO/CAMERA` appears/disappears on the SFU; other side's `call_state.videoEnabled` follows | | Deafen / Sound (+ key) | ✅ | all remote `<audio>` `muted=true`, server-side `setEnabled(false)`; undeafen restores; key + new on/off switch verified in the Push-to-Deafen fix | | Screenshare start/stop + "Share your screen?" confirm | ✅ | confirm dialog shown; `VIDEO/SCREEN_SHARE` + `AUDIO/SCREEN_SHARE_AUDIO` published; stop removes them | | Screenshare **audio** mute | ✅ after fix | receive-side mute of others' share audio. **Bug found:** when the sharer stopped and re-shared (or someone else started sharing) the audio came back at full volume while the button still said "Unmute Screenshare Audio" — EC's own volume controls reset the `setVolume(0)` we used. Fixed in the fork (`0.25.0-lotus.4`, mute now rides the renderer's `muted` prop like deafen) and pinned in `68ce13f0`. Verified: re-published track mounts `enabled=false` while muted, re-enables on unmute; deafen+undeafen keeps it muted; leaving the call resets it | | Fullscreen | ✅ | verified in the earlier call batch | | ⋮ More → Spotlight/Grid, Reactions, Settings | ✅ | EC's `input[value=spotlight]` becomes checked and the item flips to "Grid View"; Reactions opens the picker ("Pick reaction 👍 🎉 …"); Settings opens EC's Audio/Video/Preferences dialog | | End | ✅ | membership gone from `m.call.member` state immediately | | PTT | ✅ | toggled **mid-call** via Settings: mic goes muted on enable; holding Space → SFU track unmuted; release → muted; disabling PTT restores the mic. (Release-on-blur not exercised headless.) | | AFK auto-mute | ✅ | silent fake mic, 1-minute timeout: mic muted ~60 s after join, toast "Your microphone was muted after inactivity.", SFU shows `(muted)` | | PiP: drag / resize / fullscreen button / return / badges | ✅ | drag moves it (150×120 px), NW-corner resize 278×156 → 410×248, "Fullscreen camera" button present, click and double-click return to the call room, badges "Your microphone is muted (alice)" and "All other participants are muted" appear on the right conditions ![pip](https://code.lotusguild.org/attachments/44de4c00-93ec-4396-8147-2bf82fa12d0c) | | Denoise (ML) | ✅ audio flows | DeepFilterNet tier: `lotusDenoiseSource=true`, `df_bg.wasm` + model fetched, other side hears the mic (RMS 0.12–0.25 with a pure-tone input) and gets `speaking=true`; survives an SFU restart (audio back within ~2 s). By-ear quality is a human item → new issue | Extras found along the way: - EC load watchdog: blocked the EC document → "The call failed to load. Check your connection and try again." + Back after 25 s ✅; but every DOM-driven call hook threw `SecurityError` reading the now-cross-origin frame — fixed in `70620d4b` (`getCallDocument()`). ![watchdog](https://code.lotusguild.org/attachments/00ae2cc3-145d-4f87-ad5e-6fadb0aee787) - After an **SFU restart** one participant's speaking indicator stays off until they toggle their mic (audio is fine) → filed in element-call. - PiP is see-through over the timeline → filed (polish). Closing; the by-ear rows live in the new human-QA issue.
jared closed this issue 2026-09-19 00:36:10 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#173