mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
test(core): address review feedback on T6a / T10 / T7 stubs (#1268)
T6a (#1263): add fromTo corpus script (third parser method) with negative position values to exercise UnaryExpression arm; drop unused breatheRepeats from COMPLEX_SCRIPT; generate fromto.parsed.json + fromto.serialized.js goldens. T10 (#1262): split applyDraft move/resize into two stubs; add applyDraft edge- case describe block (concurrent gestures, idempotent revert, playhead-change stability, nested sub-composition root); add getElementTimings stub for absent data-start/end on a data-hf-id element. T7 (#1267): expand to full parity with T3 — add text-content, attribute, and fallthrough stubs (Core sourceMutation supports all patch types via patchElementInHtml).
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"animations": [
|
||||||
|
{
|
||||||
|
"targetSelector": "#hero",
|
||||||
|
"method": "fromTo",
|
||||||
|
"position": 0.1,
|
||||||
|
"properties": {
|
||||||
|
"x": 0,
|
||||||
|
"opacity": 1
|
||||||
|
},
|
||||||
|
"fromProperties": {
|
||||||
|
"x": -200,
|
||||||
|
"opacity": 0
|
||||||
|
},
|
||||||
|
"duration": 0.6,
|
||||||
|
"ease": "power3.out",
|
||||||
|
"id": "#hero-fromTo-100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"targetSelector": "#caption",
|
||||||
|
"method": "fromTo",
|
||||||
|
"position": 0.5,
|
||||||
|
"properties": {
|
||||||
|
"y": 0,
|
||||||
|
"opacity": 1
|
||||||
|
},
|
||||||
|
"fromProperties": {
|
||||||
|
"y": -30,
|
||||||
|
"opacity": 0
|
||||||
|
},
|
||||||
|
"duration": 0.45,
|
||||||
|
"id": "#caption-fromTo-500"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timelineVar": "tl",
|
||||||
|
"preamble": "var tl = gsap.timeline({ paused: true });",
|
||||||
|
"postamble": "window.__timelines[\"hero-reveal\"] = tl;"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
var tl = gsap.timeline({ paused: true });
|
||||||
|
tl.fromTo("#hero", { x: -200, opacity: 0 }, { x: 0, opacity: 1, duration: 0.6, ease: "power3.out" }, 0.1);
|
||||||
|
tl.fromTo("#caption", { y: -30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.45 }, 0.5);
|
||||||
|
window.__timelines["hero-reveal"] = tl;
|
||||||
|
|
||||||
@@ -51,13 +51,22 @@ const COMPLEX_SCRIPT = `\
|
|||||||
window.__timelines = window.__timelines || {};
|
window.__timelines = window.__timelines || {};
|
||||||
gsap.defaults({ force3D: true });
|
gsap.defaults({ force3D: true });
|
||||||
const tl = gsap.timeline({ paused: true, defaults: { duration: 0.45, ease: "power3.out" } });
|
const tl = gsap.timeline({ paused: true, defaults: { duration: 0.45, ease: "power3.out" } });
|
||||||
const breatheRepeats = Math.ceil(7 / 2.4) - 1;
|
|
||||||
tl.from(".headline span", { y: 46, opacity: 0, stagger: 0.055, duration: 0.38, ease: "back.out(1.35)" }, 0.05)
|
tl.from(".headline span", { y: 46, opacity: 0, stagger: 0.055, duration: 0.38, ease: "back.out(1.35)" }, 0.05)
|
||||||
.from(".headline .sub", { y: 20, opacity: 0, duration: 0.28 }, 0.2)
|
.from(".headline .sub", { y: 20, opacity: 0, duration: 0.28 }, 0.2)
|
||||||
.from(".ambient-word", { scale: 0.92, opacity: 0, duration: 0.5 }, 0.08)
|
.from(".ambient-word", { scale: 0.92, opacity: 0, duration: 0.5 }, 0.08)
|
||||||
.from(".ambient-line", { scaleX: 0, opacity: 0, stagger: 0.08, duration: 0.42 }, 0.16);
|
.from(".ambient-line", { scaleX: 0, opacity: 0, stagger: 0.08, duration: 0.42 }, 0.16);
|
||||||
window.__timelines["vpn-youtube-spot"] = tl;`;
|
window.__timelines["vpn-youtube-spot"] = tl;`;
|
||||||
|
|
||||||
|
// fromTo: exercises the three-argument (fromArg, toArg, position) AST path and
|
||||||
|
// negative numeric literals (UnaryExpression arm in resolveNode).
|
||||||
|
const FROMTO_SCRIPT = `\
|
||||||
|
var tl = gsap.timeline({ paused: true });
|
||||||
|
var hero = document.getElementById("hero");
|
||||||
|
var caption = document.getElementById("caption");
|
||||||
|
tl.fromTo(hero, { x: -200, opacity: 0 }, { x: 0, opacity: 1, duration: 0.6, ease: "power3.out" }, 0.1);
|
||||||
|
tl.fromTo(caption, { y: -30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.45 }, 0.5);
|
||||||
|
window.__timelines["hero-reveal"] = tl;`;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -123,4 +132,20 @@ describe("T6a — GSAP parser golden tests (Recast/Babel baseline)", () => {
|
|||||||
await expect(serialized).toMatchFileSnapshot(g("complex.serialized.js"));
|
await expect(serialized).toMatchFileSnapshot(g("complex.serialized.js"));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromTo — two tl.fromTo calls with negative positions (hero-reveal)", () => {
|
||||||
|
let parsed: string;
|
||||||
|
let serialized: string;
|
||||||
|
beforeAll(() => {
|
||||||
|
({ parsed, serialized } = parseAndSerialize(FROMTO_SCRIPT));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("parseGsapScript output matches golden", async () => {
|
||||||
|
await expect(parsed).toMatchFileSnapshot(g("fromto.parsed.json"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("serializeGsapAnimations output matches golden", async () => {
|
||||||
|
await expect(serialized).toMatchFileSnapshot(g("fromto.serialized.js"));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,13 +26,33 @@ describe("T10 — PreviewAdapter contract (spec for R7)", () => {
|
|||||||
describe("applyDraft / revertDraft", () => {
|
describe("applyDraft / revertDraft", () => {
|
||||||
it.todo("applyDraft writes --hf-studio-* CSS props and sets the gesture marker");
|
it.todo("applyDraft writes --hf-studio-* CSS props and sets the gesture marker");
|
||||||
|
|
||||||
it.todo("applyDraft accepts both move (dx/dy) and resize (w/h) payloads");
|
it.todo("applyDraft accepts a move payload (dx/dy) and writes the translate draft");
|
||||||
|
|
||||||
|
it.todo("applyDraft accepts a resize payload (w/h) and writes the size draft");
|
||||||
|
|
||||||
it.todo("revertDraft removes draft props and clears the gesture marker");
|
it.todo("revertDraft removes draft props and clears the gesture marker");
|
||||||
|
|
||||||
it.todo("revertDraft restores original translate when an original was recorded");
|
it.todo("revertDraft restores original translate when an original was recorded");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("applyDraft edge cases (R7 implementation contract)", () => {
|
||||||
|
it.todo(
|
||||||
|
"second applyDraft before revert/commit overwrites first draft — does not accumulate (dx/dy)",
|
||||||
|
);
|
||||||
|
|
||||||
|
it.todo(
|
||||||
|
"revertDraft is safe to call when no gesture is in progress (idempotent / no-op on empty marker)",
|
||||||
|
);
|
||||||
|
|
||||||
|
it.todo(
|
||||||
|
"elementAtPoint filtering is stable when playhead changes mid-drag — opacity re-evaluated per call",
|
||||||
|
);
|
||||||
|
|
||||||
|
it.todo(
|
||||||
|
"stage-root exclusion applies only to the outermost data-hf-root; nested sub-composition roots count as targets",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
describe("commitPreview", () => {
|
describe("commitPreview", () => {
|
||||||
it.todo("returns null when no gesture marker is present");
|
it.todo("returns null when no gesture marker is present");
|
||||||
|
|
||||||
@@ -47,5 +67,9 @@ describe("T10 — PreviewAdapter contract (spec for R7)", () => {
|
|||||||
it.todo("reads authored absolute times from data-start / data-end");
|
it.todo("reads authored absolute times from data-start / data-end");
|
||||||
|
|
||||||
it.todo("ignores elements without data-hf-id");
|
it.todo("ignores elements without data-hf-id");
|
||||||
|
|
||||||
|
it.todo(
|
||||||
|
"returns a defined timing entry when data-hf-id is present but data-start / data-end are missing",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -365,8 +365,16 @@ describe("probeElementInSource", () => {
|
|||||||
// T7 — data-hf-id targeting (spec for R1).
|
// T7 — data-hf-id targeting (spec for R1).
|
||||||
// R1 adds `hfId?: string` to SourceMutationTarget and a `[data-hf-id="…"]` branch
|
// R1 adds `hfId?: string` to SourceMutationTarget and a `[data-hf-id="…"]` branch
|
||||||
// in findTargetElement (sourceMutation.ts:34). Convert from it.todo in the R1 PR.
|
// in findTargetElement (sourceMutation.ts:34). Convert from it.todo in the R1 PR.
|
||||||
|
// Covers the same surface as T3 (Studio sourcePatcher) — Core sourceMutation supports
|
||||||
|
// all patch types (inline-style, attribute, text-content) via patchElementInHtml.
|
||||||
describe("T7 — data-hf-id targeting (spec for R1)", () => {
|
describe("T7 — data-hf-id targeting (spec for R1)", () => {
|
||||||
it.todo("patches element by data-hf-id when no HTML id attribute is present");
|
it.todo("updates inline style by data-hf-id when no HTML id attribute is present");
|
||||||
|
|
||||||
|
it.todo("updates text content by data-hf-id");
|
||||||
|
|
||||||
|
it.todo("updates attribute by data-hf-id");
|
||||||
|
|
||||||
it.todo("data-hf-id attribute survives the patch (can be targeted again)");
|
it.todo("data-hf-id attribute survives the patch (can be targeted again)");
|
||||||
|
|
||||||
|
it.todo("hfId lookup falls through to selector when hfId is not found in the document");
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user