mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(registry): caption components keep the last phrase until its last word ends (#6792)
* fix(registry): caption components keep the last phrase until its last word ends * test(registry): caption last group stays visible until its last word ends * test(registry): narrow the timeline lookup for strict typecheck
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import puppeteer, { type Browser } from "puppeteer-core";
|
||||
|
||||
const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
const componentHtml = readFileSync(
|
||||
new URL(
|
||||
"../../../../registry/components/caption-highlight/caption-highlight.html",
|
||||
import.meta.url,
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
const gsapScript = readFileSync(
|
||||
createRequire(new URL("../../../core/package.json", import.meta.url)).resolve(
|
||||
"gsap/dist/gsap.min.js",
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
/** Scaled demo words: the last group opens before the old 7.95 s cap and its last word ends after it. */
|
||||
const STRETCH = 1.15;
|
||||
const LAST_WORD_START_S = 7.3 * STRETCH;
|
||||
const LAST_WORD_END_S = 7.7 * STRETCH;
|
||||
|
||||
function stretchedComponent(): string {
|
||||
const wordsStart = componentHtml.indexOf("var WORDS = [");
|
||||
const wordsEnd = componentHtml.indexOf("];", wordsStart);
|
||||
const words = componentHtml
|
||||
.slice(wordsStart, wordsEnd)
|
||||
.replace(/(start|end): ([\d.]+)/g, (_, key, value) => `${key}: ${Number(value) * STRETCH}`);
|
||||
return (componentHtml.slice(0, wordsStart) + words + componentHtml.slice(wordsEnd)).replace(
|
||||
/<script src="https:[^"]*gsap[^"]*"><\/script>/,
|
||||
`<script>${gsapScript}</script>`,
|
||||
);
|
||||
}
|
||||
|
||||
describe.runIf(executablePath)("caption-highlight last group in Chromium", () => {
|
||||
let browser: Browser;
|
||||
|
||||
beforeAll(async () => {
|
||||
browser = await puppeteer.launch({ executablePath, args: ["--no-sandbox"] });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await browser?.close();
|
||||
});
|
||||
|
||||
async function lastGroupVisibleAt(time: number): Promise<boolean> {
|
||||
const page = await browser.newPage();
|
||||
try {
|
||||
await page.setContent(stretchedComponent());
|
||||
return await page.evaluate((t) => {
|
||||
const timeline = (
|
||||
window as unknown as { __timelines: Record<string, { seek(t: number): void }> }
|
||||
).__timelines["caption-highlight"];
|
||||
timeline!.seek(t);
|
||||
const groups = document.querySelectorAll(".hl-group");
|
||||
const style = getComputedStyle(groups[groups.length - 1]!);
|
||||
return style.visibility !== "hidden" && Number(style.opacity) > 0;
|
||||
}, time);
|
||||
} finally {
|
||||
await page.close();
|
||||
}
|
||||
}
|
||||
|
||||
it("shows the last phrase from its first word to just before its last word ends", async () => {
|
||||
expect(await lastGroupVisibleAt(LAST_WORD_START_S)).toBe(true);
|
||||
expect(await lastGroupVisibleAt(LAST_WORD_END_S - 0.05)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -56,6 +56,18 @@ describe("registry components", () => {
|
||||
expect(invalidMedia).toEqual([]);
|
||||
});
|
||||
|
||||
it("never caps a caption's last group at a fixed demo-length constant", () => {
|
||||
const capped: string[] = [];
|
||||
|
||||
for (const entry of readdirSync(componentsDir, { withFileTypes: true })) {
|
||||
if (!entry.isDirectory() || !entry.name.startsWith("caption-")) continue;
|
||||
const html = readFileSync(join(componentsDir, entry.name, `${entry.name}.html`), "utf8");
|
||||
if (/nextStart\s*=[^;]*:\s*\d+(?:\.\d+)?;/.test(html)) capped.push(entry.name);
|
||||
}
|
||||
|
||||
expect(capped).toEqual([]);
|
||||
});
|
||||
|
||||
it("ships demos without source-less media", async () => {
|
||||
const invalidMedia: string[] = [];
|
||||
|
||||
|
||||
@@ -153,7 +153,8 @@
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var nextStart =
|
||||
gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : Infinity;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.5, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
var ws = pair[0];
|
||||
var we = pair[1];
|
||||
var nextStart =
|
||||
gi + 1 < RAW_GROUPS.length ? TRANSCRIPT[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
gi + 1 < RAW_GROUPS.length ? TRANSCRIPT[RAW_GROUPS[gi + 1][0]].start : Infinity;
|
||||
var end = Math.min(TRANSCRIPT[we].end + 0.24, nextStart - 0.04);
|
||||
return { wordStart: ws, wordEnd: we, start: TRANSCRIPT[ws].start, end: end };
|
||||
});
|
||||
|
||||
@@ -178,7 +178,8 @@
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var nextStart =
|
||||
gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : Infinity;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.5, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
@@ -174,7 +174,8 @@
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var nextStart =
|
||||
gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : Infinity;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user