Skip to content

Mobile QA Testing Guide

Comprehensive manual testing checklist for the Sapari mobile app. Run before every major release.

Tests are organized by workflow order and grouped to avoid redundant retesting. Each section builds on previous ones — complete them in order. Sections marked with [P+L] require testing in both portrait and landscape orientations.


Prerequisites

  • Mobile browser or Chrome DevTools device emulation (iPhone 14 Pro recommended)
  • Window width < 768px (mobile breakpoint)
  • Test video file (30s+, with speech and silence)
  • Test assets: one video, one audio, one image
  • Backend running locally or connected to staging
  • For landscape testing: enable auto-rotate (or use DevTools rotation toggle)
  • For haptic testing: use a physical iOS/Android device

0. Onboarding (First-Time User)

Upload Step Tour (4 steps)

  • First login → spotlight tour on upload step
  • Step 1: Upload zone highlighted (tooltip below)
  • Step 2: Assets tab in bottom nav (tooltip above)
  • Step 3: Projects tab (tooltip above)
  • Step 4: Settings tab (tooltip above)
  • Skip/Done dismisses, doesn't show again

Configure Step Tour (8 steps, auto tab-switching)

  • First time reaching Configure → second tour starts
  • Step 1: Tab toggle (CUTS/AUDIO/ASSETS) highlighted
  • Step 2: Pacing Style (stays on Cuts tab)
  • Step 3: False Starts (stays on Cuts tab)
  • Step 4: Clean Audio (switches to Audio tab)
  • Step 5: Caption Language (stays on Audio tab)
  • Step 6: Profanity (stays on Audio tab)
  • Step 7: Asset injection (switches to Assets tab)
  • Step 8: START PROCESSING button
  • After dismiss → resets to Cuts tab
  • Touch targets work — tooltip doesn't cover key actions
  • Dark mode correct

0b. Playback Speed Control

  • Speed button beside volume (bottom-left of video)
  • Tap button to toggle vertical slider (same pattern as volume)
  • Works in both portrait and landscape
  • Button shows current speed, orange when not 1x
  • Timeline overview (Layers) button hidden when no edits

CC Toggle (Video Preview)

  • CC button visible bottom-left of video (next to speed button)
  • Tap CC → captions hidden, button dims to white
  • Tap CC again → captions shown, button turns orange
  • Toggle state syncs with export panel's captions setting
  • Works in both portrait and landscape

1. Authentication & Settings

Login

  • Enter valid email + password → redirects to project list
  • Enter invalid credentials → error message appears
  • Submit with empty fields → validation prevents submit
  • Keyboard submit works (tap Done/Go on mobile keyboard)
  • "Remember me" checkbox visible and tappable (44px target)
  • Login with "Remember me" → persistent session (~30 days)
  • Login without → standard session (~8h)
  • Login as unverified user → "Resend verification email" tappable link appears (44px target)
  • Tap "Resend verification email" → status changes to "Verification email sent. Check your inbox."
  • After ~10 fast failed login attempts → "Too many failed login attempts" message (not "Incorrect password")

Email verification

  • Open verification link from email on mobile → "Verified" success page renders
  • Tap expired link → "Invalid or expired verification link" (no false success)

Change Password (Account Settings)

  • Change password with correct current password → success message, auto-redirects to login after ~2s
  • Login with new password works
  • Wrong current password → error message
  • OAuth user → can set password without current password

Change Email (Account Settings)

  • Collapsible "Change Email" in Account tab (collapsed by default)
  • Enter new email + password → success message
  • Wrong password → error
  • Touch targets 44px on all inputs and button
  • Confirmation page at /confirm-email-change?token=... works

Change Name (Account Settings)

  • Tap name in profile → inline edit → OK saves, X cancels
  • Name updates immediately after save
  • Touch targets 44px on edit input and buttons

Delete Account (Account Settings)

  • "Delete Account" button in Account tab
  • Tap → password field + "Type DELETE" confirmation
  • Wrong password → error message
  • Correct password + DELETE → account deactivated, logged out
  • Cancel resets all fields
  • Touch targets 44px on all interactive elements

