/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
e2e_playwright/st_button_test.py
299 строк
11 KB
Lukas Masuch
Auto-escape some markdown syntax in markdown labels (#13887)
11 фев 2026, 20:11
Не верифицирован
11 фев 2026, 20:11
9661d92
Код
Авторство
О чём код?
# 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_run from e2e_playwright.shared.app_utils import ( check_top_level_class, click_button, click_checkbox, click_toggle, expect_markdown, expect_prefixed_markdown, get_button, get_element_by_key, get_expander, ) TOTAL_BUTTONS = 32 def test_button_widget_rendering( themed_app: Page, assert_snapshot: ImageCompareFunction ): """Test that the button widgets are correctly rendered via screenshot matching.""" expect(themed_app.get_by_test_id("stButton")).to_have_count(TOTAL_BUTTONS) assert_snapshot( get_button(themed_app, "button 1"), name="st_button-default", ) assert_snapshot( get_button(themed_app, "button 2 (disabled)"), name="st_button-disabled", ) assert_snapshot( get_button(themed_app, "button 3 (primary)"), name="st_button-primary", ) assert_snapshot( get_button(themed_app, "button 4 (primary + disabled)"), name="st_button-disabled_primary", ) assert_snapshot( get_element_by_key(themed_app, "styled_label_button"), name="st_button-styled_label", ) assert_snapshot( get_element_by_key(themed_app, "help_button_key"), name="st_button-just_help", ) assert_snapshot( get_button(themed_app, "Like Button"), name="st_button-material_icon", ) assert_snapshot( get_button(themed_app, "Star Button"), name="st_button-emoji_icon", ) assert_snapshot( get_button(themed_app, re.compile(r"^Tertiary Button$")), name="st_button-tertiary", ) assert_snapshot( get_button(themed_app, "Disabled Tertiary Button"), name="st_button-disabled_tertiary", ) assert_snapshot( get_element_by_key(themed_app, "material_icon_digit_button"), name="st_button-material_icon_1k_icon", ) assert_snapshot( get_element_by_key(themed_app, "material_icon_digit_in_label_button"), name="st_button-material_icon_1k_markdown", ) assert_snapshot( get_button(themed_app, "Shortcut Button"), name="st_button-shortcut_button", ) assert_snapshot( get_element_by_key(themed_app, "icon_right_material"), name="st_button-icon_position_right_material", ) # The rest is tested in one screenshot in the following test def test_material_icon_hover(app: Page, assert_snapshot: ImageCompareFunction): like_btn_container = get_button(app, "Like Button") like_btn_container.hover() assert_snapshot(like_btn_container, name="st_button-material_icon_hover") def test_buttons_in_columns(themed_app: Page, assert_snapshot: ImageCompareFunction): """Test that the button widgets are correctly rendered in columns via screenshot matching.""" columns_container = get_element_by_key(themed_app, "buttons_in_columns") expect(columns_container).to_have_count(1) expect(columns_container.get_by_test_id("stButton")).to_have_count(8) assert_snapshot(columns_container, name="st_button-in_columns") def test_value_correct_on_click(app: Page): click_button(app, "button 1") expect_markdown(app, "value: True") expect_markdown(app, "value from state: True") def test_value_not_reset_on_reclick(app: Page): click_button(app, "button 1") click_button(app, "button 1") expect_markdown(app, "value: True") def test_click_calls_callback(app: Page): expect_markdown(app, "Button was clicked: False") click_button(app, "button 1") expect_markdown(app, "Button was clicked: True") expect_markdown(app, "times clicked: 1") expect_markdown(app, "arg value: 1") expect_markdown(app, "kwarg value: 2") def test_click_increment_count(app: Page): click_button(app, "button 1") expect_markdown(app, "times clicked: 1") click_button(app, "button 1") expect_markdown(app, "times clicked: 2") click_button(app, "button 1") expect_markdown(app, "times clicked: 3") def test_reset_on_other_widget_change(app: Page): click_button(app, "button 1") expect_markdown(app, "value: True") expect_markdown(app, "value from state: True") click_checkbox(app, "reset button return value") expect_markdown(app, "value: False") expect_markdown(app, "value from state: False") def test_check_top_level_class(app: Page): """Check that the top level class is correctly set.""" check_top_level_class(app, "stButton") 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, "button")).to_be_visible() def test_shows_cursor_pointer(app: Page): """Test that the button shows cursor pointer when hovered.""" expect(get_button(app, "button 1")).to_have_css("cursor", "pointer") def test_colored_text_hover(app: Page): """Test that the colored text is correctly rendered and changes color on hover.""" # Check hover behavior for colored text in primary button primary_button_container = get_element_by_key(app, "colored_text_primary") primary_text = primary_button_container.locator("span.stMarkdownColoredText").first expect(primary_text).to_have_class("stMarkdownColoredText") expect(primary_text).to_have_css( "color", "rgb(0, 84, 163)", # blueTextColor ) primary_button_container.locator("button").hover() # For primary buttons, the colored text should stay blue on hover (no color inheritance) expect(primary_text).to_have_css( "color", "rgb(0, 84, 163)", # blueTextColor ) # Check hover behavior for colored text in secondary button secondary_button_container = get_element_by_key(app, "colored_text_secondary") secondary_text = secondary_button_container.locator( "span.stMarkdownColoredText" ).first expect(secondary_text).to_have_class("stMarkdownColoredText") expect(secondary_text).to_have_css( "color", "rgb(0, 84, 163)", # blueTextColor ) secondary_button_container.locator("button").hover() # For secondary buttons, the colored text should stay blue on hover (no color inheritance) expect(secondary_text).to_have_css( "color", "rgb(0, 84, 163)", # blueTextColor ) # Check hover behavior for colored text in tertiary button tertiary_button_container = get_element_by_key(app, "colored_text_tertiary") tertiary_text = tertiary_button_container.locator( "span.stMarkdownColoredText" ).first expect(tertiary_text).to_have_class("stMarkdownColoredText") expect(tertiary_text).to_have_css( "color", "rgb(0, 84, 163)", # blueTextColor ) tertiary_button_container.locator("button").hover() # For tertiary buttons, the colored text should be red on hover to match the rest of the text expect(tertiary_text).to_have_css( "color", "rgb(255, 75, 75)", ) def test_button_hover(themed_app: Page, assert_snapshot: ImageCompareFunction): help_button_container = get_element_by_key(themed_app, "help_button_container") help_button = get_element_by_key(help_button_container, "help_button_key") help_button.hover() expect(themed_app.get_by_text("help text")).to_be_visible() assert_snapshot(help_button_container, name="st_button-help_button") def test_button_width_examples(app: Page, assert_snapshot: ImageCompareFunction): """Test button width examples via screenshot matching.""" # Button width examples button_expander = get_expander(app, "Button Width Examples") assert_snapshot( get_button(button_expander, "Content Width (Default)"), name="st_button-width_content", ) assert_snapshot( get_button(button_expander, "Stretch Width"), name="st_button-width_stretch", ) assert_snapshot( get_button(button_expander, "200px Width"), name="st_button-width_200px", ) def test_dynamic_button(app: Page, assert_snapshot: ImageCompareFunction): """Test that the button can be updated dynamically.""" dynamic_button = get_element_by_key(app, "dynamic_button_with_key") expect(dynamic_button).to_be_visible() expect(dynamic_button).to_contain_text("Initial dynamic button") assert_snapshot(dynamic_button, name="st_button-dynamic_initial") # Click the toggle to update the button props click_toggle(app, "Update button props") expect(dynamic_button).to_contain_text("Updated dynamic button") dynamic_button.scroll_into_view_if_needed() assert_snapshot(dynamic_button, name="st_button-dynamic_updated") # Click the submit button: dynamic_button.click() wait_for_app_run(app) expect_prefixed_markdown(app, "Clicked updated button:", "True") def test_button_shortcut_triggers(app: Page): """Ensure pressing the shortcut activates the button.""" shortcut_button = get_element_by_key(app, "shortcut_button") expect(shortcut_button).to_be_visible() # Ensure shortcut labels are rendered for buttons. expect(shortcut_button.locator("kbd")).to_have_text("Ctrl + J") # Press hotkey to trigger the button: app.keyboard.press("Control+J") wait_for_app_run(app) expect_markdown(app, "Shortcut button pressed!") def test_button_with_spinner_icon(app: Page): """Test that the button with spinner icon is rendered.""" button = get_button(app, "Button with spinner icon") # Check that the spinner icon is visible: expect(button.get_by_test_id("stSpinnerIcon")).to_be_visible() def test_markdown_syntax_in_labels(app: Page): """Test that markdown syntax characters in labels are displayed literally (issue #7359).""" # Test that "+" is not parsed as a list marker plus_button = get_element_by_key(app, "markdown_plus_label") expect(plus_button).to_contain_text("+") # Test that "1." is not parsed as an ordered list marker numbered_button = get_element_by_key(app, "markdown_numbered_label") expect(numbered_button).to_contain_text("1. Something")