6.1 KiB
6.1 KiB
Real-device acceptance test
These are required manual checks, not a claim that physical devices have been tested. Use a trusted HTTPS origin, two separate browser profiles/devices on one LAN, and the Rust service with a fresh database.
Setup and access
- Open
/loginin a clean profile. Confirm all labels render in English. Switch to Russian and Spanish, refresh, and confirm the choice persists and the login card fits. - Try a wrong setup token and a weak password. Confirm rejection. Create the owner using the local setup token and a 12+ character password containing letters and digits. Try setup again: it must be closed.
- Add two viewer accounts. Try a duplicate username with different casing: rejected. Sign in as a viewer; direct navigation and direct API calls to account management must be rejected.
- Try incorrect credentials 11 times within one minute from the same IP: the login endpoint returns 429. Wait a minute; valid login works.
Capture and source switching
- On
/host, no camera should activate before user interaction. Enable preview; accept permission. A local video appears, but another viewer remains waiting until Go live. - Deny permission in another profile. Confirm an actionable translated error and no false Live status. Open a LAN HTTP URL: confirm the secure-context error rather than a broken capture attempt.
- Grant camera access and inspect front/back controls on a dual-camera phone. Select back camera, then front. Confirm the correct lens, front preview mirroring only, and no duplicate media tracks. With one camera, unavailable back camera stays disabled.
- Start broadcasting. Join in a separate viewer session via the QR code. Confirm moving video and the host's viewer count. Compare host and viewer clocks/frame motion for LAN latency.
- While live, switch front → back → screen → front. Select a screen/window in the browser prompt. Confirm the existing viewer updates without signing in again. On platforms unable to open both lenses concurrently, note the error; stop preview and retry the other lens.
- Cancel the screen picker: the previous source must continue. Click the browser’s Stop sharing control: hosting stops, camera indicator turns off, and viewer shows waiting.
- Switch bitrate between low/adaptive/high. Inspect browser WebRTC stats: max bitrate changes (actual resolution depends on capture and congestion).
- Stop hosting, navigate to settings, close the tab, and log out separately. Each must stop the host camera and close outgoing peer streams.
Keep the host screen awake
- In Settings, enable Do not turn off the host. Refresh and confirm it remains enabled. Check the label and hint in English, Russian, and Spanish, including keyboard/Space operation of the switch.
- Open the host screen: preview alone must not acquire a lock. Go live over HTTPS with the setting enabled: the status should confirm the screen stays on. Leave the device untouched beyond its normal auto-lock timeout and confirm the screen and stream remain active. Repeat on a phone and computer.
- Toggle the setting off/on directly on the host screen without interrupting video. Stop hosting, navigate away, and sign out separately: the screen lock must be released. The viewer page must never request a lock.
- Background Webka, then return while still hosting: the wake lock should be acquired again if the platform allows it. Manually locking the device may suspend video; the setting does not bypass that.
- Test an unsupported browser, insecure HTTP, denied screen-wake-lock policy, and a battery-saving mode where available. Confirm a translated unavailable/unsupported message and no false active status. If denied, remove the restriction and use the retry button. No automatic retry loop or scrolling should occur.
Viewer lifecycle and session revocation
- Join before the host is live; automatic playback should start once the host starts. Check fullscreen, language switching while fullscreen, quality/resolution, and disconnect.
- Join from two viewers and revoke one session. Within two seconds its signaling closes; the host removes that peer and the revoked viewer returns to login. Other viewers continue normally.
- Reset a viewer password; all its sessions stop and old credentials fail. Delete that viewer account and confirm subsequent login is denied.
- Reset the administrator password while streaming. All its sessions are logged out and viewers stop receiving media.
- Interrupt Wi-Fi briefly. Confirm reconnect state and bounded exponential retry. Restore connectivity; playback should recover. Reload/stop/start the host and confirm waiting viewers recover.
- Attempt a second host tab with the same or another administrator session: it must show a conflict, not replace the active broadcast.
- Leave a session hidden/inactive for 30 minutes and reopen it; it must return to login. Absolute expiry after 12 hours applies even with heartbeats (also covered by automated backend tests).
Visual, accessibility, and LAN checks
- Check all five routes at 390px and 1440px widths, portrait/landscape, and 200% text enlargement. No clipped dialogs or unreachable controls; the account table may scroll horizontally.
- Check keyboard-only navigation, skip link, focus indicators, native dialog focus containment/Escape/return focus, language dropdown, and form error announcements.
- Check dark/light modes and all four accents. Enable OS reduced motion: highlights and morph/ripple animations stop.
- Scroll account rows to observe compact navigation. Check notches and fullscreen bottom safe areas.
- Scan the QR on a second device; its URL must match the configured HTTPS origin. Test
webka.localwith mDNS on/off and the documented local DNS/IP fallback. - Inspect browser network traffic: assets, API and WebSocket stay at the configured origin; media connects only between LAN peers. There should be no public STUN/TURN, external image/font, telemetry, or cloud requests.
- Confirm behavior on desktop Chromium/Firefox/Safari, Android Chrome, and iOS Safari where available. Record unsupported screen share, background suspension, camera switching, and client-isolation limits.