/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
e2e_playwright/st_feedback_test.py
257 строк
9 KB
Lukas Masuch
Extract `st.feedback` into its own proto and component (#13689)
02 фев 2026, 21:49
Не верифицирован
02 фев 2026, 21:49
4d2e7ff
Код
Авторство
О чём код?
# 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 Locator, Page, expect from e2e_playwright.conftest import ImageCompareFunction, wait_for_app_run from e2e_playwright.shared.app_utils import ( check_top_level_class, click_button, click_checkbox, click_form_button, click_toggle, expect_markdown, expect_prefixed_markdown, get_element_by_key, get_feedback, get_markdown, ) def get_feedback_icon_buttons(locator: Locator, type: str | None = None) -> Locator: elements = locator.get_by_test_id(re.compile(r"stFeedbackButton(Active)?")) if type: elements = elements.filter(has_text=type) return elements def get_feedback_icon_button( locator: Locator, type: str | None = None, index: int = 0 ) -> Locator: return get_feedback_icon_buttons(locator, type).nth(index) def test_click_thumbsup_and_take_snapshot( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Create snapshot of thumbs feedback (enabled & disabled).""" container = get_element_by_key(themed_app, "thumbs_container") expect(container).to_be_attached() thumbs = get_feedback(themed_app, "thumbs_container") expect(thumbs).to_be_attached() get_feedback_icon_button(thumbs, "thumb_up").click() wait_for_app_run(themed_app) # Hover over the hover test feedback to show hover state hover_test_button = get_feedback_icon_button( get_feedback(themed_app, "thumbs_feedback_hover_test"), "thumb_down" ) hover_test_button.hover() assert_snapshot(container, name="st_feedback-thumbs") def test_clicking_on_faces_shows_sentiment_via_on_change_callback_and_take_snapshot( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Create snapshot of faces feedback (enabled & disabled).""" container = get_element_by_key(themed_app, "faces_container") expect(container).to_be_attached() faces = get_feedback(themed_app, "faces_container") get_feedback_icon_button(faces, "sentiment_satisfied").click() wait_for_app_run(themed_app) text = get_markdown(themed_app, "Faces sentiment: 3") expect(text).to_be_attached() # Hover over the hover test feedback to show hover state hover_test_button = get_feedback_icon_button( get_feedback(themed_app, "faces_feedback_hover_test"), "sentiment_very_satisfied", ) hover_test_button.hover() assert_snapshot(container, name="st_feedback-faces") def test_clicking_on_stars_shows_sentiment_and_take_snapshot( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Create snapshot of stars feedback (enabled & disabled).""" container = get_element_by_key(themed_app, "stars_container") expect(container).to_be_attached() stars = get_feedback(themed_app, "stars_container") get_feedback_icon_button(stars, "star", 3).click() wait_for_app_run(themed_app) text = get_markdown(themed_app, "Star sentiment: 3") expect(text).to_be_attached() # Hover over the hover test feedback to show hover state hover_test_button = get_feedback_icon_button( get_feedback(themed_app, "stars_feedback_hover_test"), "star", 4 ) hover_test_button.hover() assert_snapshot(container, name="st_feedback-stars") def test_feedback_buttons_are_disabled(app: Page): """Test that feedback buttons are disabled when `disabled=True` and that they cannot be interacted with. """ container = get_element_by_key(app, "stars_container") expect(container).to_be_attached() stars = get_feedback(app, "star_feedback_disabled") star_buttons = get_feedback_icon_buttons(stars) for star_button in star_buttons.all(): expect(star_button).to_have_js_property("disabled", True) selected_button = star_buttons.nth(4) selected_button.click(force=True) expect(selected_button).not_to_have_css( "color", re.compile(r"rgb\(\d+, \d+, \d+\)") ) # the feedback value was set to 3 via session state text = get_markdown(app, "feedback-disabled: 3") expect(text).to_be_attached() def test_pass_default_selections(app: Page): """Test that passed defaults are rendered correctly.""" expect_markdown(app, "Star sentiment: None") click_checkbox(app, "Set default value") expect_markdown(app, "Star sentiment: 2") click_checkbox(app, "Set default value") expect_markdown(app, "Star sentiment: None") def test_feedback_works_in_forms(app: Page): expect(app.get_by_text("feedback-in-form: None")).to_be_visible() container = app.get_by_test_id("stForm") expect(container).to_be_attached() thumbs = get_feedback(app, "feedback_in_form") get_feedback_icon_button(thumbs, "thumb_up").click() expect(app.get_by_text("feedback-in-form: None")).to_be_visible() click_form_button(app, "Submit") wait_for_app_run(app) text = get_markdown(app, "feedback-in-form: 1") expect(text).to_be_attached() def test_feedback_works_with_fragments(app: Page): expect(app.get_by_text("Runs: 1")).to_be_visible() expect(app.get_by_text("feedback-in-fragment: None")).to_be_visible() thumbs = get_feedback(app, "fragment_feedback") get_feedback_icon_button(thumbs, "thumb_up").click() wait_for_app_run(app) expect(app.get_by_text("feedback-in-fragment: 1")).to_be_visible() expect(app.get_by_text("Runs: 1")).to_be_visible() def test_feedback_remount_keep_value(app: Page): """Test that `st.feedback` remounts correctly without resetting value.""" expect(app.get_by_text("feedback-after-sleep: None")).to_be_visible() thumbs = get_feedback(app, "after_sleep_feedback") selected_button = get_feedback_icon_button(thumbs, "thumb_up") selected_button.click() wait_for_app_run(app) expect(app.get_by_text("feedback-after-sleep: 1")).to_be_visible() expect(selected_button).to_have_css("color", re.compile(r"rgb\(\d+, \d+, \d+\)")) click_button(app, "Create some elements to unmount component") expect(selected_button).to_have_css("color", re.compile(r"rgb\(\d+, \d+, \d+\)")) expect(app.get_by_text("feedback-after-sleep: 1")).to_be_visible() def test_check_top_level_class(app: Page): """Check that the top level class is correctly set.""" check_top_level_class(app, "stFeedback") 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, "faces_feedback")).to_be_visible() def test_feedback_width_examples(app: Page, assert_snapshot: ImageCompareFunction): """Test feedback widgets with different width configurations.""" # Test thumbs width examples thumbs_content = get_element_by_key(app, "thumbs_content_width") assert_snapshot(thumbs_content, name="st_feedback-thumbs_width_content") thumbs_stretch = get_element_by_key(app, "thumbs_stretch_width") assert_snapshot(thumbs_stretch, name="st_feedback-thumbs_width_stretch") thumbs_300px = get_element_by_key(app, "thumbs_300px_width") assert_snapshot(thumbs_300px, name="st_feedback-thumbs_width_300px") def test_feedback_minimum_width_enforcement( app: Page, assert_snapshot: ImageCompareFunction ): """Test that st.feedback enforces minimum width to prevent icon wrapping (gh-12068).""" min_width_container = get_element_by_key(app, "feedback_min_width") assert_snapshot(min_width_container, name="st_feedback-min_width_enforced") def test_dynamic_feedback_props(app: Page, assert_snapshot: ImageCompareFunction): """Test that the feedback can be updated dynamically while keeping the state.""" feedback_widget = get_feedback(app, "dynamic_feedback_widget") expect(feedback_widget).to_be_visible() # Initial state assert_snapshot(feedback_widget, name="st_feedback-dynamic_initial") expect_prefixed_markdown(app, "Initial feedback value:", "2") # Click to change selection get_feedback_icon_button(feedback_widget, None, 3).click() wait_for_app_run(app) expect_prefixed_markdown(app, "Initial feedback value:", "3") # Update props via toggle click_toggle(app, "Update feedback props") # Value persisted expect_prefixed_markdown(app, "Updated feedback value:", "3") feedback_widget.scroll_into_view_if_needed() assert_snapshot(feedback_widget, name="st_feedback-dynamic_updated") # Click a different value get_feedback_icon_button(feedback_widget, None, 4).click() wait_for_app_run(app) expect_prefixed_markdown(app, "Updated feedback value:", "4")