@@ -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 > => {
@@ -44,6 +49,18 @@ export const dragAndDrop = async (
4449 await page . mouse . up ( ) ;
4550} ;
4651
52+ const getTargetPosition = (
53+ canvasPosition : { x : number ; y : number } ,
54+ displacementQty : number ,
55+ multiplyFactor : number
56+ ) : Position => {
57+ const positionDisplacement = displacementQty * ( multiplyFactor + 1 ) ;
58+ return {
59+ x : canvasPosition . x + displacementQty + positionDisplacement ,
60+ y : canvasPosition . y + positionDisplacement ,
61+ } ;
62+ } ;
63+
4764export const addComponentsToCanvas = async (
4865 page : Page ,
4966 components : string [ ] ,
@@ -58,25 +75,110 @@ export const addComponentsToCanvas = async (
5875 await component . scrollIntoViewIfNeeded ( ) ;
5976 const position = await getLocatorPosition ( component ) ;
6077
61- const targetPosition = (
62- displacementQty : number ,
63- multiplyFactor : number
64- ) => {
65- const positionDisplacement = displacementQty * ( multiplyFactor + 1 ) ;
66- return {
67- x : canvasPosition . x + displacementQty + positionDisplacement ,
68- y : canvasPosition . y + positionDisplacement ,
69- } ;
70- } ;
71-
72- await dragAndDrop ( page , position , targetPosition ( displacementQty , index ) ) ;
78+ const targetPosition = getTargetPosition (
79+ canvasPosition ,
80+ displacementQty ,
81+ index
82+ ) ;
83+ await dragAndDrop ( page , position , targetPosition ) ;
84+ }
85+ } ;
86+
87+ export const addComponentsWithDifferentCategoriesToCanvas = async (
88+ page : Page ,
89+ components : ComponentWithCategory [ ] ,
90+ displacementQty : number = 120
91+ ) => {
92+ // Handle empty array
93+ if ( components . length === 0 ) {
94+ return ;
95+ }
96+
97+ const stageCanvas = await page . locator ( '#konva-stage canvas' ) . nth ( 1 ) ;
98+ const canvasPosition = await stageCanvas . boundingBox ( ) ;
99+ if ( ! canvasPosition ) throw new Error ( 'No canvas found' ) ;
100+
101+ let currentCategory : string | undefined = undefined ;
102+
103+ for await ( const [ index , componentConfig ] of components . entries ( ) ) {
104+ try {
105+ // Change category only if it's different from current one
106+ if (
107+ componentConfig . category &&
108+ componentConfig . category !== currentCategory
109+ ) {
110+ const categoryButton = page . getByText ( componentConfig . category , {
111+ exact : true ,
112+ } ) ;
113+
114+ // Check if category exists before clicking
115+ await categoryButton . waitFor ( { state : 'visible' , timeout : 3000 } ) ;
116+ await categoryButton . click ( ) ;
117+
118+ // Wait a bit for the category change to take effect
119+ await page . waitForTimeout ( 500 ) ;
120+ currentCategory = componentConfig . category ;
121+ }
122+
123+ // Find component with better handling for duplicates
124+ let component = page . getByAltText ( componentConfig . name , { exact : true } ) ;
125+
126+ // Check if there are multiple elements with the same alt text
127+ const componentCount = await component . count ( ) ;
128+
129+ if ( componentCount > 1 ) {
130+ // Handle duplicates by selecting the first visible one in the current category context
131+ console . warn (
132+ `Multiple components found with name "${ componentConfig . name } ". Using first visible one.`
133+ ) ;
134+ component = component . first ( ) ;
135+ }
136+
137+ // Wait for component to be available
138+ await component . waitFor ( { state : 'visible' , timeout : 5000 } ) ;
139+ await component . scrollIntoViewIfNeeded ( ) ;
140+ const position = await getLocatorPosition ( component ) ;
141+
142+ const targetPosition = getTargetPosition (
143+ canvasPosition ,
144+ displacementQty ,
145+ index
146+ ) ;
147+ await dragAndDrop ( page , position , targetPosition ) ;
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+ }
73155 }
74156} ;
75157
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