@@ -43,47 +43,67 @@ export const waitForHoverOutline = async (options?: {
4343 await waitFor (
4444 ( ) => {
4545 const hoverOutline = document . querySelector (
46- "[data-testid='visual-builder__hover-outline'][style]"
47- ) ;
48- expect ( hoverOutline ) . not . toBeNull ( ) ;
46+ "[data-testid='visual-builder__hover-outline']"
47+ ) as HTMLElement | null ;
48+ if ( ! hoverOutline ) {
49+ throw new Error ( "Hover outline element not found" ) ;
50+ }
51+ // Check that style is set (either via attribute or style object)
52+ // CI environments can be slower, so check both attribute and style properties
53+ const styleAttr = hoverOutline . getAttribute ( "style" ) ;
54+ const hasStyleAttr = styleAttr && styleAttr . trim ( ) !== "" ;
55+ const hasStyleProps =
56+ hoverOutline . style . top &&
57+ hoverOutline . style . top !== "" &&
58+ hoverOutline . style . left &&
59+ hoverOutline . style . left !== "" ;
60+ if ( ! hasStyleAttr && ! hasStyleProps ) {
61+ throw new Error ( "Hover outline style not set" ) ;
62+ }
4963 } ,
5064 {
51- timeout : options ?. timeout ?? 2000 , // Reduced from 5s to 2s - mocks resolve immediately
52- interval : options ?. interval ?? 10 , // Faster polling: 10ms default
65+ timeout : options ?. timeout ?? 3000 , // Increased to 3s for CI - accounts for debounce (50ms) + async operations
66+ interval : options ?. interval ?? 20 , // Slightly slower polling for CI stability
5367 }
5468 ) ;
5569} ;
56-
57- export const waitForBuilderSDKToBeInitialized = async ( visualBuilderPostMessage : EventManager | undefined ) => {
70+
71+ export const waitForBuilderSDKToBeInitialized = async (
72+ visualBuilderPostMessage : EventManager | undefined
73+ ) => {
5874 await waitFor ( ( ) => {
5975 expect ( visualBuilderPostMessage ?. send ) . toBeCalledWith (
6076 VisualBuilderPostMessageEvents . INIT ,
6177 expect . any ( Object )
6278 ) ;
6379 } ) ;
64- }
80+ } ;
6581interface WaitForClickActionOptions {
6682 skipWaitForFieldType ?: boolean ;
6783}
68- export const triggerAndWaitForClickAction = async ( visualBuilderPostMessage : EventManager | undefined , element : HTMLElement , { skipWaitForFieldType} : WaitForClickActionOptions = { } ) => {
84+ export const triggerAndWaitForClickAction = async (
85+ visualBuilderPostMessage : EventManager | undefined ,
86+ element : HTMLElement ,
87+ { skipWaitForFieldType } : WaitForClickActionOptions = { }
88+ ) => {
6989 await waitForBuilderSDKToBeInitialized ( visualBuilderPostMessage ) ;
7090 await act ( async ( ) => {
7191 await fireEvent . click ( element ) ;
72- } )
73- if ( ! skipWaitForFieldType ) {
92+ } ) ;
93+ if ( ! skipWaitForFieldType ) {
7494 await waitFor ( ( ) => {
75- expect ( element ) . toHaveAttribute ( "data-cslp-field-type" )
76- } )
95+ expect ( element ) . toHaveAttribute ( "data-cslp-field-type" ) ;
96+ } ) ;
7797 }
78- }
98+ } ;
7999export const waitForToolbaxToBeVisible = async ( ) => {
80100 await waitFor ( ( ) => {
81101 const toolbar = document . querySelector (
82102 ".visual-builder__focused-toolbar__field-label-container"
83103 ) ;
84104 expect ( toolbar ) . not . toBeNull ( ) ;
85105 } ) ;
86- }
106+ } ;
87107
88108export const waitForCursorToBeVisible = async ( options ?: {
89109 timeout ?: number ;
@@ -117,8 +137,8 @@ export const waitForCursorIcon = async (
117137 expect ( customCursor ) . toHaveAttribute ( "data-icon" , icon ) ;
118138 } ,
119139 {
120- timeout : options ?. timeout ?? 1000 , // Reduced from 2s to 1s - mocks resolve immediately
121- interval : options ?. interval ?? 10 , // Faster polling: 10ms default
140+ timeout : options ?. timeout ?? 2000 , // Increased to 2s for CI - async operations can be slower
141+ interval : options ?. interval ?? 20 , // Slightly slower polling for CI stability
122142 }
123143 ) ;
124144} ;
@@ -129,17 +149,24 @@ const defaultRect = {
129149 bottom : 20 ,
130150 width : 10 ,
131151 height : 5 ,
132- }
133- export const mockGetBoundingClientRect = ( element : HTMLElement , rect = defaultRect ) => {
134- vi . spyOn ( element , "getBoundingClientRect" ) . mockImplementation ( ( ) => rect as DOMRect ) ;
135- }
152+ } ;
153+ export const mockGetBoundingClientRect = (
154+ element : HTMLElement ,
155+ rect = defaultRect
156+ ) => {
157+ vi . spyOn ( element , "getBoundingClientRect" ) . mockImplementation (
158+ ( ) => rect as DOMRect
159+ ) ;
160+ } ;
136161export const getElementBytestId = ( testId : string ) => {
137162 return document . querySelector ( `[data-testid="${ testId } "]` ) ;
138- }
139- export const asyncRender : ( componentChild : ComponentChild ) => ReturnType < typeof render > = async ( ...args ) => {
163+ } ;
164+ export const asyncRender : (
165+ componentChild : ComponentChild
166+ ) => ReturnType < typeof render > = async ( ...args ) => {
140167 let returnValue : ReturnType < typeof render > ;
141168 await act ( async ( ) => {
142169 returnValue = render ( ...args ) ;
143170 } ) ;
144171 return returnValue ;
145- }
172+ } ;
0 commit comments