@@ -591,6 +591,44 @@ describe("composition rules", () => {
591591 } ) ;
592592 } ) ;
593593
594+ describe ( "missing_data_no_timeline" , ( ) => {
595+ it ( "warns when root has no timeline registration and no data-no-timeline" , async ( ) => {
596+ const html = `<!DOCTYPE html><html><body>
597+ <div data-composition-id="c1" data-width="320" data-height="180" data-duration="5"></div>
598+ </body></html>` ;
599+ const result = await lintHyperframeHtml ( html ) ;
600+ const finding = result . findings . find ( ( f ) => f . code === "missing_data_no_timeline" ) ;
601+ expect ( finding ) . toBeDefined ( ) ;
602+ expect ( finding ?. severity ) . toBe ( "warning" ) ;
603+ } ) ;
604+
605+ it ( "does not warn when data-no-timeline is present (boolean form)" , async ( ) => {
606+ const html = `<!DOCTYPE html><html><body>
607+ <div data-composition-id="c1" data-no-timeline data-width="320" data-height="180" data-duration="5"></div>
608+ </body></html>` ;
609+ const result = await lintHyperframeHtml ( html ) ;
610+ expect ( result . findings . find ( ( f ) => f . code === "missing_data_no_timeline" ) ) . toBeUndefined ( ) ;
611+ } ) ;
612+
613+ it ( "does not warn when a script registers window.__timelines[id]" , async ( ) => {
614+ const html = `<!DOCTYPE html><html><body>
615+ <div data-composition-id="c1" data-width="320" data-height="180" data-duration="5"></div>
616+ <script>
617+ window.__timelines = window.__timelines || {};
618+ window.__timelines["c1"] = gsap.timeline({ paused: true });
619+ </script>
620+ </body></html>` ;
621+ const result = await lintHyperframeHtml ( html ) ;
622+ expect ( result . findings . find ( ( f ) => f . code === "missing_data_no_timeline" ) ) . toBeUndefined ( ) ;
623+ } ) ;
624+
625+ it ( "does not warn when there is no root composition-id" , async ( ) => {
626+ const html = `<!DOCTYPE html><html><body><p>hello</p></body></html>` ;
627+ const result = await lintHyperframeHtml ( html ) ;
628+ expect ( result . findings . find ( ( f ) => f . code === "missing_data_no_timeline" ) ) . toBeUndefined ( ) ;
629+ } ) ;
630+ } ) ;
631+
594632 describe ( "root_composition_missing_data_duration (removed)" , ( ) => {
595633 // The rule was a static proxy for the runtime's loop-inflation Infinity
596634 // emission, but lint cannot observe GSAP timeline duration statically and
0 commit comments