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 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
758e848
Add sample playwright tests for folium
hansthen Apr 7, 2025
1db8558
Second iteration of the tests
hansthen Apr 22, 2025
2aa00d0
Undo module import
hansthen Apr 13, 2025
e806e55
Add dev requirements
hansthen Apr 14, 2025
077e34d
Move pixelmatch away from conda and mamba
hansthen Apr 15, 2025
4a11bbb
Enable static file serving
hansthen Apr 15, 2025
80de813
Upload screenshots after failure
hansthen Apr 15, 2025
4b6f014
There are some small differences in the tiles
hansthen Apr 15, 2025
bdaa021
New snapshot code
hansthen Apr 22, 2025
2ba54d1
Fix merge conflict
hansthen Apr 22, 2025
7b013ae
Moved snapshots to new location
hansthen May 11, 2025
582e255
Include pixelmatch dependency
hansthen May 11, 2025
3901694
Create visual snapshot testing
hansthen May 11, 2025
4579084
Small fixes
hansthen May 11, 2025
49ca780
Add test file
hansthen May 11, 2025
6e57804
New screenshots
hansthen May 11, 2025
ace74eb
New screenshots
hansthen May 11, 2025
54a5074
Remove snapshot tests regular workflow
hansthen May 11, 2025
8aaa4c8
Remove snapshot tests
hansthen May 11, 2025
a60a406
Cleanup playwright tests
hansthen May 11, 2025
f47f291
Improvements
hansthen May 11, 2025
210b398
New screenshots
hansthen May 11, 2025
6ac6a58
Add a tests to save all package versions
hansthen May 11, 2025
862c76a
Try again
hansthen May 11, 2025
182f6ad
Check versions
hansthen May 11, 2025
3709c47
Aargh
hansthen May 11, 2025
2ab87e1
Also save the generated html
hansthen May 11, 2025
1d59fdb
Also upload the generated maps
hansthen May 11, 2025
8ff4630
Check the chromium version
hansthen May 11, 2025
e196dbe
Used remotely created screenshots
hansthen May 11, 2025
62aba23
Rerun 5 times
hansthen May 11, 2025
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
43 changes: 43 additions & 0 deletions .github/workflows/save_versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Save package versions

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 folium from source
shell: bash -l {0}
run: |
python -m pip install -e . --no-deps --force-reinstall

- name: Create versions.txt
shell: bash -l {0}
run: |
conda list > /tmp/versions.txt
chromium --version >> /tmp/versions.txt

- name: Save versions.txt
if: always()
uses: actions/upload-artifact@v4
with:
name: versions.txt
path: /tmp/versions.txt
fail-on-empty: false
7 changes: 6 additions & 1 deletion .github/workflows/test_code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@ jobs:
- name: Install folium from source
run: python -m pip install -e . --no-deps --force-reinstall

- name: Install pixelmatch
shell: bash -l {0}
run: |
pip install pixelmatch

- name: Code tests
run: python -m pytest -vv --ignore=tests/selenium
run: python -m pytest -vv --ignore=tests/selenium --ignore=tests/playwright --ignore=tests/snapshots
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 --ignore=tests/snapshots
55 changes: 55 additions & 0 deletions .github/workflows/test_snapshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Run Snapshot 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 pytest plugins and pixelmatch
shell: bash -l {0}
run: |
pip install pixelmatch pytest-github-actions-annotate-failures pytest-rerunfailures

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

- name: Test with pytest
shell: bash -l {0}
run: |
python -m pytest tests/snapshots -s --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
/tmp/folium_map_*.html
2 changes: 1 addition & 1 deletion .github/workflows/test_streamlit_folium.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
shell: bash -l {0}
run: |
cd streamlit_folium
pytest tests/test_frontend.py --browser chromium -s --reruns 3 --junit-xml=test-results.xml
pytest tests/test_frontend.py --browser chromium -s --reruns 5 --junit-xml=test-results.xml

- name: Surface failing tests
if: always()
Expand Down
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)
46 changes: 46 additions & 0 deletions examples/streamlit/pages/issue_1770.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import json

import streamlit as st
from streamlit_folium import st_folium

import folium

st.set_page_config(layout="wide")