Settings Tab (4 tabs: Account / Billing / Credits / Prefs)

  • Account tab: avatar, username, email, Sign Out
  • Prefs tab: theme toggle (Light / Dark / Auto), language selector
  • Theme preference persists after page reload
  • Dark mode: all backgrounds, text, borders use dark variants
  • Sign Out → returns to login screen
  • For Billing + Credits tab tests, see Mobile Billing QA

2. Project Management

Create & List

  • Tap NEW (orange + button) → new project appears
  • Empty state shows appropriate message
  • Projects sorted newest-first
  • Project cards show: thumbnail (or letter fallback), name, status badge, date
  • After first clip processed, project card shows video frame thumbnail

Delete

  • Trash icon on each project card (right side)
  • Tap trash → inline DELETE / CANCEL confirmation (date hidden to save space)
  • Tap DELETE → project removed, card disappears
  • Tap CANCEL → confirmation dismissed, card returns to normal
  • Tapping project card while confirmation showing does nothing (no accidental navigation)

Resume

  • Tap project card → opens project in editor
  • Status badges show correctly: COMPLETE (green), PROCESSING (yellow)

3. File Upload & Import

Upload

  • Tap upload area → file picker opens
  • Select video → upload progress bar shows
  • Upload completes → file listed with checkmark
  • Upload fails → error message displayed

Clip Reorder

  • Upload 2+ clips → drag handles visible
  • Drag clip to new position → clips reorder
  • Refresh → order persists

YouTube Import

  • Paste YouTube URL → IMPORT button activates
  • Tap IMPORT → download progress shown
  • Successful import → asset appears in library
  • Invalid URL → error message

4. Analysis Settings

Silence & False Starts

  • Pacing buttons: Off / Natural / Balanced / Fast → selected button highlighted
  • False start buttons: Off / Moderate / Aggressive → selected button highlighted
  • Selecting Off disables that detection type

Audio & Captions

  • Clean Sweep toggle: on/off visually distinct
  • Caption language dropdown: selection persists

Presets

  • No presets by default -- only "Custom" shown initially
  • Save current settings as preset → appears in preset list
  • Tap saved preset → pacing, false starts, and other settings auto-apply
  • Delete preset → removed from list

Cost Estimate & Analysis Mode

  • Nothing toggled → shows "MANUAL - FREE" above START PROCESSING
  • Set only language → shows "CAPTIONS - ~X AI MIN" (0.5x)
  • Enable pacing or false starts → shows "AI EDIT - ~X AI MIN" (1.0x)
  • Hint text below cost (no tooltip on mobile)
  • Switching settings updates cost in real time

Run Analysis

  • Tap ANALYZE → processing begins
  • Progress updates shown in real-time
  • Analysis completes → transitions to review screen

Re-analyze & Run Switching

  • Back button from Review → Configure step (re-analyze flow)
  • Configure shows collapsible "Previous Analyses" dropdown when runs exist
  • Dropdown collapsed by default, chevron toggle to expand
  • Run cards with orange active state, "N cuts · M inserts" labels
  • Tap any run → navigates to Review with that run's edits
  • Tap already-active run → still navigates to Review
  • Tap inactive run → loading spinner, backend activates, edits switch
  • Touch targets min 44px on run cards
  • Dark mode: run cards styled correctly
  • Re-analyze: adjust settings, tap START PROCESSING → new run created, old preserved

5. Swipe Review — Edits Tab [P+L]

Card Swiping

Swipe review card with accept/dismiss gestures [image to be added]

  • Swipe right → card rotates clockwise, green tint → edit accepted
  • Swipe left → card rotates counter-clockwise, red tint → edit dismissed
  • Card snaps back if swipe isn't decisive enough
  • Edit counter updates (e.g., "1 / 45")
  • Status badge shows "ACCEPTED" or "DISMISSED"

Card Details

  • Edit type badge visible (SILENCE orange, FALSE_START purple, MANUAL cyan, ASSET blue, KEEP yellow)
  • Time range displayed (e.g., "00:05.250 → 00:08.100")
  • Description text shown
  • Keep cards have dashed yellow border (distinct from solid borders on other types)
  • Cards outside active keep regions show "Outside keep region" warning with EyeOff icon

