Repository navigation
test(player): transcript-ownership harness for canvas switches - #70
Merged
Merged
Conversation
Locks in a previously-untested path: a late external-VTT response for a canvas the viewer has already left must not overwrite the current canvas's transcript. The guard (transcriptGeneration in Root's resolveVTTTranscript) already exists — this is a regression lock, not a bug report. The scenario is distinguishable by construction: two video canvases with unmistakably different transcript text and timestamps (ALPHA @ 0:07, BRAVO @ 0:23), delivered as external VTT supplementing tracks under annotations="auto" — the only path that issues a deferrable fetch. A controlled fetch layer (mockFetchRoutes + deferred) holds each VTT response until the test releases it, so it can force resolution in reverse order: mount A, switch to B while A is pending, resolve B, then resolve A late. The test asserts both requests were actually outstanding (so it really reproduces the race) and that BRAVO owns the panel throughout. Expected text and timestamps come from the fixtures, never the library's parser. Calibrated: with the generation re-check temporarily disabled, the test fails at the late-A step (ALPHA overwrites BRAVO), confirming it detects the fault rather than merely the current behavior. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KfYGrLi7iJoevyVQsn5ur
Review follow-up on the ownership harness. Steps 9-10 previously only checked the rendered segment's timestamp text and inferred the seek — a broken click handler would have passed. Now the test drives the media element to ready with a duration, actually clicks the segment, and asserts the seek landed on BRAVO's 23s (not ALPHA's 7s). The late-A wait was a fixed 50ms sleep. Replace it with an explicit signal: wrap loadVTTTranscript via vi.mock (importOriginal, real implementation) to capture the exact promise Root awaits for A, then await that whole chain (fetch → text → parse → generation re-check) before asserting. Re-verified calibration: with the guard disabled the test fails at the late-A step. (An intermediate microtask-drain attempt gave a false green under calibration — caught precisely because calibration was repeated.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KfYGrLi7iJoevyVQsn5ur
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a regression lock for a currently-untested path: a late external-VTT response for a canvas the viewer has already left must not overwrite the current canvas's transcript.
Honest framing
The guard this exercises —
transcriptGenerationre-checked after eachawaitinresolveVTTTranscript— already exists and works. This is not a bug report; it's a named regression test for a path that had no direct coverage (the existingRoot.transcript-generationtest covers a different stale case: an annotations mode-flip vs. an in-flight HLS import).What the test does
0:07, BRAVO @0:23— delivered as external VTTsupplementingtracks underannotations="auto", the only path that issues a deferrable fetch (embedded transcripts resolve synchronously with nothing to race).mockFetchRoutes+deferredto hold each VTT response until released, so the test forces resolution in reverse order: mount A → switch to B while A is pending → resolve B → resolve A late.Test-only; no production changes. Full suite green (734).
🤖 Generated with Claude Code
https://claude.ai/code/session_015KfYGrLi7iJoevyVQsn5ur