@@ -817,14 +817,17 @@ describe('BackendWebSocketService', () => {
817817 it ( 'should skip connect when reconnect timer is already scheduled' , async ( ) => {
818818 await withService (
819819 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
820+ // Mock Math.random to make Cockatiel's jitter deterministic
821+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
822+
820823 // Connect successfully first
821824 await service . connect ( ) ;
822825
823826 const mockWs = getMockWebSocket ( ) ;
824827
825828 // Simulate unexpected close to trigger scheduleReconnect
826829 mockWs . simulateClose ( 1006 , 'Abnormal closure' ) ;
827- await completeAsyncOperations ( 10 ) ;
830+ await completeAsyncOperations ( 0 ) ;
828831
829832 // Verify reconnect timer is scheduled
830833 const attemptsBefore = service . getConnectionInfo ( ) . reconnectAttempts ;
@@ -894,14 +897,22 @@ describe('BackendWebSocketService', () => {
894897 await withService (
895898 { mockWebSocketOptions : { autoConnect : false } } ,
896899 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
900+ // Mock Math.random to make Cockatiel's jitter deterministic
901+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
902+
897903 // eslint-disable-next-line @typescript-eslint/no-floating-promises
898904 service . connect ( ) ;
899905 await completeAsyncOperations ( 10 ) ;
900906
901- // Close during connection phase
907+ // Verify we're in CONNECTING state
902908 const mockWs = getMockWebSocket ( ) ;
909+ expect ( service . getConnectionInfo ( ) . state ) . toBe (
910+ WebSocketState . CONNECTING ,
911+ ) ;
912+
913+ // Close during connection phase
903914 mockWs . simulateClose ( 1006 , 'Connection failed' ) ;
904- await completeAsyncOperations ( 10 ) ;
915+ await completeAsyncOperations ( 0 ) ;
905916
906917 // Should schedule reconnect and be in ERROR state
907918 expect ( service . getConnectionInfo ( ) . state ) . toBe ( WebSocketState . ERROR ) ;
@@ -916,6 +927,9 @@ describe('BackendWebSocketService', () => {
916927 mockWebSocketOptions : { autoConnect : false } ,
917928 } ,
918929 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
930+ // Mock Math.random to make Cockatiel's jitter deterministic
931+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
932+
919933 // Start connection (this sets connectionTimeout)
920934 // eslint-disable-next-line @typescript-eslint/no-floating-promises
921935 service . connect ( ) ;
@@ -939,7 +953,7 @@ describe('BackendWebSocketService', () => {
939953 // Since state is ERROR (not CONNECTING), onclose will call handleClose
940954 // which will clear connectionTimeout
941955 mockWs . simulateClose ( 1006 , 'Close after timeout' ) ;
942- await completeAsyncOperations ( 10 ) ;
956+ await completeAsyncOperations ( 0 ) ;
943957
944958 // State should still be ERROR or DISCONNECTED
945959 expect ( [ WebSocketState . ERROR , WebSocketState . DISCONNECTED ] ) . toContain (
@@ -952,6 +966,9 @@ describe('BackendWebSocketService', () => {
952966 it ( 'should not schedule multiple reconnects when scheduleReconnect called multiple times' , async ( ) => {
953967 await withService (
954968 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
969+ // Mock Math.random to make Cockatiel's jitter deterministic
970+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
971+
955972 await service . connect ( ) ;
956973 expect ( service . getConnectionInfo ( ) . state ) . toBe (
957974 WebSocketState . CONNECTED ,
@@ -961,15 +978,15 @@ describe('BackendWebSocketService', () => {
961978
962979 // First close to trigger scheduleReconnect
963980 mockWs . simulateClose ( 1006 , 'Connection lost' ) ;
964- await completeAsyncOperations ( 10 ) ;
981+ await completeAsyncOperations ( 0 ) ;
965982
966983 const attemptsBefore = service . getConnectionInfo ( ) . reconnectAttempts ;
967984 expect ( attemptsBefore ) . toBeGreaterThan ( 0 ) ;
968985
969986 // Second close should trigger scheduleReconnect again,
970987 // but it should return early since timer already exists
971988 mockWs . simulateClose ( 1006 , 'Connection lost again' ) ;
972- await completeAsyncOperations ( 10 ) ;
989+ await completeAsyncOperations ( 0 ) ;
973990
974991 // Attempts should not have increased again due to idempotency
975992 expect ( service . getConnectionInfo ( ) . reconnectAttempts ) . toBe (
@@ -987,6 +1004,9 @@ describe('BackendWebSocketService', () => {
9871004 it ( 'should force reconnection and schedule connect' , async ( ) => {
9881005 await withService (
9891006 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
1007+ // Mock Math.random to make Cockatiel's jitter deterministic
1008+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
1009+
9901010 await service . connect ( ) ;
9911011 expect ( service . getConnectionInfo ( ) . state ) . toBe (
9921012 WebSocketState . CONNECTED ,
@@ -1001,7 +1021,7 @@ describe('BackendWebSocketService', () => {
10011021
10021022 // Force reconnection
10031023 await service . forceReconnection ( ) ;
1004- await completeAsyncOperations ( 10 ) ;
1024+ await completeAsyncOperations ( 0 ) ;
10051025
10061026 // Should be disconnected after forceReconnection
10071027 expect ( service . getConnectionInfo ( ) . state ) . toBe (
@@ -1018,14 +1038,17 @@ describe('BackendWebSocketService', () => {
10181038 await withService (
10191039 { mockWebSocketOptions : { autoConnect : false } } ,
10201040 async ( { service, getMockWebSocket, completeAsyncOperations } ) => {
1041+ // Mock Math.random to make Cockatiel's jitter deterministic
1042+ jest . spyOn ( Math , 'random' ) . mockReturnValue ( 0 ) ;
1043+
10211044 // Trigger a connection failure to schedule a reconnect
10221045 // eslint-disable-next-line @typescript-eslint/no-floating-promises
10231046 service . connect ( ) ;
10241047 await completeAsyncOperations ( 10 ) ;
10251048
10261049 const mockWs = getMockWebSocket ( ) ;
10271050 mockWs . simulateError ( ) ;
1028- await completeAsyncOperations ( 10 ) ;
1051+ await completeAsyncOperations ( 0 ) ;
10291052
10301053 const attemptsBefore = service . getConnectionInfo ( ) . reconnectAttempts ;
10311054
0 commit comments