o2buvioma: Autoplay mobile feed videos muted when they snap into view, with a session mute toggle and tap to pause

This commit is contained in:
2026-10-20 10:22:39 -06:00
parent 6af225afa5
commit e37ec780a9
5 changed files with 254 additions and 22 deletions
+46
View File
@@ -0,0 +1,46 @@
import { describe, expect, it } from "vitest";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { readFileSync } from "node:fs";
import { getSessionMuted, isAutoplayBlocked, setSessionMuted } from "@/lib/autoplay";
import { VideoPlayer } from "@/components/VideoPlayer";
describe("session mute choice", () => {
it("starts muted and keeps the person's choice", () => {
expect(getSessionMuted()).toBe(true);
setSessionMuted(false);
expect(getSessionMuted()).toBe(false);
setSessionMuted(true);
expect(getSessionMuted()).toBe(true);
});
});
describe("autoplay refusal", () => {
it("only counts the browser's NotAllowedError", () => {
expect(isAutoplayBlocked({ name: "NotAllowedError" })).toBe(true);
expect(isAutoplayBlocked({ name: "AbortError" })).toBe(false);
expect(isAutoplayBlocked(null)).toBe(false);
expect(isAutoplayBlocked("NotAllowedError")).toBe(false);
});
});
describe("VideoPlayer", () => {
it("is inline and not muted unless asked (desktop unchanged)", () => {
const html = renderToStaticMarkup(createElement(VideoPlayer, { mp4Url: "https://cdn/v.mp4", poster: null, label: "v" }));
expect(html).toContain("playsInline");
expect(html).toContain("controls");
expect(html).not.toContain("muted");
});
it("renders muted inline video for the mobile autoplay", () => {
const html = renderToStaticMarkup(createElement(VideoPlayer, { mp4Url: "https://cdn/v.mp4", poster: null, label: "v", controls: false, muted: true }));
expect(html).toContain("muted");
expect(html).not.toContain("controls");
});
});
describe("mobile autoplay styles", () => {
it("has a frosted mute button", () => {
const css = readFileSync("src/styles/mobile.css", "utf8");
expect(css).toMatch(/\.slide-mute \{[^}]*backdrop-filter/);
});
});