@@ -5,6 +5,11 @@ export interface Position {
55 y : number ;
66}
77
8+ export interface ComponentWithCategory {
9+ name : string ;
10+ category ?: string ;
11+ }
12+
813export const getLocatorPosition = async (
914 locator : Locator
1015) : Promise < Position > => {
@@ -73,10 +78,107 @@ export const addComponentsToCanvas = async (
7378 }
7479} ;
7580
81+ export const addComponentsWithDifferentCategoriesToCanvas = async (
82+ page : Page ,
83+ components : ComponentWithCategory [ ] ,
84+ displacementQty : number = 120
85+ ) => {
86+ // Handle empty array
87+ if ( components . length === 0 ) {
88+ return ;
89+ }
90+
91+ const stageCanvas = await page . locator ( '#konva-stage canvas' ) . nth ( 1 ) ;
92+ const canvasPosition = await stageCanvas . boundingBox ( ) ;
93+ if ( ! canvasPosition ) throw new Error ( 'No canvas found' ) ;
94+
95+ let currentCategory : string | undefined = undefined ;
96+
97+ for await ( const [ index , componentConfig ] of components . entries ( ) ) {
98+ try {
99+ // Change category only if it's different from current one
100+ if (
101+ componentConfig . category &&
102+ componentConfig . category !== currentCategory
103+ ) {
104+ const categoryButton = page . getByText ( componentConfig . category , {
105+ exact : true ,
106+ } ) ;
107+
108+ // Check if category exists before clicking
109+ await categoryButton . waitFor ( { state : 'visible' , timeout : 3000 } ) ;
110+ await categoryButton . click ( ) ;
111+
112+ // Wait a bit for the category change to take effect
113+ await page . waitForTimeout ( 500 ) ;
114+ currentCategory = componentConfig . category ;
115+ }
116+
117+ // Find component with better handling for duplicates
118+ let component = page . getByAltText ( componentConfig . name , { exact : true } ) ;
119+
120+ // Check if there are multiple elements with the same alt text
121+ const componentCount = await component . count ( ) ;
122+
123+ if ( componentCount > 1 ) {
124+ // Handle duplicates by selecting the first visible one in the current category context
125+ console . warn (
126+ `Multiple components found with name "${ componentConfig . name } ". Using first visible one.`
127+ ) ;
128+ component = component . first ( ) ;
129+ }
130+
131+ // Wait for component to be available
132+ await component . waitFor ( { state : 'visible' , timeout : 5000 } ) ;
133+ await component . scrollIntoViewIfNeeded ( ) ;
134+ const position = await getLocatorPosition ( component ) ;
135+
136+ const targetPosition = (
137+ displacementQty : number ,
138+ multiplyFactor : number
139+ ) => {
140+ const positionDisplacement = displacementQty * ( multiplyFactor + 1 ) ;
141+ return {
142+ x : canvasPosition . x + displacementQty + positionDisplacement ,
143+ y : canvasPosition . y + positionDisplacement ,
144+ } ;
145+ } ;
146+
147+ await dragAndDrop ( page , position , targetPosition ( displacementQty , index ) ) ;
148+ } catch ( error ) {
149+ const errorMessage =
150+ error instanceof Error ? error . message : String ( error ) ;
151+ throw new Error (
152+ `Failed to add component "${ componentConfig . name } " from category "${ componentConfig . category || 'default' } ": ${ errorMessage } `
153+ ) ;
154+ }
155+ }
156+ } ;
157+
76158export const getShapePosition = async ( shape : Group ) : Promise < Position > => {
77159 return { x : shape ?. attrs . x , y : shape ?. attrs . y } ;
78160} ;
79161
162+ export const selectAllComponentsInCanvas = async (
163+ page : Page ,
164+ selectionArea ?: { start : Position ; end : Position }
165+ ) => {
166+ // Clear any existing selection first
167+ await page . mouse . click ( 800 , 130 ) ;
168+
169+ // Small delay to ensure the click is processed
170+ await page . waitForTimeout ( 100 ) ;
171+
172+ const selectionStart = selectionArea ?. start || { x : 260 , y : 130 } ;
173+ const selectionEnd = selectionArea ?. end || { x : 1000 , y : 650 } ;
174+
175+ // Perform drag selection using the proven coordinates
176+ await dragAndDrop ( page , selectionStart , selectionEnd ) ;
177+
178+ // Small delay to ensure selection is processed
179+ await page . waitForTimeout ( 200 ) ;
180+ } ;
181+
80182export const moveSelected = (
81183 page : Page ,
82184 direction : string ,
0 commit comments