@@ -5,6 +5,11 @@ export interface Position {
5
5
y : number ;
6
6
}
7
7
8
+ export interface ComponentWithCategory {
9
+ name : string ;
10
+ category ?: string ;
11
+ }
12
+
8
13
export const getLocatorPosition = async (
9
14
locator : Locator
10
15
) : Promise < Position > => {
@@ -44,6 +49,18 @@ export const dragAndDrop = async (
44
49
await page . mouse . up ( ) ;
45
50
} ;
46
51
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
+
47
64
export const addComponentsToCanvas = async (
48
65
page : Page ,
49
66
components : string [ ] ,
@@ -58,25 +75,110 @@ export const addComponentsToCanvas = async (
58
75
await component . scrollIntoViewIfNeeded ( ) ;
59
76
const position = await getLocatorPosition ( component ) ;
60
77
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
+ }
73
155
}
74
156
} ;
75
157
76
158
export const getShapePosition = async ( shape : Group ) : Promise < Position > => {
77
159
return { x : shape ?. attrs . x , y : shape ?. attrs . y } ;
78
160
} ;
79
161
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
+
80
182
export const moveSelected = (
81
183
page : Page ,
82
184
direction : string ,
0 commit comments