Setup Screen
SS-02
Smart fill — pickup first
Pickup empty → tap Recent → should fill pickup, not dest
SS-03
Smart fill — skip to dest
Pickup pre-filled → tap Recent → should fill destination only
Unsafe Drop-Off
UD-01
Button locked at 50% progress
Ferry Bldg → Dolores Park @ 50%. Button must be grey + non-tappable
UD-02
Button unlocks at 76% progress
Same route @ 76%. Button must be full-opacity and tappable
UD-03
Overpass returns safe places
Ferry Bldg → Mission District @ 80%. Open Unsafe Drop-Off → expect police + pharmacy cards
UD-04
Nominatim fallback (sparse area)
Car moved to ocean coords. Overpass likely empty → Nominatim fallback fires
Re-Route
RR-01
Autocomplete fires on typing
Ferry Bldg → Dolores @ 40%. Opens reroute, types "Union Square", waits up to 4s for Nominatim suggestions. Pass = list visible with ≥1 result
RR-02
Select suggestion → route updates
Types "Castro District", auto-clicks first Nominatim result, checks overlay closes + destination updates. Requires network.
I'm in Danger
ID-01
Overlay + 5s countdown bar
Downtown → Castro @ 30%. Danger triggered. Watch bar shrink over exactly 5s
ID-02
Cancel within 5s — full abort
Danger triggered → auto-cancelled at 2s. Overlay gone; ride resumes; no extra API calls
ID-07/08
Full flow → dest updates to police
Downtown → Mission @ 45%. Let sequence run fully. Bottom sheet should show police station. Loading should NOT flash twice
ID-09
Banner Cancel → I'm Safe only
Simulates post-reroute state. Emergency banner visible. Tap Cancel on banner → agent overlay reopens with ONLY I'm Safe button
Return to Car
RC-01/02
Unlock → lock → safe drop-off prompt
Boots to arrived screen + door unlocked. Tap I'm in → safe drop-off prompt should appear. NO survey jump
RC-03
8s auto-survey does NOT fire
Same as RC-01/02. Lock door quickly. Even after 8s, survey must not appear
ID-03
5s window expires → cancel btn fades
Triggers danger, waits 6s. Pass = countdown btn hidden, cancel-plain shown
ID-04
Cancel Emergency Response (post-5s)
Triggers danger, waits for 5s window, then cancels. Overlay closes, ride resumes.
ID-05
Emergency banner shows police name
Full danger flow. Pass = emg-dest text contains "Police" or "Station"
ID-06
Saved destination populated before reroute
Triggers danger at 40%. Pass = _savedDestName non-empty after police route applied
RR-03
Cancel reroute → progress preserved
Opens reroute at 60%, cancels. Pass = overlay closes + progress stays ≥ 58%
Survey
SV-01
Survey auto-appears after arriving
Drives to 99%, lets anim complete. Pass = survey screen active within 10s
SV-02
Survey renders 5 star options
Opens survey directly. Pass = 5 star labels visible
SV-03
Star click → enables submit
Opens survey, clicks star 4. Pass = submit button enabled
SV-04
Submit survey → back to setup
Opens survey, rates 5 stars, submits. Pass = setup screen shown
Speed & Progress
SP-01
Speed buttons update animSpeed
Clicks 10×, then 1×. Pass = active class + interval changes
SP-02
Progress bar never goes backwards
Boots at 50%, manually sets _lastProgress to 0.80, calls setProgress(0.60). Pass = bar stays at 80%
SP-03
ETA chip updates correctly
Boots at 50%. Checks ETA chip shows a time string (not "--")
Edge Cases
EX-03
Offline — graceful error state
fetch() monkey-patched to fail. Unsafe Drop-Off should show empty/error state without crashing
EX-05
Phase lock regression at 74%/76%
Auto-advances from 74% (locked) to 76% (unlocked). Pass = both states correct
EX-06
Double danger trigger — no duplicate state
Triggers danger twice rapidly. Pass = only one overlay open, dangerActive stays true
EX-07
Reset app clears danger state
Triggers danger, then resets. Pass = dangerActive false, banner hidden