test(studio): the edit bench render serves GSAP from the repo, never the CDN - #4996
Conversation
Edit accuracy: accurate 1556 (base branch 1556), smooth 1426 of thoseThe gate passes. Quarantined, measured but not gated (0) |
terencecho
left a comment
There was a problem hiding this comment.
Approving cfb1a296. The bench's render step no longer waits on jsdelivr, and the fix reaches the real browser, not just the mocked test.
What I verified
- End to end, with a stalled CDN. I ran
renderBoxon therotate-size-px-r0-root-z200-onfixture with a proxy that accepts connections and never answers (stand-in for a stalled jsdelivr). Before this change (the tworender.mjsedits removed): 33.2 s, box 240x160, which is the 0 s frame and the CI failure. At this head: 1.1 s, box 300x200, twice. With the network reachable, the old code gives 300x200, so the stall is what flips it. - Unit test.
render.test.mjspasses 3 of 3 runs at this head (needsNODE_ENV=testand the dependency packages built, as for the other studio tests). It is picked up by the studio vitest config like its siblings. - Mutants. Five changes to
render.mjs, each failing the one test: no local serving (expected [] to deeply equal ['Fetch.enable', …]), dedup option dropped, dedup set totrue, serving started afterinitializeSession(so the first request is missed), and serving attached to a different page. - Scope. Three files under
packages/studio/tests/e2e/edit-accuracy/:exportadded toserveFixtureAssetsLocally, two lines inrender.mjs, and the new test. No product or runtime change, andcase.mjsdoes not importrender.mjs, so the new import adds no cycle.
Non-blocking
- The Fetch pattern is
https://cdn.jsdelivr.net/*, and any jsdelivr URL that is not the installed gsap's dist is now failed withBlockedByClienton the producer page too (and named once by the existing warning), same as the Studio half. Fine for today's fixtures; a fixture that loads another jsdelivr file would now fail its render alone. - The unit test mocks the producer, so it pins the wiring (pattern, order, dedup off), not real interception. My run above is the real-browser check.
CI at this head is not finished: 56 pass, 2 skipped, 0 failing, 35 still pending (20 Studio: edit accuracy shards, 10 regression-shards, and the Windows jobs). Nothing is red, so this approval is on code merit, not CI completion. The edit accuracy shards are the ones to watch, since they exercise this change. It is not authorization to merge or deploy beyond what the gate already does.
— Review by tai (pr-review)
What this fixes
The edit accuracy case
rotate-size-px-r0-root-z200-onfailed itsrendermetric on some CI runs and passed on others with the same code (65.62 px vs 0.03 px). The failing runs also took about 30 s longer (60 s vs 29 s).Cause: the bench's render step renders the saved project through the producer's own browser, and that browser fetched GSAP from cdn.jsdelivr.net. #4968 made the Studio half serve GSAP from the repo, but not this step. When jsdelivr stalled, the fixture's blocking GSAP script held the page load until Chrome gave the request up (about 30 s), GSAP never ran, the producer's short wait after a failed script found no timeline, and the frame showed the box at its 0 s size (240x160) instead of its 2 s size (300x200). The failing CI runs already included #4968.
A second page had the same problem: the producer's static-frame dedup opens a verification page that loads the project again from the network. The bench captures one frame, so it needs no dedup.
Change
render.mjsserves the fixture's CDN requests from the repo on the producer's page (the sameserveFixtureAssetsLocallythe Studio half uses, now exported fromcase.mjs), before the page loads.render.mjsturns static-frame dedup off for its one-frame render, so no second page fetches GSAP.render.test.mjsrunsrenderBoxwith the producer mocked and checks that the interception pattern covers the fixture's GSAP URL, that GSAP is served from the repo'sgsapdist, and that dedup is off.Evidence
Same saved project, a proxy that accepts connections and never answers standing in for a stalled jsdelivr:
renderrender.test.mjs: 3 of 3 runs exit 0. Six mutations each turn it red: no local serving ("expected [] to deeply equal ['Fetch.enable', …]"), dedup left on ("expected { playerReadyTimeout: 10000 } to match object { staticFrameDedup: false }"), an interception pattern for another host, the pattern without its trailing*(Chrome then matches only the exact URL; the test matches patterns the way Chrome does), and a pattern narrowed byrequestStage: "Response"or byresourceType: "Document"(the test checks the whole pattern object).Chrome still opens two speculative connections to jsdelivr per run with the CDN stalled. Nothing waits on them: the case time matches the run with the CDN answering.
No visible change
Test harness only; nothing a Studio user sees changes.
Why it ships alone
Under 100 lines on purpose: this flake can turn the required edit accuracy gate red on any unrelated Studio PR, and the next change in this area (the crop-scale render fix) touches the runtime and waits on its own decision, so nothing ready can carry it.