Skip to content

Issue 2077: Add sample playwright tests for folium #2127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test_code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ jobs:
run: python -m pip install -e . --no-deps --force-reinstall

- name: Code tests
run: python -m pytest -vv --ignore=tests/selenium
run: python -m pytest -vv --ignore=tests/selenium --ignore=tests/playwright
2 changes: 1 addition & 1 deletion .github/workflows/test_latest_branca.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ jobs:
run: |
micromamba remove branca --yes --force
python -m pip install git+https://github.com/python-visualization/branca.git
python -m pytest -vv --ignore=tests/selenium
python -m pytest -vv --ignore=tests/selenium --ignore=tests/playwright
61 changes: 61 additions & 0 deletions .github/workflows/test_playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Run Playwright Tests

on:
pull_request:
push:
branches:
- main

jobs:
run:
runs-on: ubuntu-latest

steps:
- name: Checkout Folium
uses: actions/checkout@v4

- name: Setup Micromamba env
uses: mamba-org/setup-micromamba@v2
with:
environment-name: TEST
create-args: >-
python=3
--file requirements.txt
--file requirements-dev.txt

- name: Install streamlit-folium
shell: bash -l {0}
run: |
pip install streamlit-folium pytest-playwright pytest-rerunfailures pixelmatch

- name: Install playwright dependencies
shell: bash -l {0}
run: |
playwright install --with-deps

- name: Install annotate-failures-plugin
run: pip install pytest-github-actions-annotate-failures

- name: Install folium from source
shell: bash -l {0}
run: |
python -m pip install -e . --no-deps --force-reinstall

- name: Test with pytest and retry flaky tests up to 3 times
shell: bash -l {0}
run: |
pytest tests/playwright --browser chromium -s --reruns 3 --junit-xml=test-results.xml

- name: Surface failing tests
if: always()
uses: pmeier/pytest-results-action@main
with:
path: test-results.xml
fail-on-empty: false

- name: Upload screenshots
if: failure()
uses: actions/upload-artifact@v4
with:
name: screenshots
path: /tmp/screenshot_*_*.png
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ repos:
- id: debug-statements
- id: end-of-file-fixer
- id: check-docstring-first
exclude: ^examples/streamlit
- id: check-added-large-files
args: ['--maxkb=1024']
- id: requirements-txt-fixer
- id: file-contents-sorter
files: requirements-dev.txt
Expand Down
2 changes: 2 additions & 0 deletions .streamlit/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[server]
enableStaticServing = true
11 changes: 11 additions & 0 deletions examples/streamlit/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import streamlit as st

st.logo("https://python-visualization.github.io/folium/latest/_static/folium_logo.png")
st.title("Python data, leaflet.js maps")

"""
Folium builds on the data wrangling strengths of the Python ecosystem
and the mapping strengths of the Leaflet.js library.

Manipulate your data in Python, then visualize it in a Leaflet map via
Folium."""
43 changes: 43 additions & 0 deletions examples/streamlit/pages/draw_feature_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import streamlit as st

st.set_page_config(
page_title="streamlit-folium documentation: Draw Support",
page_icon=":pencil:",
layout="wide",
)

"""
# streamlit-folium: Draw Support

Folium supports some of the [most popular leaflet
plugins](https://python-visualization.github.io/folium/plugins.html). In this example,
we can add the
[`Draw`](https://python-visualization.github.io/folium/plugins.html#folium.plugins.Draw)
plugin to our map, which allows for drawing geometric shapes on the map.

When a shape is drawn on the map, the coordinates that represent that shape are passed
back as a geojson feature via the `all_drawings` and `last_active_drawing` data fields.

Draw something below to see the return value back to Streamlit!
"""

with st.echo(code_location="below"):
import streamlit as st
from streamlit_folium import st_folium

import folium
from folium.plugins import Draw

m = folium.Map(location=[39.949610, -75.150282], zoom_start=5, png_enabled=True)
items = folium.FeatureGroup()
marker = folium.Marker(location=[38, -83]).add_to(items)
items.add_to(m)

Draw(export=False, feature_group=items, show_geometry_on_click=False).add_to(m)

c1, c2 = st.columns(2)
with c1:
output = st_folium(m, width=700, height=500)

with c2:
st.write(output)
78 changes: 78 additions & 0 deletions examples/streamlit/pages/realtime-iss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import streamlit as st
from streamlit_folium import st_folium

import folium
from folium.plugins import Realtime

st.set_page_config(page_title="iss", layout="wide")

m = folium.Map()

source = folium.JsCode(
"""
function(responseHandler, errorHandler) {
var url = 'https://api.wheretheiss.at/v1/satellites/25544';

fetch(url)
.then((response) => {
return response.json().then((data) => {
var { id, timestamp, longitude, latitude } = data;

return {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [longitude, latitude]
},
'properties': {
'id': id,
'timestamp': timestamp
}
}]
};
})
})
.then(responseHandler)
.catch(errorHandler);
}
"""
)

on_each_feature = folium.JsCode(
"""
(feature, layer) => {
layer.on("click", (event) => {
Streamlit.setComponentValue({
id: feature.properties.id,
// Be careful, on_each_feature binds only once.
// You need to extract the current location from
// the event.
location: event.sourceTarget.feature.geometry
});
});
}
"""
)

realtime = Realtime(source, on_each_feature=on_each_feature, interval=1000).add_to(m)
realtime.on(
update=folium.JsCode(
"""
(e) => {
console.log('update ', e.target._map);
var map = e.target._map;
var realtime = e.target;
map.fitBounds(realtime.getBounds(), {maxZoom: 8});
}
"""
)
)

