@@ -606,4 +606,114 @@ describe('nodeProxyTracker', () => {
606606 const mainComponent = await getMainComponentAsync ( )
607607 expect ( mainComponent ) . toBeNull ( )
608608 } )
609+
610+ test ( 'toTestCaseFormatWithVariables should collect variable info from fills' , async ( ) => {
611+ // Setup figma global mock
612+ const mockFigma = {
613+ variables : {
614+ getVariableByIdAsync : async ( id : string ) => {
615+ if ( id === 'VariableID:123' ) {
616+ return { id : 'VariableID:123' , name : 'primary-color' }
617+ }
618+ return null
619+ } ,
620+ } ,
621+ }
622+ ; ( globalThis as unknown as { figma : typeof mockFigma } ) . figma = mockFigma
623+
624+ // Create a node with boundVariables referencing a variable
625+ const nodeWithVariable = {
626+ ...createMockNode ( { id : 'node-1' , name : 'NodeWithVariable' } ) ,
627+ fills : [
628+ {
629+ type : 'SOLID' ,
630+ color : { r : 1 , g : 0 , b : 0 } ,
631+ boundVariables : {
632+ color : '[NodeId: VariableID:123]' ,
633+ } ,
634+ } ,
635+ ] ,
636+ } as unknown as SceneNode
637+
638+ const wrapped = nodeProxyTracker . wrap ( nodeWithVariable )
639+
640+ // Access fills to trigger tracking
641+ const _fills = ( wrapped as unknown as FrameNode ) . fills
642+
643+ // Call toTestCaseFormatWithVariables
644+ const result = await nodeProxyTracker . toTestCaseFormatWithVariables ( )
645+
646+ expect ( result . nodes . length ) . toBe ( 1 )
647+ expect ( result . variables . length ) . toBe ( 1 )
648+ expect ( result . variables [ 0 ] . id ) . toBe ( 'VariableID:123' )
649+ expect ( result . variables [ 0 ] . name ) . toBe ( 'primary-color' )
650+ } )
651+
652+ test ( 'assembleNodeTree should setup variable mocks when variables provided' , async ( ) => {
653+ // Create nodes with variable reference in fills
654+ const nodes = [
655+ {
656+ id : 'node-1' ,
657+ name : 'NodeWithVariable' ,
658+ type : 'FRAME' ,
659+ fills : [
660+ {
661+ type : 'SOLID' ,
662+ boundVariables : {
663+ color : 'VariableID:456' ,
664+ } ,
665+ } ,
666+ ] ,
667+ } ,
668+ ]
669+
670+ const variables = [ { id : 'VariableID:456' , name : 'secondary-color' } ]
671+
672+ // Call assembleNodeTree with variables
673+ const rootNode = assembleNodeTree ( nodes , variables )
674+
675+ expect ( rootNode . id ) . toBe ( 'node-1' )
676+
677+ // Verify variable mock was set up
678+ const g = globalThis as {
679+ figma ?: {
680+ variables ?: { getVariableByIdAsync ?: ( id : string ) => Promise < unknown > }
681+ }
682+ }
683+ expect ( g . figma ?. variables ?. getVariableByIdAsync ) . toBeDefined ( )
684+
685+ // Call the mock to verify it returns the variable info
686+ const getVariableByIdAsync = g . figma ?. variables ?. getVariableByIdAsync
687+ if ( getVariableByIdAsync ) {
688+ const variable = await getVariableByIdAsync ( 'VariableID:456' )
689+ expect ( variable ) . toEqual ( {
690+ id : 'VariableID:456' ,
691+ name : 'secondary-color' ,
692+ } )
693+ }
694+ } )
695+
696+ test ( 'assembleNodeTree should add getMainComponentAsync to non-INSTANCE nodes' , async ( ) => {
697+ // Create a FRAME node (not INSTANCE)
698+ const nodes = [
699+ {
700+ id : 'frame-1' ,
701+ name : 'FrameNode' ,
702+ type : 'FRAME' ,
703+ } ,
704+ ]
705+
706+ const rootNode = assembleNodeTree ( nodes )
707+
708+ expect ( rootNode . type ) . toBe ( 'FRAME' )
709+
710+ // The FRAME node should have getMainComponentAsync method (default fallback)
711+ expect ( typeof rootNode . getMainComponentAsync ) . toBe ( 'function' )
712+
713+ // Call the method and verify it returns null
714+ const getMainComponentAsync =
715+ rootNode . getMainComponentAsync as ( ) => Promise < unknown >
716+ const result = await getMainComponentAsync ( )
717+ expect ( result ) . toBeNull ( )
718+ } )
609719} )
0 commit comments