123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- """Integration tests for var operations."""
- import time
- from typing import Callable, Generator, TypeVar
- import pytest
- from selenium.webdriver.common.by import By
- from reflex.testing import AppHarness
- # pyright: reportOptionalMemberAccess=false, reportGeneralTypeIssues=false, reportUnknownMemberType=false
- def DynamicComponents():
- """App with var operations."""
- import reflex as rx
- class DynamicComponentsState(rx.State):
- value: int = 10
- button: rx.Component = rx.button(
- "Click me",
- custom_attrs={
- "id": "button",
- },
- )
- @rx.event
- def got_clicked(self):
- self.button = rx.button(
- "Clicked",
- custom_attrs={
- "id": "button",
- },
- )
- @rx.var
- def client_token_component(self) -> rx.Component:
- return rx.vstack(
- rx.el.input(
- custom_attrs={
- "id": "token",
- },
- value=self.router.session.client_token,
- is_read_only=True,
- ),
- rx.button(
- "Update",
- custom_attrs={
- "id": "update",
- },
- on_click=DynamicComponentsState.got_clicked,
- ),
- )
- app = rx.App()
- def factorial(n: int) -> int:
- if n == 0:
- return 1
- return n * factorial(n - 1)
- @app.add_page
- def index():
- return rx.vstack(
- DynamicComponentsState.client_token_component,
- DynamicComponentsState.button,
- rx.text(
- DynamicComponentsState._evaluate(
- lambda state: factorial(state.value), of_type=int
- ),
- id="factorial",
- ),
- )
- @pytest.fixture(scope="module")
- def dynamic_components(tmp_path_factory) -> Generator[AppHarness, None, None]:
- """Start VarOperations app at tmp_path via AppHarness.
- Args:
- tmp_path_factory: pytest tmp_path_factory fixture
- Yields:
- running AppHarness instance
- """
- with AppHarness.create(
- root=tmp_path_factory.mktemp("dynamic_components"),
- app_source=DynamicComponents,
- ) as harness:
- assert harness.app_instance is not None, "app is not running"
- yield harness
- T = TypeVar("T")
- def poll_for_result(
- f: Callable[[], T], exception=Exception, max_attempts=5, seconds_between_attempts=1
- ) -> T:
- """Poll for a result from a function.
- Args:
- f: function to call
- exception: exception to catch
- max_attempts: maximum number of attempts
- seconds_between_attempts: seconds to wait between
- Returns:
- Result of the function
- Raises:
- AssertionError: if the function does not return a value
- """
- attempts = 0
- while attempts < max_attempts:
- try:
- return f()
- except exception:
- attempts += 1
- time.sleep(seconds_between_attempts)
- raise AssertionError("Function did not return a value")
- @pytest.fixture
- def driver(dynamic_components: AppHarness):
- """Get an instance of the browser open to the dynamic components app.
- Args:
- dynamic_components: AppHarness for the dynamic components
- Yields:
- WebDriver instance.
- """
- driver = dynamic_components.frontend()
- try:
- token_input = poll_for_result(lambda: driver.find_element(By.ID, "token"))
- assert token_input
- # wait for the backend connection to send the token
- token = dynamic_components.poll_for_value(token_input)
- assert token is not None
- yield driver
- finally:
- driver.quit()
- def test_dynamic_components(driver, dynamic_components: AppHarness):
- """Test that the var operations produce the right results.
- Args:
- driver: selenium WebDriver open to the app
- dynamic_components: AppHarness for the dynamic components
- """
- button = poll_for_result(lambda: driver.find_element(By.ID, "button"))
- assert button
- assert button.text == "Click me"
- update_button = driver.find_element(By.ID, "update")
- assert update_button
- update_button.click()
- assert (
- dynamic_components.poll_for_content(button, exp_not_equal="Click me")
- == "Clicked"
- )
- factorial = poll_for_result(lambda: driver.find_element(By.ID, "factorial"))
- assert factorial
- assert factorial.text == "3628800"
|