left, right = st.columns(2)
with left:
data = st_folium(m, width=1000, returned_objects=[], debug=True)

with right:
st.write(data)
2 changes: 1 addition & 1 deletion folium/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ def __init__(
popup: Optional["GeoJsonPopup"] = None,
zoom_on_click: bool = False,
on_each_feature: Optional[JsCode] = None,
marker: Union[Circle, CircleMarker, Marker, None] = None,
marker: Union[Circle, CircleMarker, folium.map.Marker, None] = None,
**kwargs: Any,
):
super().__init__(name=name, overlay=overlay, control=control, show=show)
Expand Down
5 changes: 4 additions & 1 deletion folium/plugins/search.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from branca.element import MacroElement

from folium import FeatureGroup, GeoJson, TopoJson
from folium.elements import JSCSSMixin
from folium.features import FeatureGroup, GeoJson, TopoJson

# from folium.map import FeatureGroup
# from folium.features import GeoJson, TopoJson
from folium.folium import Map
from folium.plugins import MarkerCluster
from folium.template import Template
Expand Down
11 changes: 11 additions & 0 deletions tests/playwright/regressions/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import streamlit as st

st.logo("https://python-visualization.github.io/folium/latest/_static/folium_logo.png")
st.title("Python data, leaflet.js maps")

st.write(
"""
This app is meant to store regression tests. For issues, create a
test pages under pages with the format issue_d+.
"""
)
31 changes: 31 additions & 0 deletions tests/playwright/regressions/pages/issue_1885.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from streamlit_folium import st_folium

import folium

# Library of Congress coordinates (latitude, longitude)
loc_coordinates = (38.8886, -77.0047)

# Create a Folium map centered around the Library of Congress
map_lc = folium.Map(location=loc_coordinates, zoom_start=15)

# Define the DivIcon with the custom icon. This variable can be used in one marker successfully, but will fail if we use it in two markers.


icon = folium.DivIcon(
icon_anchor=(15, 15),
html="""<div><img src="/app/static/book-open-variant-outline.png" height="35" width="35"/></div>""",
)


folium.Marker(
location=(38.886970844230866, -77.00471380332),
popup="Library of Congress: James Madison Building",
icon=icon,
).add_to(map_lc)

folium.Marker(location=loc_coordinates, popup="Library of Congress", icon=icon).add_to(
map_lc
)
# if we save here, everything will be fine.

st_folium(map_lc, width=600, height=500)
32 changes: 32 additions & 0 deletions tests/playwright/regressions/pages/issue_1885_add_child.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from streamlit_folium import st_folium

import folium

# Library of Congress coordinates (latitude, longitude)
loc_coordinates = (38.8886, -77.0047)

# Create a Folium map centered around the Library of Congress
map_lc = folium.Map(location=loc_coordinates, zoom_start=15)

# Define the DivIcon with the custom icon. This variable can be used in one marker successfully, but will fail if we use it in two markers.
icon = folium.DivIcon(
icon_anchor=(15, 15),
html="""<div><img src="/app/static/book-open-variant-outline.png" height="35" width="35"/></div>""",
)


folium.Marker(
location=(38.886970844230866, -77.00471380332),
popup="Library of Congress: James Madison Building",
icon=icon,
).add_to(map_lc)

marker = folium.Marker(
location=loc_coordinates,
popup="Library of Congress",
).add_to(map_lc)

marker.add_child(icon)
# if we save here, everything will be fine.

st_folium(map_lc, width=600, height=500)
34 changes: 34 additions & 0 deletions tests/playwright/regressions/pages/issue_1885_add_to.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from streamlit_folium import st_folium

import folium

# Library of Congress coordinates (latitude, longitude)
loc_coordinates = (38.8886, -77.0047)

# Create a Folium map centered around the Library of Congress
map_lc = folium.Map(location=loc_coordinates, zoom_start=15)

# Define the DivIcon with the custom icon. This variable can be used in one marker successfully, but will fail if we use it in two markers.


icon = folium.DivIcon(
icon_anchor=(15, 15),
html="""<div><img src="/app/static/book-open-variant-outline.png" height="35" width="35"/></div>""",
)


folium.Marker(
location=(38.886970844230866, -77.00471380332),
popup="Library of Congress: James Madison Building",
icon=icon,
).add_to(map_lc)

marker = folium.Marker(
location=loc_coordinates,
popup="Library of Congress",
).add_to(map_lc)
# if we save here, everything will be fine.

icon.add_to(marker)

st_folium(map_lc, width=600, height=500)
31 changes: 31 additions & 0 deletions tests/playwright/regressions/pages/issue_1885_set_icon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from streamlit_folium import st_folium

import folium

# Library of Congress coordinates (latitude, longitude)
loc_coordinates = (38.8886, -77.0047)

# Create a Folium map centered around the Library of Congress
map_lc = folium.Map(location=loc_coordinates, zoom_start=15)

# Define the DivIcon with the custom icon. This variable can be used in one marker successfully, but will fail if we use it in two markers.


icon = folium.DivIcon(
icon_anchor=(15, 15),
html="""<div><img src="/app/static/book-open-variant-outline.png" height="35" width="35"/></div>""",
)


marker1 = folium.Marker(
location=(38.886970844230866, -77.00471380332),
popup="Library of Congress: James Madison Building",
).add_to(map_lc)

marker2 = folium.Marker(
location=loc_coordinates, popup="Library of Congress", icon=icon
).add_to(map_lc)
marker1.set_icon(icon)
marker2.set_icon(icon)

st_folium(map_lc, width=600, height=500)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading