feat(speed): switch Playback Speed to 0x–4x forward (drop reverse)
Real-browser eyeball: below-0x reverse jittered because the base loop clips aren't all-intra (the flagged risk). Narrow the slider to 0x–4x forward (still continuous, step=any); 0x still freezes; OS reduced-motion behavior unchanged. Removes the manual rAF reverse loop and the HEFScrub.reverseStep helper + its unit tests. Tests: node unit 10/10; a11y e2e 12/12 (Task 5 now 3 slider tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,23 +52,25 @@ test.describe("Task 5 — Playback speed slider (replaces Reduce motion)", () =>
|
||||
.toBe(false); // experience running → loop plays
|
||||
}
|
||||
|
||||
test("the Reduce motion toggle is gone, replaced by a speed slider", async ({ page }) => {
|
||||
test("the Reduce motion toggle is gone, replaced by a 0–4x speed slider", async ({ page }) => {
|
||||
await page.emulateMedia({ reducedMotion: "no-preference" });
|
||||
await page.goto("/");
|
||||
await expect(page.locator("#reduce-motion")).toHaveCount(0);
|
||||
const slider = page.locator("#play-speed");
|
||||
await expect(slider).toBeVisible();
|
||||
await expect(slider).toHaveValue("1"); // default = normal speed
|
||||
await expect(slider).toHaveValue("1"); // default = normal speed
|
||||
await expect(slider).toHaveAttribute("min", "0");
|
||||
await expect(slider).toHaveAttribute("max", "4");
|
||||
});
|
||||
|
||||
test("forward speed sets the loop video's playbackRate", async ({ page }) => {
|
||||
test("forward speed sets the loop video's playbackRate (up to 4x)", async ({ page }) => {
|
||||
await page.emulateMedia({ reducedMotion: "no-preference" });
|
||||
await page.goto("/");
|
||||
await startExperience(page);
|
||||
await page.locator("#play-speed").fill("2");
|
||||
await page.locator("#play-speed").fill("4");
|
||||
await expect
|
||||
.poll(() => page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.playbackRate))
|
||||
.toBe(2);
|
||||
.toBe(4);
|
||||
});
|
||||
|
||||
test("0x freezes the loop video", async ({ page }) => {
|
||||
@@ -81,23 +83,6 @@ test.describe("Task 5 — Playback speed slider (replaces Reduce motion)", () =>
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
test("negative speed plays the loop in reverse (manual frame-stepping)", async ({ page }) => {
|
||||
await page.emulateMedia({ reducedMotion: "no-preference" });
|
||||
await page.goto("/");
|
||||
await startExperience(page);
|
||||
await page.locator("#play-speed").fill("-1.5");
|
||||
await page.waitForTimeout(150);
|
||||
const a = await page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.currentTime);
|
||||
const paused = await page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.paused);
|
||||
await page.waitForTimeout(250);
|
||||
const b = await page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.currentTime);
|
||||
// The reverse loop pauses the element and drives currentTime by hand — so the
|
||||
// element reads paused, yet currentTime keeps moving (≠ forward play, ≠ freeze).
|
||||
// (It may wrap loopStart→tail, so we assert movement, not a strict decrease.)
|
||||
expect(paused).toBe(true);
|
||||
expect(b).not.toBe(a);
|
||||
});
|
||||
|
||||
test("OS reduced-motion disables the slider and freezes the loop", async ({ page }) => {
|
||||
await page.emulateMedia({ reducedMotion: "reduce" });
|
||||
await page.goto("/");
|
||||
|
||||
Reference in New Issue
Block a user