mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
Addresses review comments on #982: - studio shouldTrack(): adds VITE_HYPERFRAMES_NO_TELEMETRY (mirrors CLI's HYPERFRAMES_NO_TELEMETRY) and import.meta.env.DEV gates so dev / CI studio builds don't pollute production telemetry. shouldTrack() is now exported for testability. - App.tsx session dedupe: moves the once-per-session check from a useRef (which resets on HMR / remount) to sessionStorage via new hasFiredSessionStart / markSessionStartFired helpers in config.ts. - studioRenderTelemetry.ts: documents why `workers` is intentionally omitted from emitStudioRenderError (studio renders don't accept a user-supplied worker count, so early failures genuinely don't know one). - client.ts flush(): documents fire-and-forget no-retry design so future hands don't accidentally add retry logic that double-counts. Tests: - studioRenderTelemetry.test.ts (8 tests): perfPayload mapping for every RenderPerfSummary field, undefined-perf path, missing-extract path, zero-elapsed edge case, error event shape. - studio/telemetry/events.test.ts (4 tests): pin event names (studio_session_start, studio_render_start) and payload shape. - studio/telemetry/client.test.ts (9 tests): shouldTrack() returns false for non-phc_ key, opt-out, doNotTrack, build-time env, vite dev mode; memoization.
58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
|
|
// Mock client.trackEvent so we can assert event names and payloads without
|
|
// firing network requests or relying on memoized shouldTrack() state.
|
|
const trackEvent = vi.fn();
|
|
vi.mock("./client", () => ({
|
|
trackEvent: (...args: unknown[]) => trackEvent(...args),
|
|
}));
|
|
|
|
const { trackStudioSessionStart, trackStudioRenderStart } = await import("./events");
|
|
|
|
describe("studio telemetry events", () => {
|
|
beforeEach(() => {
|
|
trackEvent.mockClear();
|
|
});
|
|
|
|
it("trackStudioSessionStart emits 'studio_session_start' with has_project", () => {
|
|
trackStudioSessionStart({ has_project: true });
|
|
expect(trackEvent).toHaveBeenCalledOnce();
|
|
expect(trackEvent).toHaveBeenCalledWith("studio_session_start", { has_project: true });
|
|
});
|
|
|
|
it("trackStudioSessionStart preserves false for has_project (scratch open)", () => {
|
|
trackStudioSessionStart({ has_project: false });
|
|
expect(trackEvent).toHaveBeenCalledWith("studio_session_start", { has_project: false });
|
|
});
|
|
|
|
it("trackStudioRenderStart emits 'studio_render_start' with all render opts", () => {
|
|
trackStudioRenderStart({
|
|
fps: 30,
|
|
quality: "standard",
|
|
format: "mp4",
|
|
resolution: "landscape",
|
|
composition: "intro.html",
|
|
});
|
|
expect(trackEvent).toHaveBeenCalledOnce();
|
|
expect(trackEvent).toHaveBeenCalledWith("studio_render_start", {
|
|
fps: 30,
|
|
quality: "standard",
|
|
format: "mp4",
|
|
resolution: "landscape",
|
|
composition: "intro.html",
|
|
});
|
|
});
|
|
|
|
it("trackStudioRenderStart leaves optional fields undefined when omitted", () => {
|
|
trackStudioRenderStart({ fps: 60, quality: "high", format: "webm" });
|
|
const payload = trackEvent.mock.calls[0][1];
|
|
expect(payload).toEqual({
|
|
fps: 60,
|
|
quality: "high",
|
|
format: "webm",
|
|
resolution: undefined,
|
|
composition: undefined,
|
|
});
|
|
});
|
|
});
|