Explorar el Código

Add AppHarness for form submit (#1571)

Thomas Brandého hace 1 año
padre
commit
59132e533b
Se han modificado 1 ficheros con 136 adiciones y 0 borrados
  1. 136 0
      integration/test_form_submit.py

+ 136 - 0
integration/test_form_submit.py

@@ -0,0 +1,136 @@
+"""Integration tests for forms."""
+import time
+from typing import Generator
+
+import pytest
+from selenium.webdriver.common.by import By
+from selenium.webdriver.common.keys import Keys
+
+from reflex.testing import AppHarness
+
+
+def FormSubmit():
+    """App with a form using on_submit."""
+    import reflex as rx
+
+    class FormState(rx.State):
+        form_data: dict = {}
+
+        def form_submit(self, form_data: dict):
+            self.form_data = form_data
+
+    app = rx.App(state=FormState)
+
+    @app.add_page
+    def index():
+        return rx.vstack(
+            rx.form(
+                rx.vstack(
+                    rx.input(id="name_input"),
+                    rx.hstack(rx.pin_input(length=4, id="pin_input")),
+                    rx.number_input(id="number_input"),
+                    rx.checkbox(id="bool_input"),
+                    rx.switch(id="bool_input2"),
+                    rx.slider(id="slider_input"),
+                    rx.range_slider(id="range_input"),
+                    rx.radio_group(["option1", "option2"], id="radio_input"),
+                    rx.select(["option1", "option2"], id="select_input"),
+                    rx.text_area(id="text_area_input"),
+                    rx.button("Submit", type_="submit"),
+                ),
+                on_submit=FormState.form_submit,
+            ),
+            rx.spacer(),
+            height="100vh",
+        )
+
+    app.compile()
+
+
+@pytest.fixture(scope="session")
+def form_submit(tmp_path_factory) -> Generator[AppHarness, None, None]:
+    """Start FormSubmit 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("form_submit"),
+        app_source=FormSubmit,  # type: ignore
+    ) as harness:
+        assert harness.app_instance is not None, "app is not running"
+        yield harness
+
+
+@pytest.fixture
+def driver(form_submit: AppHarness):
+    """GEt an instance of the browser open to the form_submit app.
+
+    Args:
+        form_submit: harness for ServerSideEvent app
+
+    Yields:
+        WebDriver instance.
+    """
+    driver = form_submit.frontend()
+    try:
+        assert form_submit.poll_for_clients()
+        yield driver
+    finally:
+        driver.quit()
+
+
+def test_submit(driver, form_submit: AppHarness):
+    """Fill a form with various different output, submit it to backend and verify
+    the output.
+
+    Args:
+        driver: selenium WebDriver open to the app
+        form_submit: harness for FormSubmit app
+    """
+    assert form_submit.app_instance is not None, "app is not running"
+    _, backend_state = list(form_submit.app_instance.state_manager.states.items())[0]
+
+    name_input = driver.find_element(By.ID, "name_input")
+    name_input.send_keys("foo")
+
+    pin_inputs = driver.find_elements(By.CLASS_NAME, "chakra-pin-input")
+    pin_values = ["8", "1", "6", "4"]
+    for i, pin_input in enumerate(pin_inputs):
+        pin_input.send_keys(pin_values[i])
+
+    number_input = driver.find_element(By.CLASS_NAME, "chakra-numberinput")
+    buttons = number_input.find_elements(By.XPATH, "//div[@role='button']")
+    for _ in range(3):
+        buttons[1].click()
+
+    checkbox_input = driver.find_element(By.CLASS_NAME, "chakra-checkbox__control")
+    checkbox_input.click()
+
+    switch_input = driver.find_element(By.CLASS_NAME, "chakra-switch__track")
+    switch_input.click()
+
+    radio_buttons = driver.find_elements(By.CLASS_NAME, "chakra-radio__control")
+    radio_buttons[1].click()
+
+    textarea_input = driver.find_element(By.CLASS_NAME, "chakra-textarea")
+    textarea_input.send_keys("Some", Keys.ENTER, "Text")
+
+    time.sleep(1)
+
+    submit_input = driver.find_element(By.CLASS_NAME, "chakra-button")
+    submit_input.click()
+
+    assert backend_state.form_data["name_input"] == "foo"
+    assert backend_state.form_data["pin_input"] == pin_values
+    assert backend_state.form_data["number_input"] == "-3"
+    assert backend_state.form_data["bool_input"] is True
+    assert backend_state.form_data["bool_input2"] is True
+    assert backend_state.form_data["slider_input"] == "50"
+    assert backend_state.form_data["range_input"] == ["25", "75"]
+    assert backend_state.form_data["radio_input"] == "option2"
+    assert backend_state.form_data["select_input"] == "option1"
+    assert backend_state.form_data["text_area_input"] == "Some\nText"