diff --git a/setup.py b/setup.py index 9fbadec..cc9fcc7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setuptools.setup( name="streamlit_folium", - version="0.21.0", + version="0.21.1", author="Randy Zwitch", author_email="rzwitch@gmail.com", description="Render Folium objects in Streamlit", diff --git a/streamlit_folium/__init__.py b/streamlit_folium/__init__.py index 45f8410..b968b40 100644 --- a/streamlit_folium/__init__.py +++ b/streamlit_folium/__init__.py @@ -397,8 +397,8 @@ def walk(fig): 0, "https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" ) js_links.insert(0, "https://d3js.org/d3.v4.min.js") - css_links.extend([href for _, href in elem.default_css]) - js_links.extend([src for _, src in elem.default_js]) + css_links.extend([href for _, href in getattr(elem, "default_css", [])]) + js_links.extend([src for _, src in getattr(elem, "default_js", [])]) component_value = _component_func( script=leaflet, diff --git a/tests/test_frontend.py b/tests/test_frontend.py index 50604de..a5e198b 100644 --- a/tests/test_frontend.py +++ b/tests/test_frontend.py @@ -1,8 +1,10 @@ +from __future__ import annotations + from contextlib import contextmanager from time import sleep import pytest -from playwright.sync_api import Page, expect +from playwright.sync_api import Page, Response, expect LOCAL_TEST = False @@ -20,6 +22,7 @@ def before_module(): def before_test(page: Page): page.goto(f"localhost:{PORT}") page.set_viewport_size({"width": 2000, "height": 2000}) + expect.set_options(timeout=5_000) # Take screenshot of each page if there are failures for this session @@ -61,7 +64,31 @@ def run_streamlit(): p.kill() +def click_button_or_marker(page: Page, nth: int = 0, locator: str | None = None): + """For some reason, there's a discrepancy between how the map markers are + selectable locally and on github actions, perhaps related some error in loading + the actual marker images. This tries both ways to select a marker""" + + frame = page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]') + if locator is not None: + frame = frame.locator(locator) + try: + frame.get_by_role("button", name="Marker").nth(nth).click(timeout=5_000) + except Exception: + frame.get_by_role("img").nth(nth).click(timeout=5_000) + + def test_marker_click(page: Page): + def check_for_404(response: Response): + if not response.ok: + print(response) + print(response.text()) + print(response.url) + print(response.status) + raise Exception("404") + + page.on("response", check_for_404) + # Check page title expect(page).to_have_title("streamlit-folium documentation") @@ -69,9 +96,7 @@ def test_marker_click(page: Page): # Click marker try: - page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]').get_by_role( - "button", name="Marker" - ).click() + click_button_or_marker(page) except Exception as e: page.screenshot(path="screenshot-test-marker-click.png", full_page=True) raise e @@ -119,15 +144,11 @@ def test_limit_data(page: Page): expect(page.get_by_text('{"last_object_clicked":NULL}')).to_be_visible() # Click marker - page.frame_locator( - 'internal:attr=[title="streamlit_folium.st_folium"i]' - ).get_by_role("button").nth(2).click() + click_button_or_marker(page, 2) # Have to click a second time for some reason, maybe because it doesn't load right # away - page.frame_locator( - 'internal:attr=[title="streamlit_folium.st_folium"i]' - ).get_by_role("button").nth(2).click() + click_button_or_marker(page, 2) expect(page.get_by_text('{"last_object_clicked":{"lat":39.96')).to_be_visible() @@ -144,12 +165,8 @@ def test_dual_map(page: Page): # Click marker on left map try: - page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]').locator( - "#map_div" - ).get_by_role("button", name="Marker").click() - page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]').locator( - "#map_div2" - ).get_by_role("button", name="Marker").click() + click_button_or_marker(page, 0, "#map_div") + click_button_or_marker(page, 0, "#map_div2") except Exception as e: page.screenshot(path="screenshot-dual-map.png", full_page=True) raise e @@ -170,9 +187,7 @@ def test_tooltip_click(page: Page): expect(page.get_by_text('"last_object_clicked_tooltip":NULL')).to_be_visible() # Click marker on map - page.frame_locator( - 'internal:attr=[title="streamlit_folium.st_folium"i]' - ).get_by_role("button").nth(0).click() + click_button_or_marker(page) expect( page.get_by_text('"last_object_clicked_tooltip":"Liberty Bell"') @@ -186,9 +201,7 @@ def test_popup_text(page: Page): expect(page.get_by_text("Popup: None")).to_be_visible() expect(page.get_by_text("Tooltip: None")).to_be_visible() - page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]').get_by_role( - "button" - ).nth(0).click() + click_button_or_marker(page) try: expect(page.get_by_text("Popup: Popup!")).to_be_visible() @@ -207,9 +220,7 @@ def test_return_on_hover(page: Page): page.get_by_text("Return on hover?").click() - page.frame_locator('iframe[title="streamlit_folium\\.st_folium"]').get_by_role( - "button" - ).nth(1).hover() + click_button_or_marker(page, 1) try: expect(page.get_by_text("Popup: Popup 2!")).to_be_visible() @@ -273,6 +284,12 @@ def test_grouped_layer_control(page: Page): ).check() +def test_geojson_popup(page: Page): + page.get_by_role("link", name="geojson popup").click() + + expect(page.get_by_text("AttributeError")).to_be_hidden() + + def test_dynamic_feature_group_update(page: Page): page.get_by_role("link", name="dynamic updates").click() page.get_by_text("Show generated code").click()