geojson = """
{"type": "FeatureCollection",
"features": [
{"id": "0", "type": "Feature", "properties": {"foo": 0},
"geometry": {"type": "Point", "coordinates": [0.0, 0.0]}
},
{"id": "1", "type": "Feature", "properties": {"foo": 1},
"geometry": {"type": "MultiPoint", "coordinates": [[1.0, 1.0]]}},
{"id": "2", "type": "Feature",
"properties": {"foo": 2}, "geometry": {"type": "MultiPoint", "coordinates":
[[2.0, 2.0]]}}, {"id": "3", "type": "Feature", "properties": {"foo": 3},
"geometry": {"type": "MultiPoint", "coordinates": [[3.0, 3.0]]}}, {"id": "4",
"type": "Feature", "properties": {"foo": 4}, "geometry": {"type":
"MultiPoint", "coordinates": [[4.0, 4.0]]}}]}"""

geojson = json.loads(geojson)

on_each_feature = folium.JsCode(
"""
(feature, layer) => {
layer.bindPopup("hello world");
}
"""
)
m = folium.Map(
zoom_start=5,
location=(0, 0),
)
folium.GeoJson(
geojson, on_each_feature=on_each_feature, marker=folium.CircleMarker(radius=20)
).add_to(m)

st_folium(m, width=700, height=500)
# st_folium(m, width=700, height=500, returned_objects=[])

html = m.get_root().render()
st.code(html)
101 changes: 101 additions & 0 deletions examples/streamlit/pages/issue_1989.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import io

import branca
import geopandas
import pandas as pd
import requests
import streamlit as st
from streamlit_folium import st_folium

import folium

st.set_page_config(layout="wide")

response = requests.get(
"https://gist.githubusercontent.com/tvpmb/4734703/raw/"
"b54d03154c339ed3047c66fefcece4727dfc931a/US%2520State%2520List"
)
abbrs = pd.read_json(io.StringIO(response.text))

income = pd.read_csv(
"https://raw.githubusercontent.com/pri-data/50-states/master/data/income-counties-states-national.csv",
dtype={"fips": str},
)
income["income-2015"] = pd.to_numeric(income["income-2015"], errors="coerce")

data = requests.get(
"https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_states.json"
).json()

states = geopandas.GeoDataFrame.from_features(data, crs="EPSG:4326")
statesmerge = states.merge(abbrs, how="left", left_on="name", right_on="name")
statesmerge["geometry"] = statesmerge.geometry.simplify(0.05)

statesmerge["medianincome"] = statesmerge.merge(
income.groupby("state")["income-2015"].median(),
how="left",
left_on="alpha-2",
right_on="state",
)["income-2015"]
statesmerge["change"] = statesmerge.merge(
income.groupby("state")["change"].median(),
how="left",
left_on="alpha-2",
right_on="state",
)["change"]

statesmerge["empty"] = None

colormap = branca.colormap.LinearColormap(
vmin=statesmerge["change"].quantile(0.0),
vmax=statesmerge["change"].quantile(1),
colors=["red", "orange", "lightblue", "green", "darkgreen"],
caption="State Level Median County Household Income (%)",
)

m = folium.Map(location=[35.3, -97.6], zoom_start=4)

popup = folium.GeoJsonPopup(
fields=["name", "change"],
aliases=["State", "% Change"],
localize=True,
labels=True,
style="background-color: yellow;",
)

tooltip = folium.GeoJsonTooltip(
fields=["name", "medianincome", "change", "empty"],
aliases=["State:", "2015 Median Income(USD):", "Median % Change:", "empty"],
localize=True,
sticky=False,
labels=True,
style="""
background-color: #F0EFEF;
border: 2px solid black;
border-radius: 3px;
box-shadow: 3px;
""",
max_width=800,
)

g = folium.GeoJson(
statesmerge,
style_function=lambda x: {
"fillColor": (
colormap(x["properties"]["change"])
if x["properties"]["change"] is not None
else "transparent"
),
"color": "black",
"fillOpacity": 0.4,
},
tooltip=tooltip,
popup=popup,
).add_to(m)

colormap.add_to(m)

html = m.get_root().render()
st_folium(m, width=700, height=500)

st.code(html)
Loading
Loading