Add Edit Menu

  • Portrait: +ADD button opens dropdown with "Cut here" and "Keep here" options
  • Dropdown dismisses on tap outside
  • "Cut here" creates a manual cut at current playback position
  • "Keep here" creates a keep region at current playback position
  • Landscape: inline CUT (scissors) and KEEP (check) icon buttons — no dropdown
  • Keep regions render on timeline as dashed yellow border with transparent fill
  • Keep regions dim areas outside them (dark overlay on non-keep areas)

Inline Actions

  • Accept button → activates edit
  • Dismiss button → deactivates edit
  • Trash icon on card → triggers bottom bar DELETE/CANCEL confirmation (single confirmation, not duplicated)
  • Focus button (asset edits) → opens AssetFocusMode

List View

  • Toggle list view → all edits shown as scrollable list
  • Auto-scroll highlights current edit
  • Tap list item → navigates to that edit
  • Keep edits show yellow label in list

Landscape Layout

  • Video on left, swipeable edit cards on right (same EditsPanel as portrait)
  • Video column width adapts to aspect ratio (narrow for 9:16, wider for 16:9)
  • Swipe left/right to navigate edits
  • ACCEPT / DISMISS / DELETE action bar at bottom of right panel
  • List view, focus button, and delete all work in landscape

6. Swipe Review — Format Tab [P+L]

Format Selection

Format tab with platform buttons and letterbox options [image to be added]

  • Tap Original → native aspect ratio (no letterboxing)
  • Tap 9:16 → portrait format (TikTok/Reels)
  • Tap 1:1 → square format (Instagram)
  • Tap 16:9 → landscape format (YouTube)
  • Selected format button visually highlighted

Custom Format

  • Toggle custom format input → W:H number fields appear
  • Enter valid values (1-32 range) → custom ratio applied
  • Invalid values rejected

Letterbox Background

  • Color swatches: black, white, gray, etc. → tap to select
  • Color picker → opens full color selector
  • Selected color shown as letterbox bars in video preview

Presets

  • Save current format + color as preset (max 5)
  • Load preset → restores format and color
  • Delete preset → removed from list
  • "Make default" checkbox in save dialog

Landscape Layout

  • Format buttons arranged in compact single row
  • Color swatches remain tappable

7. Swipe Review — Style Tab [P+L]

Caption Styling

Style tab with font, size, and color controls [image to be added]

  • Style buttons: Default / Minimal / Bold → preview updates
  • Position buttons: Bottom (↓) / Center (—) / Top (↑) → caption moves in preview
  • Font buttons: SAN / SER / MON → font family changes
  • Font size slider → "A...A" label, numeric value displayed
  • Words per line: Short / Medium / Long → line wrapping changes
  • Color presets: White, Yellow, Orange, etc. → text color changes
  • Color picker → custom text color
  • "MODIFIED" badge appears if any setting changed from default

Landscape Layout

  • Controls remain usable with tighter spacing

8. Swipe Review — Captions Tab [P+L]

Caption Cards

  • Swipeable caption cards (swipe left/right to navigate)
  • Time range displayed: "HH:MM:SS → HH:MM:SS"
  • Caption text shown on card

Caption Editing

  • Tap EDIT → textarea opens with current text
  • Type new text, tap Enter → saves
  • Tap Esc → cancels edit
  • "MODIFIED" badge appears on edited captions
  • "Original: ..." hint shown below modified captions
  • RESET button → reverts to original text

Caption Deletion

  • DELETE button → confirmation dialog
  • Confirm → caption removed
  • Cancel → caption stays

List View

  • Toggle list → all captions shown
  • Color-coded cut indicators (% of caption affected by cuts)
  • Navigation: PREV / NEXT buttons (disabled at boundaries)

9. Swipe Review — Video & Waveform [P+L]

Video Playback

  • Tap video → toggles play/pause
  • Video respects selected aspect ratio and letterboxing

Video Window Controls

  • Play/Pause button with icon toggle
  • Volume button (speaker icon)
  • Layers button → opens FocusMode (timeline overview)
  • Time display updates during playback

