reflex/integration/test_exception_handlers.py
benedikt-bartscher 3039b54a75
add module prefix to generated state names (#3214)
* add module prefix to state names

* fix state names in test_app

* update state names in test_state

* fix state names in test_var

* fix state name in test_component

* fix state names in test_format

* fix state names in test_foreach

* fix state names in test_cond

* fix state names in test_datatable

* fix state names in test_colors

* fix state names in test_script

* fix state names in test_match

* fix state name in event1 fixture

* fix pyright and darglint

* fix state names in state_tree

* fix state names in redis only test

* fix state names in test_client_storage

* fix state name in js template

* add `get_state_name` and `get_full_state_name` helpers for `AppHarness`

* fix state names in test_dynamic_routes

* use new state name helpers in test_client_storage

* fix state names in test_event_actions

* fix state names in test_event_chain

* fix state names in test_upload

* fix state name in test_login_flow

* fix state names in test_input

* fix state names in test_form_submit

* ruff

* validate state module names

* wtf is going on here?

* remove comments leftover from refactoring

* adjust new test_add_style_embedded_vars

* fix state name in state.js

* fix integration/test_client_state.py

new SessionStorage feature was added with more full state names that need to be formatted in

* fix pre-commit issues in test_client_storage.py

* adjust test_computed_vars

* adjust safe-guards

* fix redis tests with new exception state

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-11 11:13:57 -07:00

155 lines
4.0 KiB
Python

"""Integration tests for event exception handlers."""
from __future__ import annotations
import time
from typing import Generator, Type
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from reflex.testing import AppHarness
def TestApp():
"""A test app for event exception handler integration."""
import reflex as rx
class TestAppConfig(rx.Config):
"""Config for the TestApp app."""
pass
class TestAppState(rx.State):
"""State for the TestApp app."""
def divide_by_number(self, number: int):
"""Divide by number and print the result.
Args:
number: number to divide by
"""
print(1 / number)
app = rx.App(state=rx.State)
@app.add_page
def index():
return rx.vstack(
rx.button(
"induce_frontend_error",
on_click=rx.call_script("induce_frontend_error()"),
id="induce-frontend-error-btn",
),
rx.button(
"induce_backend_error",
on_click=lambda: TestAppState.divide_by_number(0), # type: ignore
id="induce-backend-error-btn",
),
)
@pytest.fixture(scope="module")
def test_app(
app_harness_env: Type[AppHarness], tmp_path_factory
) -> Generator[AppHarness, None, None]:
"""Start TestApp app at tmp_path via AppHarness.
Args:
app_harness_env: either AppHarness (dev) or AppHarnessProd (prod)
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
with app_harness_env.create(
root=tmp_path_factory.mktemp("test_app"),
app_name=f"testapp_{app_harness_env.__name__.lower()}",
app_source=TestApp, # type: ignore
) as harness:
yield harness
@pytest.fixture
def driver(test_app: AppHarness) -> Generator[WebDriver, None, None]:
"""Get an instance of the browser open to the test_app app.
Args:
test_app: harness for TestApp app
Yields:
WebDriver instance.
"""
assert test_app.app_instance is not None, "app is not running"
driver = test_app.frontend()
try:
yield driver
finally:
driver.quit()
def test_frontend_exception_handler_during_runtime(
driver: WebDriver,
capsys,
):
"""Test calling frontend exception handler during runtime.
We send an event containing a call to a non-existent function in the frontend.
This should trigger the default frontend exception handler.
Args:
driver: WebDriver instance.
capsys: pytest fixture for capturing stdout and stderr.
"""
reset_button = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.ID, "induce-frontend-error-btn"))
)
reset_button.click()
# Wait for the error to be logged
time.sleep(2)
captured_default_handler_output = capsys.readouterr()
assert (
"induce_frontend_error" in captured_default_handler_output.out
and "ReferenceError" in captured_default_handler_output.out
)
def test_backend_exception_handler_during_runtime(
driver: WebDriver,
capsys,
):
"""Test calling backend exception handler during runtime.
We invoke TestAppState.divide_by_zero to induce backend error.
This should trigger the default backend exception handler.
Args:
driver: WebDriver instance.
capsys: pytest fixture for capturing stdout and stderr.
"""
reset_button = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.ID, "induce-backend-error-btn"))
)
reset_button.click()
# Wait for the error to be logged
time.sleep(2)
captured_default_handler_output = capsys.readouterr()
assert (
"divide_by_number" in captured_default_handler_output.out
and "ZeroDivisionError" in captured_default_handler_output.out
)