# Browser Session and Terminal Selector Tests Run from the repository root: ```sh python3 tests/web_ui_session/run.py ``` Requires a host C compiler, Python 3, and Node with Fetch/Response/ReadableStream support (Node 18+). All compiler outputs and rendered scripts are temporary; no firmware build, generated assets, or device writes are performed. The runner compiles production `src/web_ui.c` with HTTPD and vendored-asset data doubles. It reuses the HTTPD stub text from `tests/web_login_ui/run.py`, without importing/executing that runner. Node executes the actual C-rendered application and inline asset-failure script, not a separately maintained implementation. Coverage: - Resource selection, NULL/invalid input, setter/send failure propagation, eight-header ceiling, no-store document/application, unchanged vendor caching, nosniff/no-referrer/frame denial, exact inline-loader CSP hash and login fallback. - Session validation before initial/retried/restored connections; memory-only CSRF header and empty ticket/logout bodies; safe-text username/absolute expiry. - 401 shutdown and navigation once; manual recovery on 403; bounded Retry-After display/backoff for capacity; network errors never assert successful logout. - Confirmed 204 logout, lost response confirmed by session 401, uncertain logout, cancellation, explicit recovery, and stale session/ticket/status/logout/WS work. - Pagehide/bfcache restoration, late response bodies, and superseded session checks. - Existing writer controls, 1,024-byte binary input chunks, raw binary output, observer input gating, and explicit Disconnect pausing reconnect. - Authentication/ticket response cap 512 bytes, existing status cap 3,072 bytes, 15-second request deadline, single status request in flight, bounded retry delay, and unchanged 5,000-line terminal scrollback. - Admin-only navigation, explicit protected-ticket open, 20 switches preserving serial socket/client/writer IDs, separate output and selected-only input. - Independent 64 KiB pending output limits, visible dropped-byte counters and resumed hidden output draining; 512-byte admin input frames and overflow close. - Admin close/reopen/remote exit isolation, 401/logout/expiry/pagehide cancellation, late tickets/callbacks, handshake timeout, selected resize and three listener cleanup/restore cycles. - Session identity changes (username, role or session-stable CSRF) force a clean document before view adoption, close old admin and prevent replacement-session logout; same-session restore retains both scrollbacks behind validation gating. - Undefined initial dimensions recover at unchanged bounds; failed fits never populate the cache, readiness retries stop at three, and teardown fences stale callbacks even after restore. Sixteen Node groups total. ## Integration and known gaps This covers the Phase 8D.3 browser session behavior and 8D.6 selector. The renderer still relies on its caller to authenticate resources; protected asset failures must be 401, never a redirect to HTML served as JavaScript. No Basic fallback is implemented here. Existing 8D.5 server authorization/protocols are unchanged. These tests model DOM, timers, fetch cancellation and WebSocket events. They do not prove real-browser CSP enforcement, script-loading errors, TLS/HTTPD behavior, actual bfcache policy, cookie expiry, server revocation, or hardware serial byte integrity, actual xterm escape parsing, hidden prompts, or desktop/mobile layout. The 8D.6 firmware build and pending target checklist are recorded separately in `docs/phase8d6_implementation.md`. No target resource reserve is claimed. Browser secret references are dropped and never persisted/logged, but JavaScript cannot securely wipe engine-managed strings.