Landscape Video Sizing

  • 9:16 video → narrow left column (~25% width)
  • 1:1 video → medium left column (~35% width)
  • 16:9 video → wider left column (~45% width)
  • Video fills available height in landscape

Playback URL Refresh (Worker-Fronted Clips) [P+L]

Same retry-as-contract layer as desktop — see docs/qa/desktop/editor.md §5c for mechanism background and the TTL shortening setup. Mobile paths plumb onRequestRefresh through MobileDashboard → SwipeReview → FocusMode → VideoWindow, so refresh fires in portrait and landscape, in both SwipeReview and FocusMode layouts.

Setup (mirrors desktop §5c): SSH staging, set MEDIA_TOKEN_TTL_SECONDS=60 in .env, docker compose restart backend. Revert to 300 when done.

  • Portrait SwipeReview, play a clip, wait ~30s. Second /proxy + second /media/v1/<new-jwt> fire in Network tab. Playback continues; brief buffering overlay acceptable — sprite-tile poster when the clip has a sprite (SwipeReview and FocusMode both use <VideoWindow><ClipVideo>), otherwise "Buffering..." text. CutFocusMode/AssetFocusMode render bare <video> and still show the text overlay (follow-up).
  • Landscape SwipeReview, same test. Refresh fires; playback continues.
  • FocusMode (Layers button → enter FocusMode), same test. The FocusMode VideoWindow refreshes its URL the same way as SwipeReview's.
  • Banner in mobile layout: stop backend mid-session, wait for refresh failure. ClipPlaybackErrorBanner appears at the top of the mobile content area (above whatever tab/mode is currently rendered — Edits, Format, Style, Captions, or FocusMode).
  • Banner copy matches desktop — "Server problem..." for 5xx, "Connection issue..." for offline.
  • Tap Retry in banner: /proxy request fires. Once for each errored clip.
  • Tap Dismiss (X icon): banner hides. Session-scoped; re-shows on next distinct error.
  • Restart backend: playback recovers. Banner (if dismissed) auto-resets so next failure surfaces again.

