Files
cinny/LOTUS_TESTING.md
T
2026-06-25 04:04:21 -04:00

11 KiB
Raw Blame History

Lotus Chat — Manual Testing Guide

Generated: June 2026 Scope: Everything landed on the lotus branch since the v4.12.3 merge that I (Claude) could not verify statically and that needs a human in a real environment to confirm. Work through it top-to-bottom; the highest-risk / hardest-to-reproduce items are first.

How to report back: For each numbered check, tell me PASS / FAIL (or partial). On any FAIL, include: what you saw vs. expected, the browser/OS (and whether web LXC 106 or the desktop/Tauri build), the theme you were on, and any browser console errors (F12 → Console). Screenshots help for anything visual.

Environment notes

  • You push from your own machine; these commits are local on lotus until you do.
  • Test the web build (LXC 106 / code.lotusguild.org) first; re-run the call + poll sections on the desktop (Tauri) build too, since CSP and the EC iframe behave differently there.
  • Several call features need a second participant (second account on another device/browser, or a colleague). Items that need this are marked 👥 2 people.
  • A couple of call items need a third room/call in parallel — marked 👥👥.

Commits covered

Commit Area
caf6318a Poll vote buttons → folds tokens (N4)
c67aed01 In-call incoming-call banner (#4b)
4a875884 Selectable ringtone (#4a)
0394fce9 EC iframe load watchdog + recovery UI; avatar decorations on call tiles (#3)
d2946c00 Upload retry/backoff, presence-on-unload, typed m.direct
b7e1f89c Timeline/composer/emoji perf memoization
c0f98672 Upstream Element Call 0.20.1 merge (regression sweep)

A. Calls — new ringtone + notification work (highest priority)

A1. Ringtone selection — preview in Settings

Steps

  1. Open Settings → General, scroll to the Calls section.
  2. Find the new Ringtone dropdown (just above Ringtone Volume).
  3. Select each option in turn: Classic, Chime, Soft, Retro, Silent.

Expected

  • Selecting Classic plays the existing call.ogg clip (cut off after a few seconds).
  • Chime / Soft / Retro each play a short, distinct synthesized preview.
  • Silent plays nothing.
  • Changing Ringtone Volume then re-selecting a ringtone previews at the new volume.
  • No console errors.

⚠️ Known browser limitation: the synthesized tones use WebAudio. If a preview is ever silent, click anywhere on the page once (a "user gesture") and retry — browsers suspend audio until the page has been interacted with. The Settings preview is after a click so it should always sound; this note matters more for A3.

A2. Ringtone selection persists

  1. Set Ringtone to Retro, reload the app.
  2. Expected: the dropdown still shows Retro (setting persisted).
  3. Bonus: in devtools, set localStorage.settings to a bogus ringtoneId and reload → it should fall back to Classic, not break.

A3. Incoming call uses the selected ringtone — 👥 2 people

Setup: Account A (you) and Account B in a DM or a private (invite-only) group room.

  1. As A, pick a non-silent ringtone (e.g. Chime).
  2. From B, start a call in that DM/room. Do not answer on A.

Expected on A

  • The full-screen Incoming Call dialog appears (caller name, room avatar, Answer / Reject).
  • The selected ringtone loops until you answer/reject/ignore (at the set volume).
  • Answer → joins the call. Reject (DM) / Ignore (group) → dialog dismisses and ring stops.
  • Set ringtone to Silent and repeat → dialog still appears, no sound.

A4. In-call banner for a second incoming call — 👥👥 (the trickiest one)

Setup: You (A) already in a call in Room 1. Account B can call you in a different Room 2 (a DM or private group you share). Ideally a third account C, or B leaves Room 1's call first.

  1. While A is actively in Room 1's call, trigger an incoming call to A from Room 2.

Expected on A

  • No full-screen takeover. Instead a compact banner appears in the top-right corner with the caller's avatar, room name, "Incoming voice/video call", and Answer / Reject (or Ignore) buttons.
  • It plays a single soft ping, not a looping ring (so it doesn't talk over your active call).
  • The banner does not cover your active call's controls/PiP in a way that blocks them.
  • Answer → switches you into Room 2's call. Reject/Ignore → banner disappears.
  • The banner auto-dismisses if the caller hangs up / the call times out.

Also verify the no-op case: while in Room 1's call, if a notification for Room 1 itself arrives, nothing should pop up (no banner, no dialog).

A5. Camera focus during screenshare (#1) — 👥 2 people

Setup: You (A) and B in a call; B (or another participant) sharing their screen, and at least one person with camera on.

  1. As A, open the participant glance (the stacked avatars / member list for the call) and click a participant who has their camera on.
  2. In the menu, click "Focus camera".

Expected

  • The view switches to spotlight and pins that person's camera tile, overriding the auto-spotlighted screenshare.
  • It stays on that camera (doesn't immediately snap back to the screenshare).
  • If you pick someone with their camera off, it should at worst just toggle spotlight (graceful fallback), not error.

A6. Avatar decorations on call tiles (#3) — 👥 2 people

Setup: A participant in the call has an avatar decoration set (Settings → Profile decoration).

  1. Join a call with that participant.
  2. Look at our participant roster / prescreen tiles (not the avatars rendered inside the Element Call video grid — those are EC's and out of scope).

Expected: the decoration ring/overlay renders around that participant's avatar on the call tile, the same way it does in member lists.

A7. EC iframe load watchdog + recovery UI (#EC)

This guards against a permanently-stuck "Loading…" call.

  1. Normal case: join a call → it should connect within a few seconds as usual (the watchdog stays invisible).
  2. Failure case (best-effort to reproduce): throttle your network hard (devtools → Network → Offline) right as you click join, or block the Element Call origin, so the iframe can't finish loading.

Expected

  • On a genuine failure/timeout (~25s), instead of an endless spinner you get a visible error overlay with Retry / Leave buttons.
  • Retry attempts to reload the call; Leave exits cleanly.
  • Normal joins must not trigger the error overlay (no false positives) — this is the important part to confirm.

B. Polls (N4) — render correctly on non-TDS themes

This was the actual bug: poll buttons used undefined CSS variables, so on the default (non-Lotus-Terminal) themes they rendered with invisible borders / no selected state.

B1. Poll renders on a default theme

  1. Switch to a default Cinny theme (Settings → Appearance — not Lotus Terminal / TDS). Test both a dark and a light theme.
  2. In any room, create a poll (composer → poll button): a single-choice poll with 3 options.

Expected

  • Each option is a clearly bordered button with visible rounded corners.
  • A radio circle indicator is visible on the left of each option.
  • Text, and (after votes) the percentage, are legible.

B2. Voting + selected/progress state

  1. Vote on an option. Expected
  • The selected option shows a filled accent border + filled radio, and an accent progress-bar fill grows behind it proportional to the vote %.
  • The percentage and total vote count update.
  • Click again / pick another option → selection moves correctly (single-choice replaces; the bar redraws).

B3. Multiple-choice poll

  1. Create a poll allowing multiple selections. Expected
  • Indicators are square checkboxes (not circles); selected ones show a that's legible against the filled box.
  • You can select several options; each shows its own progress fill.

B4. Lotus Terminal theme regression

  1. Switch to Lotus Terminal / TDS theme and re-open a poll. Expected: still looks correct (the fix uses theme tokens, so the TDS accent should now drive it) — no worse than before.

C. Robustness / background behavior

C2. Presence updates on tab close

  1. Open the app, then close the tab (or quit the browser).
  2. From another session/device, check your presence shortly after. Expected: you go offline/away reliably (the unload now uses fetch({keepalive})). Previously this could be missed.

C3. Upload retry on flaky network (best-effort)

  1. In devtools → Network, set a throttle that drops/slows requests, or toggle Offline briefly during a file upload. Expected
  • A transient failure retries (up to 3×, with backoff) and the upload can still succeed once the network recovers.
  • A genuine, permanent rejection (e.g. file too large / 4xx) still fails fast with the usual error — it should not spin retrying.

C4. General timeline/composer perf (no functional regression)

The memoization changes are invisible if correct. Just confirm nothing broke:

  • Open a busy room; scrolling, jump-to-latest, mark-as-read all still work.
  • Composer: send a message, upload a file, share a location, pick an emoji and a sticker — all still work.

D. Element Call 0.20.1 merge — regression sweep (👥 2 people)

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.


Priority if you're short on time

  1. A4 (in-call banner) + A3 (ringtone) — newest, most logic, hardest to reproduce.
  2. B1B3 (polls on a default theme) — the confirmed visual bug.
  3. D (EC 0.20.1 control sweep) — guards against the upstream merge breaking calls.
  4. A7 false-positive check (normal joins don't show the error overlay).
  5. Everything else.