/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
e2e_playwright/st_time_input_test.py
316 строк
11 KB
Ken McGrady
Update copyright header to 2026 (#13491)
02 янв 2026, 16:21
Не верифицирован
02 янв 2026, 16:21
374540a
Код
Авторство
О чём код?
# 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. from __future__ import annotations import re from playwright.sync_api import Page, expect from e2e_playwright.conftest import ImageCompareFunction, wait_for_app_loaded 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_time_input, ) from e2e_playwright.shared.theme_utils import apply_theme_via_window NUM_TIME_INPUTS = 13 def test_time_input_widget_rendering( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Test that the time input widgets are correctly rendered via screenshot matching.""" time_input_widgets = themed_app.get_by_test_id("stTimeInput") expect(time_input_widgets).to_have_count(NUM_TIME_INPUTS) assert_snapshot( get_time_input(themed_app, "Time input 1 (8:45)"), name="st_time_input-8_45" ) assert_snapshot( get_time_input(themed_app, "Time input 2 (21:15, help)"), name="st_time_input-21_15_help", ) assert_snapshot( get_time_input(themed_app, "Time input 3 (disabled)"), name="st_time_input-disabled", ) assert_snapshot( get_time_input(themed_app, "Time input 4 (hidden label)"), name="st_time_input-hidden_label", ) assert_snapshot( get_time_input(themed_app, "Time input 5 (collapsed label)"), name="st_time_input-collapsed_label", ) assert_snapshot( get_time_input(themed_app, "Time input 6 (with callback)"), name="st_time_input-callback", ) assert_snapshot( get_time_input(themed_app, "Time input 7 (step=60)"), name="st_time_input-step_60", ) assert_snapshot( get_time_input(themed_app, "Time input 8 (empty)"), name="st_time_input-empty" ) assert_snapshot( get_time_input(themed_app, "Time input 9 (empty, from state)"), name="st_time_input-value_from_state", ) assert_snapshot( get_time_input( themed_app, re.compile(r"^Time input 10"), ), name="st_time_input-markdown_label", ) assert_snapshot( get_time_input(themed_app, "Time input 11 (width=200px)"), name="st_time_input-width_200px", ) assert_snapshot( get_time_input(themed_app, "Time input 12 (width='stretch')"), name="st_time_input-width_stretch", ) def test_help_tooltip_works(app: Page): element_with_help = get_time_input(app, "Time input 2 (21:15, help)") expect_help_tooltip(app, element_with_help, "Help text") def test_time_input_has_correct_initial_values(app: Page): """Test that st.time_input returns the correct initial values.""" expect_markdown(app, "Value 1: 08:45:00") expect_markdown(app, "Value 2: 21:15:00") expect_markdown(app, "Value 3: 08:45:00") expect_markdown(app, "Value 4: 08:45:00") expect_markdown(app, "Value 5: 08:45:00") expect_markdown(app, "Value 6: 08:45:00") expect_markdown(app, "time input changed: False") expect_markdown(app, "Value 7: 08:45:00") expect_markdown(app, "Value 8: None") expect_markdown(app, "Value 9: 08:50:00") def test_handles_time_selection(app: Page, assert_snapshot: ImageCompareFunction): """Test that selection of a time via the dropdown works correctly.""" get_time_input(app, "Time input 1 (8:45)").locator("input").click() # Take a snapshot of the time selection dropdown: selection_dropdown = app.locator('[data-baseweb="popover"]').first assert_snapshot(selection_dropdown, name="st_time_input-selection_dropdown") # Select the first option: selection_dropdown.get_by_text("00:00").first.click() # Check that selection worked: expect_markdown(app, "Value 1: 00:00:00") def test_correct_menu_font_colors( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Test that it uses the correct colors in the popover menu.""" get_time_input(themed_app, "Time input 1 (8:45)").locator("input").click() # Take a snapshot of the time selection dropdown: selection_dropdown = themed_app.locator('[data-baseweb="popover"]').first # Hover over another option: selection_dropdown.get_by_text("08:30").hover() # Take a screenshot assert_snapshot(selection_dropdown, name="st_time_input-menu_colors") def test_handles_step_correctly(app: Page, assert_snapshot: ImageCompareFunction): """Test that the step parameter is correctly applied.""" get_time_input(app, "Time input 7 (step=60)").locator("input").click() # Take a snapshot of the time selection dropdown: selection_dropdown = app.locator('[data-baseweb="popover"]').first assert_snapshot(selection_dropdown, name="st_time_input-step_60_dropdown") # Select the second option: selection_dropdown.get_by_text("00:01").first.click() # Check that selection worked: expect_markdown(app, "Value 7: 00:01:00") def test_handles_time_selection_via_typing(app: Page): """Test that selection of a time via typing works correctly.""" time_input_field = get_time_input(app, "Time input 1 (8:45)").locator("input") # Type an option: time_input_field.type("00:15") time_input_field.press("Enter") # Check that selection worked: expect_markdown(app, "Value 1: 00:15:00") # Type an another option that doesn't exist in the dropdown: time_input_field.type("00:16") time_input_field.press("Enter") # Check that selection worked: expect_markdown(app, "Value 1: 00:16:00") def test_empty_time_input_behaves_correctly( app: Page, assert_snapshot: ImageCompareFunction ): """Test that st.time_input behaves correctly when empty (no initial value).""" empty_time_input = get_time_input(app, "Time input 8 (empty)") empty_time_input_field = empty_time_input.locator("input") # Type an option: empty_time_input_field.type("00:15") empty_time_input_field.press("Enter") expect_markdown(app, "Value 8: 00:15:00") assert_snapshot(empty_time_input, name="st_time_input-clearable_input") # Clear the input: empty_time_input.get_by_test_id("stTimeInputClearButton").click() # Should be empty again: expect_markdown(app, "Value 8: None") def test_keeps_value_on_selection_close(app: Page): """Test that the selection is kept when the dropdown is closed.""" get_time_input(app, "Time input 1 (8:45)").locator("input").click() # Check if popover is visible: expect(app.locator('[data-baseweb="popover"]').first).to_be_visible() # Click outside to close the dropdown: app.get_by_test_id("stApp").click(position={"x": 0, "y": 0}) # Check if value is still initial value: expect_markdown(app, "Value 1: 08:45:00") def test_handles_callback_on_change_correctly(app: Page): """Test that it correctly calls the callback on change.""" # Check initial state: expect_markdown(app, "Value 6: 08:45:00") expect_markdown(app, "time input changed: False") get_time_input(app, "Time input 6 (with callback)").locator("input").click() # Select last option: time_dropdown = app.locator('[data-baseweb="popover"]').first time_dropdown.get_by_text("00:00").first.click() # Check that selection worked: expect_markdown(app, "Value 6: 00:00:00") expect_markdown(app, "time input changed: True") # Change different input to trigger delta path change empty_time_input_field = get_time_input(app, "Time input 1 (8:45)").locator("input") # Type an option: empty_time_input_field.type("00:15") empty_time_input_field.press("Enter") expect_markdown(app, "Value 1: 00:15:00") expect_markdown(app, "Value 6: 00:00:00") # The flag should be reset to False: expect_markdown(app, "time input changed: False") def test_check_top_level_class(app: Page): """Check that the top level class is correctly set.""" check_top_level_class(app, "stTimeInput") 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, "time_input_6")).to_be_visible() def test_dynamic_time_input_props(app: Page, assert_snapshot: ImageCompareFunction): """Test that the time input can be updated dynamically while keeping the state.""" dynamic_time_input = get_element_by_key(app, "dynamic_time_input_with_key") expect(dynamic_time_input).to_be_visible() expect(dynamic_time_input).to_contain_text("Initial dynamic time input") expect_prefixed_markdown(app, "Initial time input value:", "08:45:00") assert_snapshot(dynamic_time_input, name="st_time_input-dynamic_initial") # Check that the help tooltip is correct: expect_help_tooltip(app, dynamic_time_input, "initial help") # Type something and submit input_field = dynamic_time_input.locator("input") input_field.type("00:15") input_field.press("Enter") wait_for_app_loaded(app) expect_prefixed_markdown(app, "Initial time input value:", "00:15:00") # Click the toggle to update the time input props click_toggle(app, "Update time input props") # new time input is visible: expect(dynamic_time_input).to_contain_text("Updated dynamic time input") # Ensure the previously entered value remains visible expect_prefixed_markdown(app, "Updated time input value:", "00:15:00") dynamic_time_input.scroll_into_view_if_needed() assert_snapshot(dynamic_time_input, name="st_time_input-dynamic_updated") # Check that the help tooltip is correct: expect_help_tooltip(app, dynamic_time_input, "updated help") def test_time_input_with_custom_theme(app: Page, assert_snapshot: ImageCompareFunction): """Test that time input adjusts for custom theme.""" # Apply custom theme using window injection apply_theme_via_window( app, base="light", primaryColor="#9867C5", textColor="#301934", secondaryBackgroundColor="#CBC3E3", ) # Reload to apply the theme app.reload() wait_for_app_loaded(app) time_input_widgets = app.get_by_test_id("stTimeInput") expect(time_input_widgets).to_have_count(NUM_TIME_INPUTS) # Click on the first time input to open the dropdown get_time_input(app, "Time input 1 (8:45)").locator("input").click() # Hover over the first option: selection_dropdown = app.locator('[data-baseweb="popover"]').first selection_dropdown.get_by_text("00:00").first.hover() # Take a snapshot of the time selection dropdown: assert_snapshot(selection_dropdown, name="st_time_input-dropdown-custom-theme") # Take a snapshot of the time input: assert_snapshot( get_time_input(app, "Time input 1 (8:45)"), name="st_time_input-custom-theme" )