@@ -24,3 +24,93 @@ Cypress.Commands.add('accordionItem', (name) => {
2424
2525  cy . get ( '.list-group-item' ) . contains ( name ) . click ( ) ; 
2626} ) ; 
27+ 
28+ /** 
29+  * Selects an accordion item based on a path of labels. 
30+  * @param  accordionPath: The path can be a mix of strings and regular expressions. 
31+  * For example, `[/^ManageIQ Region/, 'Zone', 'Server']` 
32+  * will expand the accordion until it finds the item with the label 'Server' under 'Zone' under 'ManageIQ Region'. 
33+  * If the path is not found, it will throw an error. 
34+  */ 
35+ Cypress . Commands . add ( 'selectAccordionItem' ,  ( accordionPath )  =>  { 
36+   cy . get ( 'li.list-group-item' ) . then ( ( $items )  =>  { 
37+     // Converting jQuery collection to an array for easier manipulation 
38+     const  listItems  =  [ ...$items ] ; 
39+ 
40+     /** 
41+      * Function to recursively expand the accordion and click the target item. 
42+      * @param  {number } accordionPathIndex: The current index in the accordionPath array. 
43+      * @param  {number } searchStartIndex: The index in the listItems array to start searching from, 
44+      *                                   once the first label is matched, it is not required to start iterating from the beginning. 
45+      * @returns  {void } 
46+      */ 
47+     const  expandAndClickPath  =  ( accordionPathIndex ,  searchStartIndex )  =>  { 
48+       const  accordionLabel  =  accordionPath [ accordionPathIndex ] ; 
49+       const  isClickableNode  =  accordionPathIndex  ===  accordionPath . length  -  1 ; 
50+ 
51+       for  ( let  i  =  searchStartIndex ;  i  <  listItems . length ;  i ++ )  { 
52+         /* To remove */ 
53+         Cypress . log ( { 
54+           name : 'selectAccordionItem' , 
55+           message : `Loop index: ${ i } ${ accordionLabel }  , 
56+         } ) ; 
57+ 
58+         const  liText  =  listItems [ i ] . textContent . trim ( ) ; 
59+         // Check if the current item matches the label 
60+         // Use either string match or regex match based on the type of accordionLabel 
61+         let  isMatch  =  false ; 
62+         if  ( typeof  accordionLabel  ===  'string' )  { 
63+           isMatch  =  liText  ===  accordionLabel ; 
64+         }  else  if  ( accordionLabel  instanceof  RegExp )  { 
65+           isMatch  =  accordionLabel . test ( liText ) ; 
66+         } 
67+ 
68+         if  ( isMatch )  { 
69+           /* To remove */ 
70+           Cypress . log ( { 
71+             name : 'selectAccordionItem' , 
72+             message : `Matched "${ liText } ${ i }  , 
73+           } ) ; 
74+ 
75+           // Wrap the current li element in a jQuery object to use jQuery methods 
76+           const  currentLiElement  =  Cypress . $ ( listItems [ i ] ) ; 
77+           // If it's the last label in the path, then that is the desired item to click 
78+           if  ( isClickableNode )  { 
79+             // Click the node corresponding to the last label in the given path and terminate 
80+             cy . wrap ( currentLiElement ) . click ( ) ; 
81+             return ; 
82+           } 
83+ 
84+           const  isExpandable  = 
85+             currentLiElement . find ( 'span.fa-angle-right' ) . length  >  0 ; 
86+ 
87+           // If it's not the last label in the path, either expand the node 
88+           // or move to the next label in the given path 
89+           if  ( isExpandable )  { 
90+             // Expand the node 
91+             cy . wrap ( currentLiElement ) 
92+               . find ( 'span.fa-angle-right' ) 
93+               . click ( ) 
94+               . then ( ( )  =>  { 
95+                 // Recurse to the next label in the given path array and 
96+                 // start iteration from the current index 
97+                 expandAndClickPath ( accordionPathIndex  +  1 ,  i  +  1 ) ; 
98+               } ) ; 
99+           }  else  { 
100+             // If it's already expanded, continue to the next label 
101+             // start iteration from the current index 
102+             expandAndClickPath ( accordionPathIndex  +  1 ,  i  +  1 ) ; 
103+           } 
104+           // Exit the current function scope 
105+           return ; 
106+         } 
107+       } 
108+       // If we reach here, it means the label was not found 
109+       throw  new  Error ( `Accordion item: "${ accordionLabel }  ) ; 
110+     } ; 
111+ 
112+     // Start the recursive call from the first label in the given path 
113+     // and from the beginning of the accordion items in the panel 
114+     expandAndClickPath ( 0 ,  0 ) ; 
115+   } ) ; 
116+ } ) ; 
0 commit comments