1212from selenium .webdriver .support import expected_conditions as EC
1313from selenium .webdriver .support .wait import WebDriverWait
1414
15+ from reflex .state import BaseState
1516from reflex .testing import AppHarness , WebDriver
1617
1718
@@ -242,6 +243,12 @@ def token(event_action: AppHarness, driver: WebDriver) -> str:
242243 return token
243244
244245
246+ async def _backend_state (app : AppHarness , token : str ) -> BaseState :
247+ state_name = app .get_state_name ("_event_action_state" )
248+ state_full_name = app .get_full_state_name (["_event_action_state" ])
249+ return (await app .get_state (f"{ token } _{ state_full_name } " )).substates [state_name ]
250+
251+
245252@pytest .fixture
246253def poll_for_order (
247254 event_action : AppHarness , token : str
@@ -255,18 +262,13 @@ def poll_for_order(
255262 Returns:
256263 An async function that polls for the order list to match the expected order.
257264 """
258- state_name = event_action .get_state_name ("_event_action_state" )
259- state_full_name = event_action .get_full_state_name (["_event_action_state" ])
260265
261266 async def _poll_for_order (exp_order : list [str ]):
262- async def _backend_state ():
263- return await event_action .get_state (f"{ token } _{ state_full_name } " )
264-
265267 async def _check ():
266- return (await _backend_state ()). substates [ state_name ] .order == exp_order
268+ return (await _backend_state (event_action , token )) .order == exp_order
267269
268270 await AppHarness ._poll_for_async (_check )
269- assert (await _backend_state ()). substates [ state_name ] .order == exp_order
271+ assert (await _backend_state (event_action , token )) .order == exp_order
270272
271273 return _poll_for_order
272274
@@ -328,17 +330,18 @@ async def test_event_actions(
328330 assert driver .current_url == prev_url
329331
330332
331- @pytest .mark .usefixtures ("token" )
332333@pytest .mark .asyncio
333334async def test_event_actions_throttle_debounce (
335+ event_action : AppHarness ,
334336 driver : WebDriver ,
335- poll_for_order : Callable [[ list [ str ]], Coroutine [ None , None , None ]] ,
337+ token : str ,
336338):
337339 """Click buttons with debounce and throttle and assert on fired events.
338340
339341 Args:
342+ event_action: harness for TestEventAction app.
340343 driver: WebDriver instance.
341- poll_for_order: function that polls for the order list to match the expected order .
344+ token: The client_token associated with the driver browser .
342345 """
343346 btn_throttle = driver .find_element (By .ID , "btn-throttle" )
344347 assert btn_throttle
@@ -352,13 +355,23 @@ async def test_event_actions_throttle_debounce(
352355 btn_throttle .click ()
353356 btn_debounce .click ()
354357
355- try :
356- await poll_for_order (["on_click_throttle" ] * exp_events + ["on_click_debounce" ])
357- except AssertionError :
358- # Sometimes the last event gets throttled due to race, this is okay.
359- await poll_for_order (
360- ["on_click_throttle" ] * (exp_events - 1 ) + ["on_click_debounce" ]
361- )
358+ # Wait until the debounce event shows up
359+ async def _debounce_received ():
360+ state = await _backend_state (event_action , token )
361+ return state .order and state .order [- 1 ] == "on_click_debounce"
362+
363+ await AppHarness ._poll_for_async (_debounce_received )
364+
365+ # This test is inherently racy, so ensure the `on_click_throttle` event is fired approximately the expected number of times.
366+ final_event_order = (await _backend_state (event_action , token )).order
367+ n_on_click_throttle_received = final_event_order .count ("on_click_throttle" )
368+ print (
369+ f"Expected ~{ exp_events } on_click_throttle events, received { n_on_click_throttle_received } "
370+ )
371+ assert exp_events - 2 <= n_on_click_throttle_received <= exp_events + 1
372+ assert final_event_order == ["on_click_throttle" ] * n_on_click_throttle_received + [
373+ "on_click_debounce"
374+ ]
362375
363376
364377@pytest .mark .usefixtures ("token" )
0 commit comments