Asset playback (out of scope until task #24). MobileAssetEditor uses presigned R2 URLs (1h TTL, not Worker-fronted) — no refresh layer wired there yet. Don't test asset-URL refresh on mobile; it's the asset-playback migration's concern.


10. FocusMode — Timeline Overview [P+L]

Entry & Exit

  • Enter via Layers button on VideoWindow
  • Full-screen overlay appears
  • Close (X) button → returns to SwipeReview

Video & Caption

FocusMode showing timeline with edit segments and waveform [image to be added]

  • Video preview at top (tap to play/pause)
  • Caption text displayed below video, updates in real-time
  • A/B toggle (ORIGINAL vs EDITED) available

Filter Bar

  • ALL → shows all edits (two-row waveform when overlapping)
  • CUTS → shows only cut/false-start edits (single row)
  • INSERTS → shows only asset edits (single row)
  • Filter buttons color-coded (orange for CUTS, blue for INSERTS)

Zoom Controls

  • + button → zoom in (hold for continuous zoom)
  • - button → zoom out (hold for continuous zoom)
  • Zoom level displayed (e.g., "4.0x")
  • Range: 1x to 16x

Timeline Waveform

  • Waveform renders with 50% opacity background
  • Edit segments rendered as colored boxes with duration labels
  • Caption markers at bottom (gray bars)
  • Playhead (orange vertical line with circle)
  • Tap on waveform → seek to that position
  • Pan/scroll through zoomed timeline

Edit Interactions

  • Drag edit body → moves edit (duration preserved)
  • Drag left handle → adjusts start time
  • Drag right handle → adjusts end time
  • Minimum duration enforced (edit stays visible)

Mini-Map

  • Appears when zoomed >1x
  • Shows full timeline with viewport rectangle
  • Drag viewport rectangle → timeline pans
  • Tap mini-map → viewport jumps to position

Bottom Bar — Navigation

  • ← Prev button → navigates to previous edit
  • Index counter (e.g., "3 / 12")
  • → Next button → navigates to next edit
  • Disabled at boundaries (first/last edit)

Bottom Bar — Actions

  • CUT button (orange) → toggles edit to "cut" state
  • KEEP button (gray) → toggles edit to "keep" state
  • Haptic feedback on state toggle
  • Undo button → reverts last edit action
  • Redo button → re-applies undone action
  • Both disabled when no actions available

Bottom Bar — Create

  • +CUT button (orange) → creates manual cut at playhead position
  • +CUT disabled when INSERTS filter active
  • +INSERT button (blue) → opens MobileAssetPicker at playhead
  • +INSERT disabled when CUTS filter active

Overlap Controls

  • MERGE/SPLIT buttons appear for asset edits overlapping inserts
  • MERGE (default) → asset plays through insert continuously
  • SPLIT → asset pauses during insert, resumes after
  • Toggle state: yellow when SPLIT, gray when MERGE

Landscape Layout

  • Compact header (small close button, badge, reset)
  • Video + caption on left column
  • Timeline + mini-map + actions on right column (full height)
  • Left column width adapts to video aspect ratio
  • All controls remain functional

11. CutFocusMode — Cut/False Start Editor [P+L]

Entry

  • Tap cut/false-start edit card in SwipeReview → opens CutFocusMode directly
  • Full-screen overlay appears

CutFocusMode with video preview, waveform, and accept/dismiss buttons [image to be added]

  • Close button (X) → returns to SwipeReview
  • Edit type badge with color (SILENCE/FALSE_START/MANUAL/KEEP)
  • Confidence percentage shown (if available)
  • Time range displayed

Video Preview

  • Video plays the edit's time range
  • Letterboxed according to selected format
  • Time overlay shows "MM:SS / MM:SS" (current / end)

WaveformStrip

  • Play/Pause button (icon toggles)
  • Loop toggle (orange when active, gray when inactive)
  • Waveform visualization with edit range highlighted
  • Orange bracket bars at edit boundaries (top and bottom)
  • Orange handles (left/right) for trimming
  • Dimmed overlay outside edit range
  • White playhead (triangle + vertical line)
  • Time labels at bottom corners
  • Tap within edit range → seek to position (haptic light)
  • Drag handles → trim edit start/end
  • Loop active → playback loops within edit, skipping the cut (simulates final video)
  • DISMISS button → deactivates edit (if active), closes
  • ACCEPT button (orange) → activates edit (if inactive), closes
  • Haptic feedback (medium) on both actions

Landscape Layout

  • Compact header (small X, badge, precise time)
  • Video on left (width adapts to aspect ratio)
  • WaveformStrip on right (full height, compact mode: 56px height)
  • Action buttons stacked vertically on right below waveform

12. AssetFocusMode — Asset Insert Editor [P+L]

Entry

  • Tap asset edit card in SwipeReview → opens AssetFocusMode directly
  • Full-screen overlay appears

Header

AssetFocusMode with overlay drag handles and control panel [image to be added]

  • Close button (X) → returns to SwipeReview
  • Asset name displayed
  • Reset button (rotate icon) → resets all changes

Video & Overlay Preview

  • Main video visible (unless replace mode)
  • Overlay/replace asset renders on top of or replacing main video
  • Letterbox background applied based on format settings

Overlay Gestures (Overlay Mode Only)

  • Drag: Touch and move overlay → repositions in real-time
  • Long-press: Hold overlay → enables snap-to-grid (grid appears, haptic medium)
  • Snap-to-grid: 3x3 dot grid + dashed lines appear, overlay snaps to nearest position
  • Pinch-resize: Two-finger pinch → scales overlay (percentage shown in badge)
  • Rotation: Tap rotation handle (circle at bottom center) → rotates +15 degrees
  • Rotation badge shows "snap 45°" (orange) or current angle (black)
  • Resize handles: Four corners with L-bracket icons (white stroke), draggable

Visual Mode Controls (Video/Image Assets)

  • FULL button → asset replaces entire frame
  • OVERLAY button → asset renders as picture-in-picture
  • INSERT button → asset spliced into timeline
  • Image assets display as static image during insert duration
  • Video assets play during insert duration
  • Playback continues seamlessly through insert regions

Overlay Settings (Overlay Mode)

  • Position grid (3x3 dots) → select overlay position
  • Opacity slider → adjusts overlay transparency (% displayed)

Audio Mode Controls

  • Video assets: ORIGINAL / MIX / REPLACE buttons
  • Audio-only assets: MIX / REPLACE buttons
  • Insert mode: mode-specific options from constants
  • Selected mode visually highlighted

Volume & Ducking

  • Volume slider visible when mix or asset-only mode selected
  • Percentage displayed above slider
  • "Duck main audio" checkbox (mix mode only)

Overlap Controls

  • MERGE/SPLIT buttons per overlapping insert (if overlaps exist)
  • Yellow highlight when SPLIT active, gray when MERGE

WaveformStrip

  • Same behavior as CutFocusMode (see section 11)
  • Play/pause, loop toggle, seek, trim handles

Controls Panel (Portrait)

  • "Hide Controls" / "Show Controls" toggle with chevron icon
  • Controls section scrollable when visible
  • Waveform always visible regardless of collapse state
  • DISMISS button → deactivates edit, closes
  • ACCEPT button (orange) → activates edit, closes
  • Haptic feedback on both

Landscape Layout

  • Compact header (asset name, reset)
  • Video + waveform on left column (width adapts to aspect ratio)
  • WaveformStrip below video (compact mode)
  • All controls on right column (scrollable, no collapse toggle needed)
  • Footer buttons at bottom of right column

13. MobileAssetPicker — Insert Flow [P+L]

Step 1: Asset Selection

Asset picker showing grouped assets by type [image to be added]

  • Search field with magnifying glass icon
  • Assets grouped by type: Video (film icon), Audio (mic icon), Image (image icon)
  • Each group shows asset count
  • Asset buttons show: thumbnail (or placeholder icon), name, duration
  • Color-coded left border: blue (video), green (audio), gray (image)
  • Tap asset → selects it, advances to Step 2

Step 2: Configure Insertion

  • Back button (chevron) + "Configure" title + insertion time displayed
  • Selected asset info: thumbnail/icon, name, duration, type
  • Visual mode buttons: FULL / OVERLAY / INSERT (video/image assets)
  • Switching visual mode resets audio defaults (replace: original/0%, overlay: mix/50%/duck, insert: mix/100%)
  • Audio mode: MIX / REPLACE (audio-only assets)
  • Insert audio controls: MIX / ASSET ONLY / MUTE toggle, volume slider, duck checkbox
  • Overlay settings: position grid, size slider, opacity slider (if overlay)
  • Volume slider (when applicable)
  • Duck checkbox (mix mode)
  • CANCEL button → closes picker
  • BACK button → returns to Step 1
  • INSERT button → creates edit at playhead, closes picker

13b. In-App Notifications [P+L]

Bell Icon (MobileWizard Header)

  • Bell icon visible at right end of MobileWizard header
  • Hidden in compact mode (landscape review)
  • Red dot when unread count > 0

Notification Panel (Compact Dropdown)

  • Tap bell opens dropdown card (max 60vh, not full-screen)
  • Tap outside closes panel
  • Panel shows all unread + last 5 read
  • "Read all" button when unread exist
  • Dark header with X close button

Swipe Gestures

  • Swipe right on unread notification → green hint → marks as read
  • Swipe left on any notification → red hint → dismisses/archives
  • Swipe hint text visible at bottom of panel
  • Swipe threshold feels natural (80px)

Real-Time

  • Analysis completes → notification appears without refresh
  • Export completes → notification appears without refresh
  • Tab title updates with unread count

Dark Mode

  • Panel colors correct in dark mode
  • Orange border, dark header, correct text contrast

14. Asset Library [P+L]

Search & Filter

  • Search input with magnifying glass → filters by name (real-time)
  • Type filter: All / Video / Audio / Image (toggle buttons)
  • Sort options: Newest, Oldest, Name A-Z, Name Z-A

Asset Groups

  • Tap group card → expands/collapses
  • Pin button → group stays at top
  • + NEW GROUP button → creates empty group
  • "Show More Groups" pagination

Group Actions (Expanded)

  • Rename: pencil icon → inline text edit
  • Delete: trash icon → confirmation dialog
  • Pin/unpin toggle

Assets Within Groups

  • Thumbnail + name + duration displayed
  • Color-coded left border: blue (video), green (audio), gray (image)
  • Settings button (sliders icon) → opens MobileBehaviorEditor
  • Rename button (pencil icon) → inline edit
  • Delete button (trash icon) → confirmation
  • "Show More Assets" pagination per group

Thumbnails

  • Video assets show frame thumbnail
  • Image assets show scaled thumbnail
  • Audio assets show icon (no thumbnail)
  • Asset picker shows thumbnails

YouTube Import

  • URL input field visible
  • IMPORT button → starts download
  • Progress indicator during import
  • Success → asset appears in group
  • Error → message displayed

15. Asset Behavior Configuration

Mode Selection

  • AUTO-INSERT button (orange bolt icon) → guides to auto-type selection
  • NO AUTO-INSERT button (gray pencil icon) → sets to manual placement

Auto Type Selection

  • FIXED POSITION button (purple pin) → opens position grid
  • AI DECIDES button (blue spark) → enables AI-directed placement

Fixed Position Grid

  • Intro / Outro / Watermark / Background Audio buttons (3-column grid)
  • Selected position visually highlighted

AI Hint

  • Optional textarea: placeholder "e.g., Insert when speaker mentions travel"

Display Options (Non-Audio Assets)

  • REPLACE / OVERLAY / INSERT buttons
  • Selected option highlighted

Overlay Settings (Overlay Mode)

  • Position grid (3x3 dots)
  • Size slider (% displayed)
  • Opacity slider (% displayed)

Audio Mode

  • Video assets: ORIGINAL / MIX / REPLACE / NONE buttons
  • Volume slider (when mix/asset_only)
  • Ducking checkbox (mix mode)

Inclusion Default

  • Always (locked) / Default (can disable) / Off (manual only)

Save

  • SAVE CHANGES button (full-width) → saves and closes sheet

15c. Vertical Crop [P+L]

CROP/BARS Toggle (FormatPanel in FORMAT tab)

  • Select non-native aspect ratio → CROP/BARS toggle appears
  • Tap CROP → video auto-fills, enters adjusting mode
  • Tap BARS → letterbox mode

Zoom + Pan

  • Zoom slider works (1x-10x)
  • Drag to pan — smooth, touch-action none prevents scroll
  • Axis locking works (mostly-horizontal locks vertical)
  • Play button hidden during adjusting

Accept

  • Tap DONE → crop locked
  • Tap ADJUST CROP → re-enters adjusting
  • Export with crop matches preview

Overlays Stay Visible Under Crop (regression for #119)

  • Crop enabled + caption_position=top → captions visible at top of cropped frame (not pushed off-screen)
  • Crop enabled + caption_position=bottom → captions visible at bottom of cropped frame
  • Crop enabled + asset insert overlay → overlay visible at its configured position, not cropped out
  • Zoom/pan doesn't scale or shift overlays (only the video moves)

16. Export [P+L]

Export History

  • Past exports listed with status badges: QUEUED (yellow), RENDERING (orange), READY (green), FAILED (red)
  • READY exports: download button (orange)
  • RENDERING exports: spinner animation
  • Delete button → inline confirmation (YES/NO)

Format Review (Read-Only)

  • Platform name displayed (YouTube, TikTok, Instagram, Original)
  • Aspect ratio shown
  • Background color swatch + hex (when non-16:9)

Caption Review (Read-Only)

  • "INCLUDED" green badge (when captions enabled)
  • Style, font, size, position, color displayed

Export Configuration

  • Export name input (optional text field)
  • Format selection: Original / YouTube / TikTok / Instagram (2-column grid)
  • Captions toggle: "Captions On" (black) / "No Captions" (gray)
  • Main Volume slider (% displayed)
  • Quality buttons: 720p / 1080p

Stats Summary

  • Duration (final video length)
  • Removed (time cut, red text)
  • Original (source duration)
  • Cuts (number applied)

Export Progress

  • Circular progress indicator (orange fill)
  • Percentage in center (e.g., "45%")
  • "Exporting..." heading
  • "This may take a few minutes" subheading

Create Export

  • "+ NEW EXPORT" button (full-width, black) → starts export
  • Export appears in history with QUEUED status

17. Rotation Hint

Appearance

  • Portrait video (9:16) viewed in portrait → hint appears: "Rotate for a better view"
  • Landscape video (16:9) viewed in landscape → hint appears: "Try portrait mode"
  • Near-square video → no hint shown

Behavior

  • Toast appears at top center with rotate icon (orange) + text + close button
  • Fade-in animation (0.3s)
  • Auto-dismisses after 4 seconds
  • Tap X → dismisses immediately
  • Dismissal persists server-side (onboarding_seen) with localStorage cache → no hint on reload or new device
  • Each orientation (portrait/landscape) tracked independently

18. Dark Mode [P+L]

Global

  • All backgrounds switch to dark variants (gray-900, gray-800, etc.)
  • All text switches to light variants (white, gray-300, etc.)
  • Borders use dark variants (gray-700, gray-600)

Component-Specific

  • SwipeReview cards: dark backgrounds with light text
  • FocusMode: dark toolbar, dark filter bar
  • CutFocusMode: dark header, dark footer
  • AssetFocusMode: dark controls panel
  • MobileAssetsView: dark group cards, dark asset rows
  • MobileBehaviorEditor: dark sheet, dark buttons
  • MobileExport: dark panel, dark status badges
  • Settings: dark theme toggle shows current state

19. Browser Tab Context

  • No project → tab shows "Sapari"
  • Open project → tab shows "ProjectName - Sapari"
  • Analyze → tab shows "Analyzing..."
  • Notification arrives → tab shows "(N) ..."

19b. Welcome Modal (Trial Users)

  • First login as trial → welcome modal appears before onboarding
  • Click "GET STARTED" → modal dismisses, onboarding starts
  • Refresh → modal does not reappear

19c. Shortcut Discovery

  • Settings > Preferences tab > Help section shows "Keyboard Shortcuts" button
  • Tap → ShortcutOverlay opens

19d. Error Handling

  • Trigger an error → generic message + support ID shown
  • No internal details visible

20. Edge Cases & Regression

Orientation Transitions

  • Rotate during video playback → playback continues, layout adapts
  • Rotate while in FocusMode → layout switches without losing state
  • Rotate while dragging edit → drag cancels cleanly (no stuck state)
  • Rotate in CutFocusMode → video and waveform reflow correctly
  • Rotate in AssetFocusMode → overlay position preserved

Safe Areas (Notched Devices)

  • Landscape: no content hidden behind notch (left/right safe insets)
  • Portrait: no content hidden behind home indicator (bottom safe inset)

Touch Interactions

  • Threshold-based drag (>4px movement) vs tap distinction works
  • Rapid play/pause (20x) → no stuck audio states
  • Pinch-resize during playback → smooth, no jank
  • Two-finger gestures don't conflict with browser gestures (pinch-zoom)

Empty States

  • No edits detected → swipe review shows appropriate message
  • No assets → asset library shows empty state
  • No captions (language disabled) → captions tab hidden or empty
  • No exports → export panel shows empty state with create button

Boundary Conditions

  • Very short edit (<0.5s) → still visible and selectable in focus modes
  • Edit at time 0 → renders correctly (no off-by-one)
  • Edit at video end → renders correctly
  • Resize edit to minimum duration → segment stays visible, handles accessible
  • Maximum zoom (16x) in FocusMode → timeline remains usable

Undo/Redo Integrity

  • Undo drag in FocusMode → edit returns to previous position
  • Undo accept/dismiss → edit state reverts
  • Undo delete → edit fully restored
  • Redo after undo → change re-applied

Performance

  • 50+ edits in FocusMode → no lag during scroll/zoom
  • Drag edit → smooth movement (no jank)
  • Swipe cards → smooth rotation animation
  • Waveform rendering → no visible delay

Haptic Feedback (Physical Device Only)

  • Light haptic on: waveform seek, card swipe threshold
  • Medium haptic on: accept/dismiss, snap-to-grid activation, state toggles
  • No haptic on: simple taps, navigation