plan(0024): add zoom-out E2E case; resolve review-gate open items

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-27 06:17:42 -07:00
parent 441645ae7a
commit 3b3d30e8e0
@@ -822,6 +822,33 @@ test("zoom plays a morph, lands locked, and does not change while parked", async
await page.waitForTimeout(2000);
expect(await readout.textContent()).toBe(landed);
});
test("zooming back OUT plays a reverse morph and lands locked", async ({ page }) => {
const morphs: string[] = [];
page.on("request", (r) => {
const m = r.url().match(/\/media\/(transitions\/[^?]+)/);
if (m) morphs.push(m[1]);
});
await page.addInitScript(() => localStorage.setItem("hef.devMode", "1"));
await page.goto("/");
const readout = page.locator("#scale-name");
await expect(readout).toContainText("cosmos");
// Zoom inward one altitude, then back OUT (wheel up = -). The outward move must
// play a `.rev` morph and land back on cosmos, locked.
await page.locator("#stage").dispatchEvent("wheel", { deltaY: 120 });
await page.waitForTimeout(2500);
morphs.length = 0; // only watch the zoom-out move
await page.locator("#stage").dispatchEvent("wheel", { deltaY: -120 });
await page.waitForTimeout(2500);
expect(morphs.some((f) => /transitions\/cosmos__.*\.rev\.mp4/.test(f))).toBeTruthy();
await expect(readout).toContainText("cosmos");
// Locked after the outward move too.
const landed = (await readout.textContent())!;
await page.waitForTimeout(2000);
expect(await readout.textContent()).toBe(landed);
});
```
- [ ] **Step 3: Install + run**
@@ -898,7 +925,7 @@ git commit -m "chore(media): regenerate 154 clip-pair morphs + manifest"
**Type consistency:** `Transition(from_clip, to_clip, file, model)` (T3) used by `morph_for` (T3), `load_ring` (T3), `resolve_move` (T4), `resolved_move_to_dict` (T6). `MorphStep`/`ResolvedMove` fields (T4) match the serializer (T6) and the renderer's `step.{from_clip,to_clip,file,to_index,blended}` + `move.target_clip_id` (T7). `morphByPair` key `"from→to"` consistent in build (T7 S1) and lookup (T7 S4).
**Open items flagged for the review gate:**
1. **Storage/repo weight:** 154 short mp4s in `sample_media`. They're small, but confirm we're comfortable committing them (vs. a generate-on-setup step). Current repo already commits the 5 + bases, so this extends precedent.
2. **`build_pool_manifest.py` CLI:** Task 9 Step 1 assumes a `--media` flag; confirm the actual entrypoint flags during execution.
3. **Zoom-out E2E:** Task 8 covers zoom-in + lock; a zoom-out assertion is a cheap add if wanted.
**Open items (resolved at the review gate by the operator):**
1. **Storage/repo weight:** ✅ Commit the 154 short mp4s into `sample_media` (extends the existing precedent of committing the 5 + bases).
2. **`build_pool_manifest.py` CLI:** ✅ Approach approved; confirm the actual entrypoint flag during execution (Task 9 Step 1).
3. **Zoom-out E2E:** ✅ Added — Task 8 now covers zoom-in + lock **and** a zoom-out (`.rev` morph) + lock case.