test_connection_banner.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """Test case for displaying the connection banner when the websocket drops."""
  2. from typing import Generator
  3. import pytest
  4. from selenium.common.exceptions import NoSuchElementException
  5. from selenium.webdriver.common.by import By
  6. from reflex.testing import AppHarness, WebDriver
  7. def ConnectionBanner():
  8. """App with a connection banner."""
  9. import reflex as rx
  10. class State(rx.State):
  11. foo: int = 0
  12. def index():
  13. return rx.text("Hello World")
  14. app = rx.App(state=rx.State)
  15. app.add_page(index)
  16. @pytest.fixture()
  17. def connection_banner(tmp_path) -> Generator[AppHarness, None, None]:
  18. """Start ConnectionBanner app at tmp_path via AppHarness.
  19. Args:
  20. tmp_path: pytest tmp_path fixture
  21. Yields:
  22. running AppHarness instance
  23. """
  24. with AppHarness.create(
  25. root=tmp_path,
  26. app_source=ConnectionBanner, # type: ignore
  27. ) as harness:
  28. yield harness
  29. CONNECTION_ERROR_XPATH = "//*[ text() = 'Connection Error' ]"
  30. def has_error_modal(driver: WebDriver) -> bool:
  31. """Check if the connection error modal is displayed.
  32. Args:
  33. driver: Selenium webdriver instance.
  34. Returns:
  35. True if the modal is displayed, False otherwise.
  36. """
  37. try:
  38. driver.find_element(By.XPATH, CONNECTION_ERROR_XPATH)
  39. return True
  40. except NoSuchElementException:
  41. return False
  42. def test_connection_banner(connection_banner: AppHarness):
  43. """Test that the connection banner is displayed when the websocket drops.
  44. Args:
  45. connection_banner: AppHarness instance.
  46. """
  47. assert connection_banner.app_instance is not None
  48. assert connection_banner.backend is not None
  49. driver = connection_banner.frontend()
  50. connection_banner._poll_for(lambda: not has_error_modal(driver))
  51. # Get the backend port
  52. backend_port = connection_banner._poll_for_servers().getsockname()[1]
  53. # Kill the backend
  54. connection_banner.backend.should_exit = True
  55. if connection_banner.backend_thread is not None:
  56. connection_banner.backend_thread.join()
  57. # Error modal should now be displayed
  58. connection_banner._poll_for(lambda: has_error_modal(driver))
  59. # Bring the backend back up
  60. connection_banner._start_backend(port=backend_port)
  61. # Banner should be gone now
  62. connection_banner._poll_for(lambda: not has_error_modal(driver))