reflex/integration/test_login_flow.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

146 lines
3.9 KiB
Python

"""Integration tests for client side storage."""
from __future__ import annotations
from typing import Generator
import pytest
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver
from reflex.testing import AppHarness
from . import utils
def LoginSample():
"""Sample app for testing login/logout with LocalStorage var."""
import reflex as rx
class State(rx.State):
auth_token: str = rx.LocalStorage("")
def logout(self):
self.set_auth_token("")
def login(self):
self.set_auth_token("12345")
yield rx.redirect("/")
def index():
return rx.cond(
State.is_hydrated & State.auth_token, # type: ignore
rx.vstack(
rx.heading(State.auth_token, id="auth-token"),
rx.button("Logout", on_click=State.logout, id="logout"),
),
rx.button("Login", on_click=rx.redirect("/login"), id="login"),
)
def login():
return rx.vstack(
rx.button("Do it", on_click=State.login, id="doit"),
)
app = rx.App(state=rx.State)
app.add_page(index)
app.add_page(login)
@pytest.fixture(scope="module")
def login_sample(tmp_path_factory) -> Generator[AppHarness, None, None]:
"""Start LoginSample 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("login_sample"),
app_source=LoginSample, # type: ignore
) as harness:
yield harness
@pytest.fixture()
def driver(login_sample: AppHarness) -> Generator[WebDriver, None, None]:
"""Get an instance of the browser open to the login_sample app.
Args:
login_sample: harness for LoginSample app
Yields:
WebDriver instance.
"""
assert login_sample.app_instance is not None, "app is not running"
driver = login_sample.frontend()
try:
yield driver
finally:
driver.quit()
@pytest.fixture()
def local_storage(driver: WebDriver) -> Generator[utils.LocalStorage, None, None]:
"""Get an instance of the local storage helper.
Args:
driver: WebDriver instance.
Yields:
Local storage helper.
"""
ls = utils.LocalStorage(driver)
yield ls
ls.clear()
def test_login_flow(
login_sample: AppHarness, driver: WebDriver, local_storage: utils.LocalStorage
):
"""Test login flow.
Args:
login_sample: harness for LoginSample app.
driver: WebDriver instance.
local_storage: Local storage helper.
"""
assert login_sample.frontend_url is not None
local_storage.clear()
with pytest.raises(NoSuchElementException):
driver.find_element(By.ID, "auth-token")
login_button = driver.find_element(By.ID, "login")
login_sample.poll_for_content(login_button)
with utils.poll_for_navigation(driver):
login_button.click()
assert driver.current_url.endswith("/login/")
do_it_button = driver.find_element(By.ID, "doit")
with utils.poll_for_navigation(driver):
do_it_button.click()
assert driver.current_url == login_sample.frontend_url + "/"
def check_auth_token_header():
try:
auth_token_header = driver.find_element(By.ID, "auth-token")
except NoSuchElementException:
return False
return auth_token_header.text
assert login_sample._poll_for(check_auth_token_header) == "12345"
logout_button = driver.find_element(By.ID, "logout")
logout_button.click()
state_name = login_sample.get_full_state_name(["_state"])
assert login_sample._poll_for(
lambda: local_storage[f"{state_name}.auth_token"] == ""
)
with pytest.raises(NoSuchElementException):
driver.find_element(By.ID, "auth-token")