# Media continuity test matrix

Use this matrix to prove the transition interval, not only the settled viewer.
Capture app-owned events and screen video for every scenario.

## Evidence contract

For each run, record:

- media key and monotonic session token;
- source, transport and viewer visibility changes;
- player identity and playback intent;
- expected destination surface;
- first-visible-frame event;
- source and return measurements with versions;
- gesture classification, release decision and final phase;
- screen recording covering at least 500 ms before and after the handoff.

## Core scenarios

| Scenario | Required assertion | Visual failure to reject |
| --- | --- | --- |
| Portrait image open | Source hides before transport overlaps; viewer takes presentation after settle | Duplicate edges, crop jump, background flash |
| Portrait image close | Fresh return frame matches current row | Return to stale scroll position |
| Portrait video open while playing | Same player identity and continuous intent | Restart, time reset, poster flash |
| Landscape video open | Destination fit is stable before poster clears | Aspect snap, black interval, wrong crop |
| Landscape video close | Current feed rect is resolved again | Late crop correction |
| Cancelled downward drag | Same viewer mount, page and player session survive | Dismiss/reopen, control reset |
| Committed downward drag | Drag geometry hands off to return transport | Jump between drag and close animation |
| Horizontal page change | Only selected page acquires the player | Outgoing frame appears on incoming page |
| Gesture from letterbox | Full viewport participates | Dead black bars |
| Scrubber interaction | Controls keep recognizer priority | Viewer dismiss begins while seeking |
| Row recycled during viewing | Identity gate rejects stale target | Return to another item using the same URI |
| Source offscreen on close | Reveal/scroll/measure completes or close degrades safely | Animation flies to historical coordinates |
| Background during opening | Watchdog restores a valid owner | Hidden source and stranded overlay |
| Background during closing | Handback completes or safely finalises | Duplicate inline and overlay surfaces |
| Rotation / inset change | Layout epoch invalidates old geometry | Return misses source after rotation |
| Video replacement | Stale first-frame callback is rejected | Poster clears for the wrong asset |

## Platform matrix

Run the core scenarios on:

- iOS, current release device;
- iOS, one older supported release;
- Android with `TextureView`;
- Android with the fallback/poster path;
- low-memory Android hardware;
- 60 Hz and 120 Hz devices where available;
- reduced-motion enabled;
- screen reader enabled;
- light and dark system appearance if native controls participate.

## Repetition

Repeat the following sequences at least ten times without restarting the app:

1. open → cancel → cancel → close;
2. open video → play → page away → page back → close;
3. open → background → resume → close;
4. open → scroll source offscreen while viewer remains open → close;
5. tap item A → close → immediately tap item B.

Reject the run if any stale callback changes the active session or if the
recording contains a blank, duplicate or wrong-media frame during transfer.
