@@ -109,6 +109,22 @@ async def yield_in_async_with_self(self):
109109 yield
110110 self .counter += 1
111111
112+ @rx .event
113+ async def disconnect_reconnect (self ):
114+ self .counter += 1
115+ yield rx .call_script ("socket.disconnect()" )
116+ await asyncio .sleep (0.5 )
117+ self .counter += 1
118+
119+ @rx .event (background = True )
120+ async def disconnect_reconnect_background (self ):
121+ async with self :
122+ self .counter += 1
123+ yield rx .call_script ("socket.disconnect()" )
124+ await asyncio .sleep (0.5 )
125+ async with self :
126+ self .counter += 1
127+
112128 class OtherState (rx .State ):
113129 @rx .event (background = True )
114130 async def get_other_state (self ):
@@ -134,6 +150,9 @@ def index() -> rx.Component:
134150 rx .input (
135151 id = "token" , value = State .router .session .client_token , is_read_only = True
136152 ),
153+ rx .input (
154+ id = "sid" , value = State .router .session .session_id , is_read_only = True
155+ ),
137156 rx .hstack (
138157 rx .heading (State .counter , id = "counter" ),
139158 rx .text (State .counter_async_cv , size = "1" , id = "counter-async-cv" ),
@@ -185,6 +204,16 @@ def index() -> rx.Component:
185204 on_click = State .yield_in_async_with_self ,
186205 id = "yield-in-async-with-self" ,
187206 ),
207+ rx .button (
208+ "Disconnect / Reconnect" ,
209+ on_click = State .disconnect_reconnect_background ,
210+ id = "disconnect-reconnect" ,
211+ ),
212+ rx .button (
213+ "Disconnect / Reconnect Background" ,
214+ on_click = State .disconnect_reconnect_background ,
215+ id = "disconnect-reconnect-background" ,
216+ ),
188217 rx .button ("Reset" , on_click = State .reset_counter , id = "reset" ),
189218 )
190219
@@ -395,3 +424,43 @@ def test_yield_in_async_with_self(
395424
396425 yield_in_async_with_self_button .click ()
397426 AppHarness .expect (lambda : counter .text == "2" , timeout = 5 )
427+
428+
429+ @pytest .mark .parametrize (
430+ "button_id" ,
431+ [
432+ "disconnect-reconnect" ,
433+ "disconnect-reconnect-background" ,
434+ ],
435+ )
436+ def test_disconnect_reconnect (
437+ background_task : AppHarness ,
438+ driver : WebDriver ,
439+ token : str ,
440+ button_id : str ,
441+ ):
442+ """Test that disconnecting and reconnecting works as expected.
443+
444+ Args:
445+ background_task: harness for BackgroundTask app.
446+ driver: WebDriver instance.
447+ token: The token for the connected client.
448+ button_id: The ID of the button to click.
449+ """
450+ counter = driver .find_element (By .ID , "counter" )
451+ button = driver .find_element (By .ID , button_id )
452+ increment_button = driver .find_element (By .ID , "increment" )
453+ sid_input = driver .find_element (By .ID , "sid" )
454+ sid = background_task .poll_for_value (sid_input , timeout = 5 )
455+ assert sid is not None
456+
457+ AppHarness .expect (lambda : counter .text == "0" , timeout = 5 )
458+ button .click ()
459+ AppHarness .expect (lambda : counter .text == "1" , timeout = 5 )
460+ increment_button .click ()
461+ # should get a new sid after the reconnect
462+ assert (
463+ background_task .poll_for_value (sid_input , timeout = 5 , exp_not_equal = sid ) != sid
464+ )
465+ # Final update should come through on the new websocket connection
466+ AppHarness .expect (lambda : counter .text == "3" , timeout = 5 )
0 commit comments