Skip to content

Commit

Permalink
add basic integration test for dynamic components (#3990)
Browse files Browse the repository at this point in the history
* add basic integration test

* fix docstrings

* dang it darglint
  • Loading branch information
adhami3310 committed Sep 25, 2024
1 parent 5e738fd commit fc5d352
Showing 1 changed file with 152 additions and 0 deletions.
152 changes: 152 additions & 0 deletions integration/test_dynamic_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"""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):
button: rx.Component = rx.button(
"Click me",
custom_attrs={
"id": "button",
},
)

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()

@app.add_page
def index():
return rx.vstack(
DynamicComponentsState.client_token_component,
DynamicComponentsState.button,
)


@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, # type: ignore
) 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"
)

0 comments on commit fc5d352

Please sign in to comment.