/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
e2e_playwright/st_toggle_test.py
242 строки
9 KB
Maya Barnes
Bind widgets to query params - `st.checkbox` & `st.toggle` (#13900)
11 фев 2026, 19:42
Не верифицирован
11 фев 2026, 19:42
e91dc7e
Код
Авторство
О чём код?
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re from playwright.sync_api import Page, expect from e2e_playwright.conftest import ( ImageCompareFunction, wait_for_app_loaded, wait_for_app_run, ) from e2e_playwright.shared.app_utils import ( check_top_level_class, click_toggle, expect_help_tooltip, expect_markdown, expect_prefixed_markdown, get_element_by_key, get_expander, get_toggle, ) TOGGLE_ELEMENTS = 19 def test_toggle_widget_display(themed_app: Page, assert_snapshot: ImageCompareFunction): """Test that st.toggle renders correctly.""" toggle_elements = themed_app.get_by_test_id("stCheckbox") expect(toggle_elements).to_have_count(TOGGLE_ELEMENTS) assert_snapshot(get_toggle(themed_app, "toggle 1 (True)"), name="st_toggle-true") assert_snapshot(get_toggle(themed_app, "toggle 2 (False)"), name="st_toggle-false") assert_snapshot( get_toggle(themed_app, re.compile(r"^toggle 3")), name="st_toggle-long_label", ) assert_snapshot( get_toggle(themed_app, "toggle 4 (with callback)"), name="st_toggle-callback", ) assert_snapshot( get_toggle(themed_app, "toggle 5 (False, disabled)"), name="st_toggle-false_disabled", ) assert_snapshot( get_toggle(themed_app, "toggle 6 (True, disabled)"), name="st_toggle-true_disabled", ) assert_snapshot( get_element_by_key(themed_app, "toggle_7"), name="st_toggle-hidden_label" ) assert_snapshot( get_element_by_key(themed_app, "toggle_8"), name="st_toggle-collapsed_label" ) assert_snapshot( get_element_by_key(themed_app, "toggle_9"), name="st_toggle-markdown_label" ) # Width examples assert_snapshot( get_toggle(themed_app, "toggle with content width"), name="st_toggle-width_content", ) assert_snapshot( get_toggle(themed_app, "toggle with stretch width"), name="st_toggle-width_stretch", ) assert_snapshot( get_toggle(themed_app, "toggle with 150px width"), name="st_toggle-width_150px", ) def test_toggle_initial_values(app: Page): """Test that st.toggle has the correct initial values.""" expect_markdown(app, "toggle 1 - value: True") expect_markdown(app, "toggle 2 - value: False") expect_markdown(app, "toggle 3 - value: False") expect_markdown(app, "toggle 4 - value: False") expect_markdown(app, "toggle 4 - clicked: False") expect_markdown(app, "toggle 5 - value: False") expect_markdown(app, "toggle 6 - value: True") expect_markdown(app, "toggle 7 - value: False") expect_markdown(app, "toggle 8 - value: False") def test_toggle_values_on_click(app: Page): """Test that st.toggle updates values correctly when user clicks.""" # Click only the toggles that affect the displayed markdown values click_toggle(app, "toggle 1 (True)") click_toggle(app, "toggle 2 (False)") click_toggle(app, re.compile(r"^toggle 3")) click_toggle(app, "toggle 4 (with callback)") # Hidden/collapsed labels: click via key wrapper get_element_by_key(app, "toggle_7").locator("label").click() wait_for_app_run(app) get_element_by_key(app, "toggle_8").locator("label").click() wait_for_app_run(app) expect_markdown(app, "toggle 1 - value: False") expect_markdown(app, "toggle 2 - value: True") expect_markdown(app, "toggle 3 - value: True") expect_markdown(app, "toggle 4 - value: True") expect_markdown(app, "toggle 4 - clicked: True") expect_markdown(app, "toggle 5 - value: False") expect_markdown(app, "toggle 6 - value: True") expect_markdown(app, "toggle 7 - value: True") expect_markdown(app, "toggle 8 - value: True") def test_grouped_toggles_height(app: Page, assert_snapshot: ImageCompareFunction): """Test that grouped toggles have the correct height.""" expander_details = get_expander(app, "Grouped toggles").get_by_test_id( "stExpanderDetails" ) expect(expander_details.get_by_test_id("stCheckbox")).to_have_count(3) assert_snapshot(expander_details, name="st_toggle-grouped_styling") expect(get_toggle(expander_details, "toggle group - 1")).to_have_css( "height", "24px" ) def test_check_top_level_class(app: Page): """Check that the top level class is correctly set.""" check_top_level_class(app, "stCheckbox") def test_custom_css_class_via_key(app: Page): """Test that the element can have a custom css class via the key argument.""" expect(get_element_by_key(app, "toggle4")).to_be_visible() def test_dynamic_toggle_props(app: Page, assert_snapshot: ImageCompareFunction): """Test that the toggle can be updated dynamically.""" dynamic_toggle = get_element_by_key(app, "dynamic_toggle_with_key") expect(dynamic_toggle).to_be_visible() expect(dynamic_toggle).to_contain_text("Initial dynamic toggle") # Check that the initial toggle state is True expect_prefixed_markdown(app, "Initial toggle state:", "True") assert_snapshot(dynamic_toggle, name="st_toggle-dynamic_initial") # Check that the help tooltip is correct: expect_help_tooltip(app, dynamic_toggle, "initial help") # Click toggle -> state is False click_toggle(app, "Initial dynamic toggle") expect_prefixed_markdown(app, "Initial toggle state:", "False") # Click toggle again -> state is True click_toggle(app, "Initial dynamic toggle") expect_prefixed_markdown(app, "Initial toggle state:", "True") # Click the toggle to update the toggle props click_toggle(app, "Update toggle props") # new toggle is visible: expect(dynamic_toggle).to_contain_text("Updated dynamic toggle") # Check that the updated toggle state is still True. expect_prefixed_markdown(app, "Updated toggle state:", "True") dynamic_toggle.scroll_into_view_if_needed() assert_snapshot(dynamic_toggle, name="st_toggle-dynamic_updated") # Check that the help tooltip is correct: expect_help_tooltip(app, dynamic_toggle, "updated help") # Click the toggle click_toggle(app, "Updated dynamic toggle") expect_prefixed_markdown(app, "Updated toggle state:", "False") def test_toggle_query_param_seeding(page: Page, app_port: int): """Test that toggle value can be seeded from URL query params.""" page.goto(f"http://localhost:{app_port}/?bound_toggle=true") wait_for_app_loaded(page) expect_prefixed_markdown(page, "bound toggle value:", "True") def test_toggle_query_param_updates_url(app: Page): """Test that clicking a bound toggle updates the URL.""" # Initially default False, no query param in URL expect_prefixed_markdown(app, "bound toggle value:", "False") expect(app).not_to_have_url(re.compile(r"bound_toggle=")) # Click the toggle -> True click_toggle(app, "Bound toggle (default False)") expect_prefixed_markdown(app, "bound toggle value:", "True") # URL should now contain the query param expect(app).to_have_url(re.compile(r"bound_toggle=true")) # Click again -> back to default False click_toggle(app, "Bound toggle (default False)") expect_prefixed_markdown(app, "bound toggle value:", "False") # Query param should be removed since value is back to default expect(app).not_to_have_url(re.compile(r"bound_toggle=")) def test_toggle_query_param_default_true(page: Page, app_port: int): """Test toggle with default True: seeding and param removal.""" # Load app with query param overriding the True default page.goto(f"http://localhost:{app_port}/?bound_toggle_true=false") wait_for_app_loaded(page) # Toggle should be off (overriding True default) expect_prefixed_markdown(page, "bound toggle true value:", "False") # Click to re-toggle (back to default True) click_toggle(page, "Bound toggle (default True)") expect_prefixed_markdown(page, "bound toggle true value:", "True") # Query param should be removed since value is back to default (True) expect(page).not_to_have_url(re.compile(r"bound_toggle_true")) def test_toggle_query_param_invalid_value(page: Page, app_port: int): """Test that invalid URL values are cleared and widget uses default.""" page.goto(f"http://localhost:{app_port}/?bound_toggle=invalid") wait_for_app_loaded(page) # Toggle should use default (False), and invalid param should be cleared expect_prefixed_markdown(page, "bound toggle value:", "False") expect(page).not_to_have_url(re.compile(r"bound_toggle="))