mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 17:30:50 +00:00
- Delete unused mediaPreloader module, 5 dead RuntimeState fields, emitPerformanceMetric, lintScriptUrls, 5 variable type guards - Consolidate compiler utilities: unify CSS URL regex, relative URL predicate, MIME map, @import regex, bulk asset rewrite delegation - Cache extractGsapWindows per script (eliminates 2 redundant recast parses per lint run), share stripJsComments and script extraction - Deduplicate GSAP parser: share serializeValue/safeJsKey, centralize converted-id fallback (6 sites), keyframe codegen (3 sites), waypoint extraction, insert-after-anchor, script hoisting - Replace 88 bare any annotations with typed AstNode/AstPath interfaces - Derive RuntimeBridgeControlAction from HyperframeControlAction, alias RuntimePickerElementInfo, share macOS font profiler - Gate generateHyperframesStyles on includeStyles, collapse 4 GSAP property mutation cases into 2 - Extract magic numbers into named constants, replace 5 double casts with type guards and typed accessors (runtime/globals.ts), reduce function complexity in htmlParser and files route
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { initRuntimeAnalytics, emitAnalyticsEvent } from "./analytics";
|
|
|
|
describe("runtime analytics", () => {
|
|
let postMessage: ReturnType<typeof vi.fn>;
|
|
|
|
beforeEach(() => {
|
|
postMessage = vi.fn();
|
|
// Reset module state by re-init
|
|
initRuntimeAnalytics(postMessage);
|
|
});
|
|
|
|
it("emits analytics event via postMessage", () => {
|
|
emitAnalyticsEvent("composition_loaded");
|
|
expect(postMessage).toHaveBeenCalledWith({
|
|
source: "hf-preview",
|
|
type: "analytics",
|
|
event: "composition_loaded",
|
|
properties: {},
|
|
});
|
|
});
|
|
|
|
it("passes properties through", () => {
|
|
emitAnalyticsEvent("composition_played", { duration: 10, autoplay: true });
|
|
expect(postMessage).toHaveBeenCalledWith({
|
|
source: "hf-preview",
|
|
type: "analytics",
|
|
event: "composition_played",
|
|
properties: { duration: 10, autoplay: true },
|
|
});
|
|
});
|
|
|
|
it("does not throw when postMessage is not set", () => {
|
|
// Re-init with a function that we'll clear
|
|
initRuntimeAnalytics(null as unknown as (payload: unknown) => void);
|
|
expect(() => emitAnalyticsEvent("composition_paused")).not.toThrow();
|
|
});
|
|
|
|
it("does not throw when postMessage throws", () => {
|
|
postMessage.mockImplementation(() => {
|
|
throw new Error("channel closed");
|
|
});
|
|
expect(() => emitAnalyticsEvent("composition_seeked")).not.toThrow();
|
|
});
|
|
|
|
it("emits all event types", () => {
|
|
const events = [
|
|
"composition_loaded",
|
|
"composition_played",
|
|
"composition_paused",
|
|
"composition_seeked",
|
|
"composition_ended",
|
|
"element_picked",
|
|
] as const;
|
|
for (const event of events) {
|
|
emitAnalyticsEvent(event);
|
|
}
|
|
expect(postMessage).toHaveBeenCalledTimes(events.length);
|
|
});
|
|
});
|