umap-project 2.8.2__py3-none-any.whl → 2.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (260) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +15 -2
  3. umap/asgi.py +12 -7
  4. umap/context_processors.py +1 -0
  5. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/br/LC_MESSAGES/django.po +111 -67
  7. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/cs_CZ/LC_MESSAGES/django.po +110 -66
  9. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/el/LC_MESSAGES/django.po +129 -85
  11. umap/locale/en/LC_MESSAGES/django.po +103 -60
  12. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/es/LC_MESSAGES/django.po +114 -69
  14. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/fr/LC_MESSAGES/django.po +105 -61
  16. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  17. umap/locale/gl/LC_MESSAGES/django.po +216 -171
  18. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  19. umap/locale/it/LC_MESSAGES/django.po +142 -98
  20. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  21. umap/locale/nl/LC_MESSAGES/django.po +196 -151
  22. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/pt/LC_MESSAGES/django.po +115 -71
  24. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/zh_TW/LC_MESSAGES/django.po +109 -65
  26. umap/management/commands/empty_trash.py +12 -1
  27. umap/migrations/0026_datalayer_modified_at_datalayer_share_status.py +26 -0
  28. umap/models.py +43 -13
  29. umap/settings/base.py +5 -2
  30. umap/static/umap/base.css +5 -2
  31. umap/static/umap/content.css +2 -22
  32. umap/static/umap/css/bar.css +39 -10
  33. umap/static/umap/css/contextmenu.css +14 -2
  34. umap/static/umap/css/form.css +33 -39
  35. umap/static/umap/css/icon.css +47 -5
  36. umap/static/umap/css/panel.css +20 -2
  37. umap/static/umap/css/popup.css +0 -1
  38. umap/static/umap/css/tooltip.css +33 -31
  39. umap/static/umap/img/16-white.svg +5 -3
  40. umap/static/umap/img/16.svg +1 -1
  41. umap/static/umap/img/24-white.svg +17 -16
  42. umap/static/umap/img/24.svg +29 -18
  43. umap/static/umap/img/providers/bitbucket.png +0 -0
  44. umap/static/umap/img/providers/github.png +0 -0
  45. umap/static/umap/img/providers/keycloak.png +0 -0
  46. umap/static/umap/img/providers/openstreetmap-oauth2.png +0 -0
  47. umap/static/umap/img/providers/twitter-oauth2.png +0 -0
  48. umap/static/umap/img/source/16-white.svg +6 -4
  49. umap/static/umap/img/source/16.svg +1 -1
  50. umap/static/umap/img/source/24-white.svg +20 -18
  51. umap/static/umap/img/source/24.svg +30 -19
  52. umap/static/umap/js/components/alerts/alert.js +4 -1
  53. umap/static/umap/js/modules/browser.js +8 -8
  54. umap/static/umap/js/modules/caption.js +30 -7
  55. umap/static/umap/js/modules/data/features.js +101 -56
  56. umap/static/umap/js/modules/data/layer.js +108 -83
  57. umap/static/umap/js/modules/form/builder.js +242 -0
  58. umap/static/umap/js/modules/form/fields.js +1346 -0
  59. umap/static/umap/js/modules/formatter.js +9 -8
  60. umap/static/umap/js/modules/help.js +20 -24
  61. umap/static/umap/js/modules/importer.js +6 -3
  62. umap/static/umap/js/modules/permissions.js +11 -6
  63. umap/static/umap/js/modules/rendering/icon.js +5 -1
  64. umap/static/umap/js/modules/rendering/layers/classified.js +12 -8
  65. umap/static/umap/js/modules/rendering/layers/cluster.js +11 -1
  66. umap/static/umap/js/modules/rendering/map.js +1 -23
  67. umap/static/umap/js/modules/rendering/ui.js +20 -38
  68. umap/static/umap/js/modules/rules.js +3 -2
  69. umap/static/umap/js/modules/saving.js +5 -0
  70. umap/static/umap/js/modules/schema.js +8 -6
  71. umap/static/umap/js/modules/share.js +3 -3
  72. umap/static/umap/js/modules/sync/engine.js +56 -26
  73. umap/static/umap/js/modules/sync/updaters.js +15 -6
  74. umap/static/umap/js/modules/sync/websocket.js +50 -37
  75. umap/static/umap/js/modules/tableeditor.js +3 -2
  76. umap/static/umap/js/modules/ui/bar.js +101 -9
  77. umap/static/umap/js/modules/ui/base.js +7 -24
  78. umap/static/umap/js/modules/ui/contextmenu.js +9 -2
  79. umap/static/umap/js/modules/ui/panel.js +5 -1
  80. umap/static/umap/js/modules/ui/tooltip.js +19 -11
  81. umap/static/umap/js/modules/umap.js +121 -68
  82. umap/static/umap/js/modules/utils.js +196 -12
  83. umap/static/umap/js/umap.controls.js +11 -353
  84. umap/static/umap/locale/am_ET.js +17 -5
  85. umap/static/umap/locale/am_ET.json +17 -5
  86. umap/static/umap/locale/ar.js +17 -5
  87. umap/static/umap/locale/ar.json +17 -5
  88. umap/static/umap/locale/ast.js +17 -5
  89. umap/static/umap/locale/ast.json +17 -5
  90. umap/static/umap/locale/bg.js +17 -5
  91. umap/static/umap/locale/bg.json +17 -5
  92. umap/static/umap/locale/br.js +33 -20
  93. umap/static/umap/locale/br.json +33 -20
  94. umap/static/umap/locale/ca.js +17 -5
  95. umap/static/umap/locale/ca.json +17 -5
  96. umap/static/umap/locale/cs_CZ.js +15 -5
  97. umap/static/umap/locale/cs_CZ.json +15 -5
  98. umap/static/umap/locale/da.js +17 -5
  99. umap/static/umap/locale/da.json +17 -5
  100. umap/static/umap/locale/de.js +17 -5
  101. umap/static/umap/locale/de.json +17 -5
  102. umap/static/umap/locale/el.js +63 -51
  103. umap/static/umap/locale/el.json +63 -51
  104. umap/static/umap/locale/en.js +15 -5
  105. umap/static/umap/locale/en.json +15 -5
  106. umap/static/umap/locale/en_US.json +17 -5
  107. umap/static/umap/locale/es.js +25 -13
  108. umap/static/umap/locale/es.json +25 -13
  109. umap/static/umap/locale/et.js +17 -5
  110. umap/static/umap/locale/et.json +17 -5
  111. umap/static/umap/locale/eu.js +17 -5
  112. umap/static/umap/locale/eu.json +17 -5
  113. umap/static/umap/locale/fa_IR.js +17 -5
  114. umap/static/umap/locale/fa_IR.json +17 -5
  115. umap/static/umap/locale/fi.js +17 -5
  116. umap/static/umap/locale/fi.json +17 -5
  117. umap/static/umap/locale/fr.js +16 -6
  118. umap/static/umap/locale/fr.json +16 -6
  119. umap/static/umap/locale/gl.js +357 -345
  120. umap/static/umap/locale/gl.json +357 -345
  121. umap/static/umap/locale/he.js +17 -5
  122. umap/static/umap/locale/he.json +17 -5
  123. umap/static/umap/locale/hr.js +17 -5
  124. umap/static/umap/locale/hr.json +17 -5
  125. umap/static/umap/locale/hu.js +14 -5
  126. umap/static/umap/locale/hu.json +14 -5
  127. umap/static/umap/locale/id.js +17 -5
  128. umap/static/umap/locale/id.json +17 -5
  129. umap/static/umap/locale/is.js +17 -5
  130. umap/static/umap/locale/is.json +17 -5
  131. umap/static/umap/locale/it.js +125 -113
  132. umap/static/umap/locale/it.json +125 -113
  133. umap/static/umap/locale/ja.js +17 -5
  134. umap/static/umap/locale/ja.json +17 -5
  135. umap/static/umap/locale/ko.js +17 -5
  136. umap/static/umap/locale/ko.json +17 -5
  137. umap/static/umap/locale/lt.js +17 -5
  138. umap/static/umap/locale/lt.json +17 -5
  139. umap/static/umap/locale/ms.js +17 -5
  140. umap/static/umap/locale/ms.json +17 -5
  141. umap/static/umap/locale/nl.js +132 -119
  142. umap/static/umap/locale/nl.json +132 -119
  143. umap/static/umap/locale/no.js +17 -5
  144. umap/static/umap/locale/no.json +17 -5
  145. umap/static/umap/locale/pl.js +17 -5
  146. umap/static/umap/locale/pl.json +17 -5
  147. umap/static/umap/locale/pl_PL.json +17 -5
  148. umap/static/umap/locale/pt.js +38 -25
  149. umap/static/umap/locale/pt.json +38 -25
  150. umap/static/umap/locale/pt_BR.js +17 -5
  151. umap/static/umap/locale/pt_BR.json +17 -5
  152. umap/static/umap/locale/pt_PT.js +17 -5
  153. umap/static/umap/locale/pt_PT.json +17 -5
  154. umap/static/umap/locale/ro.js +17 -5
  155. umap/static/umap/locale/ro.json +17 -5
  156. umap/static/umap/locale/ru.js +17 -5
  157. umap/static/umap/locale/ru.json +17 -5
  158. umap/static/umap/locale/sk_SK.js +17 -5
  159. umap/static/umap/locale/sk_SK.json +17 -5
  160. umap/static/umap/locale/sl.js +17 -5
  161. umap/static/umap/locale/sl.json +17 -5
  162. umap/static/umap/locale/sr.js +17 -5
  163. umap/static/umap/locale/sr.json +17 -5
  164. umap/static/umap/locale/sv.js +17 -5
  165. umap/static/umap/locale/sv.json +17 -5
  166. umap/static/umap/locale/th_TH.js +17 -5
  167. umap/static/umap/locale/th_TH.json +17 -5
  168. umap/static/umap/locale/tr.js +17 -5
  169. umap/static/umap/locale/tr.json +17 -5
  170. umap/static/umap/locale/uk_UA.js +17 -5
  171. umap/static/umap/locale/uk_UA.json +17 -5
  172. umap/static/umap/locale/vi.js +17 -5
  173. umap/static/umap/locale/vi.json +17 -5
  174. umap/static/umap/locale/vi_VN.json +17 -5
  175. umap/static/umap/locale/zh.js +17 -5
  176. umap/static/umap/locale/zh.json +17 -5
  177. umap/static/umap/locale/zh_CN.json +17 -5
  178. umap/static/umap/locale/zh_TW.Big5.json +17 -5
  179. umap/static/umap/locale/zh_TW.js +15 -5
  180. umap/static/umap/locale/zh_TW.json +15 -5
  181. umap/static/umap/map.css +29 -76
  182. umap/static/umap/nav.css +6 -3
  183. umap/static/umap/unittests/utils.js +14 -0
  184. umap/static/umap/vars.css +3 -0
  185. umap/static/umap/vendors/dompurify/purify.es.js +138 -354
  186. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  187. umap/static/umap/vendors/editable/Leaflet.Editable.js +1 -0
  188. umap/sync/__init__.py +0 -0
  189. umap/sync/app.py +187 -0
  190. umap/sync/payloads.py +56 -0
  191. umap/templates/auth/user_detail.html +4 -0
  192. umap/templates/auth/user_form.html +9 -6
  193. umap/templates/auth/user_stars.html +4 -0
  194. umap/templates/base.html +1 -1
  195. umap/templates/registration/login.html +2 -5
  196. umap/templates/umap/about.html +5 -0
  197. umap/templates/umap/about_summary.html +2 -2
  198. umap/templates/umap/components/provider.html +8 -0
  199. umap/templates/umap/content_footer.html +1 -1
  200. umap/templates/umap/css.html +0 -2
  201. umap/templates/umap/js.html +0 -4
  202. umap/templates/umap/map_detail.html +1 -1
  203. umap/templates/umap/password_change.html +4 -0
  204. umap/templates/umap/password_change_done.html +4 -0
  205. umap/templates/umap/search.html +4 -0
  206. umap/templates/umap/search_bar.html +1 -0
  207. umap/templates/umap/team_confirm_delete.html +4 -0
  208. umap/templates/umap/team_detail.html +4 -0
  209. umap/templates/umap/team_form.html +4 -0
  210. umap/templates/umap/user_dashboard.html +1 -1
  211. umap/templates/umap/user_teams.html +4 -0
  212. umap/tests/base.py +3 -1
  213. umap/tests/integration/conftest.py +16 -23
  214. umap/tests/integration/test_anonymous_owned_map.py +2 -2
  215. umap/tests/integration/test_basics.py +4 -7
  216. umap/tests/integration/test_caption.py +1 -0
  217. umap/tests/integration/test_categorized_layer.py +4 -8
  218. umap/tests/integration/test_choropleth.py +1 -1
  219. umap/tests/integration/test_conditional_rules.py +3 -3
  220. umap/tests/integration/test_draw_polygon.py +14 -22
  221. umap/tests/integration/test_draw_polyline.py +6 -14
  222. umap/tests/integration/test_edit_datalayer.py +11 -11
  223. umap/tests/integration/test_edit_map.py +30 -4
  224. umap/tests/integration/test_edit_marker.py +5 -5
  225. umap/tests/integration/test_edit_polygon.py +6 -6
  226. umap/tests/integration/test_features_id_generation.py +2 -6
  227. umap/tests/integration/test_import.py +115 -29
  228. umap/tests/integration/test_optimistic_merge.py +1 -0
  229. umap/tests/integration/test_owned_map.py +1 -1
  230. umap/tests/integration/test_picto.py +8 -8
  231. umap/tests/integration/test_save.py +3 -2
  232. umap/tests/integration/test_star.py +13 -9
  233. umap/tests/integration/test_tableeditor.py +8 -7
  234. umap/tests/integration/test_view_marker.py +10 -0
  235. umap/tests/integration/test_websocket_sync.py +239 -64
  236. umap/tests/settings.py +2 -0
  237. umap/tests/test_datalayer.py +2 -3
  238. umap/tests/test_datalayer_views.py +20 -1
  239. umap/tests/test_empty_trash.py +10 -3
  240. umap/tests/test_map_views.py +11 -0
  241. umap/utils.py +27 -11
  242. umap/views.py +37 -6
  243. {umap_project-2.8.2.dist-info → umap_project-2.9.0.dist-info}/METADATA +22 -22
  244. {umap_project-2.8.2.dist-info → umap_project-2.9.0.dist-info}/RECORD +247 -248
  245. {umap_project-2.8.2.dist-info → umap_project-2.9.0.dist-info}/WHEEL +1 -1
  246. umap/management/commands/run_websocket_server.py +0 -23
  247. umap/settings/local_s3.py +0 -45
  248. umap/static/umap/bitbucket.png +0 -0
  249. umap/static/umap/github.png +0 -0
  250. umap/static/umap/js/umap.forms.js +0 -1242
  251. umap/static/umap/keycloak.png +0 -0
  252. umap/static/umap/openstreetmap.png +0 -0
  253. umap/static/umap/twitter.png +0 -0
  254. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +0 -468
  255. umap/static/umap/vendors/toolbar/leaflet.toolbar.css +0 -1
  256. umap/static/umap/vendors/toolbar/leaflet.toolbar.js +0 -1
  257. umap/tests/test_websocket_server.py +0 -22
  258. umap/websocket_server.py +0 -202
  259. {umap_project-2.8.2.dist-info → umap_project-2.9.0.dist-info}/entry_points.txt +0 -0
  260. {umap_project-2.8.2.dist-info → umap_project-2.9.0.dist-info}/licenses/LICENSE +0 -0
@@ -59,7 +59,7 @@ def test_cancel_deleting_datalayer_should_restore(
59
59
  markers = page.locator(".leaflet-marker-icon")
60
60
  expect(layers).to_have_count(1)
61
61
  expect(markers).to_have_count(1)
62
- page.get_by_role("link", name="Manage layers").click()
62
+ page.get_by_role("button", name="Manage layers").click()
63
63
  page.locator(".panel.right").get_by_title("Delete layer").click()
64
64
  page.get_by_role("button", name="OK").click()
65
65
  expect(markers).to_have_count(0)
@@ -77,7 +77,7 @@ def test_can_clone_datalayer(live_server, openmap, login, datalayer, page):
77
77
  markers = page.locator(".leaflet-marker-icon")
78
78
  expect(layers).to_have_count(1)
79
79
  expect(markers).to_have_count(1)
80
- page.get_by_role("link", name="Manage layers").click()
80
+ page.get_by_role("button", name="Manage layers").click()
81
81
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
82
82
  page.get_by_text("Advanced actions").click()
83
83
  page.get_by_role("button", name="Clone").click()
@@ -99,11 +99,11 @@ def test_can_change_icon_class(live_server, openmap, page):
99
99
  DataLayerFactory(map=openmap, data=data)
100
100
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/45.3/1")
101
101
  expect(page.locator(".umap-div-icon")).to_be_visible()
102
- page.get_by_role("link", name="Manage layers").click()
102
+ page.get_by_role("button", name="Manage layers").click()
103
103
  expect(page.locator(".umap-circle-icon")).to_be_hidden()
104
104
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
105
105
  page.get_by_text("Shape properties").click()
106
- page.locator(".umap-field-iconClass a.define").click()
106
+ page.locator(".umap-field-iconClass button.define").click()
107
107
  page.get_by_text("Circle", exact=True).click()
108
108
  expect(page.locator(".umap-circle-icon")).to_be_visible()
109
109
  expect(page.locator(".umap-div-icon")).to_be_hidden()
@@ -113,7 +113,7 @@ def test_can_change_name(live_server, openmap, page, datalayer):
113
113
  page.goto(
114
114
  f"{live_server.url}{openmap.get_absolute_url()}?edit&onLoadPanel=databrowser"
115
115
  )
116
- page.get_by_role("link", name="Manage layers").click()
116
+ page.get_by_role("button", name="Manage layers").click()
117
117
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
118
118
  expect(page.locator(".umap-is-dirty")).to_be_hidden()
119
119
  page.locator('input[name="name"]').click()
@@ -143,7 +143,7 @@ def test_can_create_new_datalayer(live_server, openmap, page, datalayer):
143
143
  page.goto(
144
144
  f"{live_server.url}{openmap.get_absolute_url()}?edit&onLoadPanel=databrowser"
145
145
  )
146
- page.get_by_role("link", name="Manage layers").click()
146
+ page.get_by_role("button", name="Manage layers").click()
147
147
  page.get_by_role("button", name="Add a layer").click()
148
148
  page.locator('input[name="name"]').click()
149
149
  page.locator('input[name="name"]').fill("Layer A")
@@ -155,7 +155,7 @@ def test_can_create_new_datalayer(live_server, openmap, page, datalayer):
155
155
  assert saved.name == "Layer A"
156
156
  expect(page.locator(".umap-is-dirty")).to_be_hidden()
157
157
  # Edit again, it should not create a new datalayer
158
- page.get_by_role("link", name="Manage layers").click()
158
+ page.get_by_role("button", name="Manage layers").click()
159
159
  page.locator(".panel.right").get_by_title("Edit", exact=True).first.click()
160
160
  page.locator('input[name="name"]').click()
161
161
  page.locator('input[name="name"]').fill("Layer A with a new name")
@@ -179,7 +179,7 @@ def test_can_restore_version(live_server, openmap, page, datalayer):
179
179
  with page.expect_response(re.compile(".*/datalayer/update/.*")):
180
180
  page.get_by_role("button", name="Save").click()
181
181
  expect(marker).to_have_class(re.compile(".*umap-div-icon.*"))
182
- page.get_by_role("link", name="Manage layers").click()
182
+ page.get_by_role("button", name="Manage layers").click()
183
183
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
184
184
  page.get_by_text("Versions").click()
185
185
  page.get_by_role("button", name="Restore this version").last.click()
@@ -201,7 +201,7 @@ def test_deleting_datalayer_should_remove_from_browser_and_layers_list(
201
201
  panel = page.locator(".panel.left")
202
202
  edit_panel = page.locator(".panel.right")
203
203
  page.get_by_title("Open browser").click()
204
- page.get_by_role("link", name="Manage layers").click()
204
+ page.get_by_role("button", name="Manage layers").click()
205
205
  expect(panel.get_by_text("test datalayer")).to_be_visible()
206
206
  expect(edit_panel.get_by_text("test datalayer")).to_be_visible()
207
207
  page.locator(".panel.right").get_by_title("Delete layer").click()
@@ -216,7 +216,7 @@ def test_deleting_datalayer_should_remove_from_caption(
216
216
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
217
217
  panel = page.locator(".panel.left")
218
218
  page.get_by_role("button", name="About").click()
219
- page.get_by_role("link", name="Manage layers").click()
219
+ page.get_by_role("button", name="Manage layers").click()
220
220
  expect(panel.get_by_text("test datalayer")).to_be_visible()
221
221
  page.locator(".panel.right").get_by_title("Delete layer").click()
222
222
  page.get_by_role("button", name="OK").click()
@@ -225,7 +225,7 @@ def test_deleting_datalayer_should_remove_from_caption(
225
225
 
226
226
  def test_can_edit_datalayer_name_in_list(live_server, openmap, datalayer, page):
227
227
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
228
- page.get_by_role("link", name="Manage layers").click()
228
+ page.get_by_role("button", name="Manage layers").click()
229
229
  page.get_by_text("test datalayer").click()
230
230
  page.get_by_text("test datalayer").fill("test datalayer foobar")
231
231
  page.get_by_role("button", name="Open browser").click()
@@ -21,6 +21,16 @@ def test_can_edit_name(page, live_server, tilelayer):
21
21
  )
22
22
 
23
23
 
24
+ def test_can_display_help(page, live_server, tilelayer):
25
+ page.goto(f"{live_server.url}/en/map/new/")
26
+
27
+ page.get_by_title("Edit map name and caption").click()
28
+ help_button = page.locator(".panel .umap-field-description .umap-help-button")
29
+ expect(help_button).to_be_visible()
30
+ help_button.click()
31
+ expect(page.locator("dialog").first).to_contain_text("Text formatting")
32
+
33
+
24
34
  def test_can_edit_name_on_click_on_toolbar(page, live_server, tilelayer):
25
35
  page.goto(f"{live_server.url}/en/map/new/")
26
36
  page.locator(".umap-main-edit-toolbox .map-name").click()
@@ -60,8 +70,8 @@ def test_zoomcontrol_impacts_ui(live_server, page, tilelayer):
60
70
  # Hide them
61
71
  page.get_by_text("User interface options").click()
62
72
  hide_zoom_controls = (
63
- page.locator("div")
64
- .filter(has_text=re.compile(r"^Display the zoom control"))
73
+ page.locator(".panel")
74
+ .filter(has_text=re.compile("Display the zoom control"))
65
75
  .locator("label")
66
76
  .nth(2)
67
77
  )
@@ -182,7 +192,7 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page):
182
192
 
183
193
  # Change the default sortkey to be "key"
184
194
  page.get_by_role("button", name="Edit").click()
185
- page.get_by_role("link", name="Map advanced properties").click()
195
+ page.get_by_role("button", name="Map advanced properties").click()
186
196
  page.get_by_text("Default properties").click()
187
197
 
188
198
  # Click "define"
@@ -191,7 +201,7 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page):
191
201
  page.locator('input[name="sortKey"]').fill("key")
192
202
 
193
203
  # Click the checkmark to apply the changes
194
- page.locator(".panel .umap-field-sortKey .blur-button").click()
204
+ page.locator(".panel .umap-field-sortKey .blur-container button").click()
195
205
 
196
206
  # Features should be sorted by key (First, Second, Third)
197
207
  first_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(0)
@@ -200,3 +210,19 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page):
200
210
  assert "Z First" == first_listed_feature.text_content()
201
211
  assert "Y Second" == second_listed_feature.text_content()
202
212
  assert "X Third" == third_listed_feature.text_content()
213
+
214
+
215
+ def test_hover_tooltip_setting_should_be_persistent(live_server, map, page):
216
+ map.settings["properties"]["showLabel"] = None
217
+ map.edit_status = Map.ANONYMOUS
218
+ map.save()
219
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
220
+ page.get_by_role("button", name="Map advanced properties").click()
221
+ page.get_by_text("Default interaction options").click()
222
+ expect(page.get_by_text("on hover")).to_be_visible()
223
+ expect(page.locator(".umap-field-showLabel")).to_match_aria_snapshot("""
224
+ - text: Display label
225
+ - button "clear"
226
+ - text: always never on hover
227
+ """)
228
+ expect(page.locator(".umap-field-showLabel input[value=null]")).to_be_checked()
@@ -43,7 +43,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
43
43
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.5/19")
44
44
 
45
45
  # Change colour at layer level
46
- page.get_by_role("link", name="Manage layers").click()
46
+ page.get_by_role("button", name="Manage layers").click()
47
47
  page.locator(".panel").get_by_title("Edit", exact=True).click()
48
48
  page.get_by_text("Shape properties").click()
49
49
  page.locator(".umap-field-color .define").click()
@@ -65,7 +65,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
65
65
  )
66
66
 
67
67
  # Now change again at layer level again, it should not change the marker color
68
- page.get_by_role("link", name="Manage layers").click()
68
+ page.get_by_role("button", name="Manage layers").click()
69
69
  page.locator(".panel").get_by_title("Edit", exact=True).click()
70
70
  page.get_by_text("Shape properties").click()
71
71
  page.locator(".umap-field-color input").click()
@@ -78,8 +78,8 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
78
78
  def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
79
79
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
80
80
  page.locator(".leaflet-marker-icon").click()
81
- expect(page.get_by_role("link", name="Toggle edit mode")).to_be_visible()
82
- expect(page.get_by_role("link", name="Delete this feature")).to_be_visible()
81
+ expect(page.get_by_role("button", name="Toggle edit mode")).to_be_visible()
82
+ expect(page.get_by_role("button", name="Delete this feature")).to_be_visible()
83
83
 
84
84
 
85
85
  def test_should_update_open_popup_on_edit(live_server, openmap, page, bootstrap):
@@ -115,6 +115,6 @@ def test_should_follow_datalayer_style_when_changing_datalayer(
115
115
  expect(marker).to_have_css("background-color", "rgb(0, 139, 139)")
116
116
  # Change datalayer
117
117
  marker.click()
118
- page.get_by_role("link", name="Toggle edit mode (⇧+Click)").click()
118
+ page.get_by_role("button", name="Toggle edit mode (⇧+Click)").click()
119
119
  page.locator(".umap-field-datalayer select").select_option(label="other datalayer")
120
120
  expect(marker).to_have_css("background-color", "rgb(148, 0, 211)")
@@ -57,7 +57,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
57
57
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
58
58
 
59
59
  # Change colour at layer level
60
- page.get_by_role("link", name="Manage layers").click()
60
+ page.get_by_role("button", name="Manage layers").click()
61
61
  page.locator(".panel").get_by_title("Edit", exact=True).click()
62
62
  page.get_by_text("Shape properties").click()
63
63
  page.locator(".umap-field-color .define").click()
@@ -75,7 +75,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
75
75
  )
76
76
 
77
77
  # Now change again at layer level again, it should not change the marker color
78
- page.get_by_role("link", name="Manage layers").click()
78
+ page.get_by_role("button", name="Manage layers").click()
79
79
  page.locator(".panel").get_by_title("Edit", exact=True).click()
80
80
  page.get_by_text("Shape properties").click()
81
81
  page.locator(".umap-field-color input").click()
@@ -88,8 +88,8 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
88
88
  def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
89
89
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
90
90
  page.locator("path").click()
91
- expect(page.get_by_role("link", name="Toggle edit mode")).to_be_visible()
92
- expect(page.get_by_role("link", name="Delete this feature")).to_be_visible()
91
+ expect(page.get_by_role("button", name="Toggle edit mode")).to_be_visible()
92
+ expect(page.get_by_role("button", name="Delete this feature")).to_be_visible()
93
93
 
94
94
 
95
95
  def test_can_remove_stroke(live_server, openmap, page, bootstrap):
@@ -98,10 +98,10 @@ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
98
98
  1
99
99
  )
100
100
  page.locator("path").click()
101
- page.get_by_role("link", name="Toggle edit mode").click()
101
+ page.get_by_role("button", name="Toggle edit mode").click()
102
102
  page.get_by_text("Shape properties").click()
103
103
  page.locator(".umap-field-stroke .define").first.click()
104
- page.locator(".umap-field-stroke label").first.click()
104
+ page.locator(".umap-field-stroke .show-on-defined label").first.click()
105
105
  expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
106
106
  0
107
107
  )
@@ -6,9 +6,7 @@ def test_ids_generation(page, live_server, tilelayer):
6
6
  page.goto(f"{live_server.url}/en/map/new/")
7
7
 
8
8
  # Click on the Draw a line button on a new map.
9
- create_polyline = page.locator(".leaflet-control-toolbar ").get_by_title(
10
- "Draw a polyline"
11
- )
9
+ create_polyline = page.locator(".umap-edit-bar ").get_by_title("Draw a polyline")
12
10
  create_polyline.click()
13
11
 
14
12
  map = page.locator("#map")
@@ -18,9 +16,7 @@ def test_ids_generation(page, live_server, tilelayer):
18
16
  map.click(position={"x": 100, "y": 100})
19
17
 
20
18
  # Click on the Draw a polygon button on a new map.
21
- create_polygon = page.locator(".leaflet-control-toolbar ").get_by_title(
22
- "Draw a polygon"
23
- )
19
+ create_polygon = page.locator(".umap-edit-bar ").get_by_title("Draw a polygon")
24
20
  create_polygon.click()
25
21
 
26
22
  map = page.locator("#map")
@@ -17,14 +17,15 @@ pytestmark = pytest.mark.django_db
17
17
  def test_layers_list_is_updated(live_server, tilelayer, page):
18
18
  page.goto(f"{live_server.url}/map/new/")
19
19
  modifier = "Cmd" if platform.system() == "Darwin" else "Ctrl"
20
- page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
20
+ page.get_by_role("button", name=f"Import data ({modifier}+I)").click()
21
21
  # Should work
22
22
  page.locator("[name=layer-id]").select_option(label="Import in a new layer")
23
- page.get_by_role("link", name="Manage layers").click()
23
+ page.get_by_role("button", name="Manage layers").click()
24
24
  page.get_by_role("button", name="Add a layer").click()
25
25
  page.locator('input[name="name"]').click()
26
26
  page.locator('input[name="name"]').fill("foobar")
27
- page.get_by_role("link", name=f"Import data ({modifier}+I)").click()
27
+ page.wait_for_timeout(300) # Time for the input debounce.
28
+ page.get_by_role("button", name=f"Import data ({modifier}+I)").click()
28
29
  # Should still work
29
30
  page.locator("[name=layer-id]").select_option(label="Import in a new layer")
30
31
  # Now layer should be visible in the options
@@ -70,13 +71,12 @@ def test_umap_import_from_file(live_server, tilelayer, page):
70
71
  expect(nonloaded).to_have_count(1)
71
72
 
72
73
 
73
- @pytest.mark.skip
74
74
  def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
75
75
  settings.UMAP_ALLOW_ANONYMOUS = True
76
76
  page.goto(f"{live_server.url}/map/new/")
77
77
  page.get_by_role("button", name="Open browser").click()
78
78
  page.get_by_title("Import data").click()
79
- textarea = page.locator(".umap-upload textarea")
79
+ textarea = page.locator(".umap-import textarea")
80
80
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap"
81
81
  textarea.fill(path.read_text())
82
82
  page.locator('select[name="format"]').select_option("umap")
@@ -111,7 +111,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
111
111
  button = page.get_by_title("Import data")
112
112
  expect(button).to_be_visible()
113
113
  button.click()
114
- textarea = page.locator(".umap-upload textarea")
114
+ textarea = page.locator(".umap-import textarea")
115
115
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.json"
116
116
  textarea.fill(path.read_text())
117
117
  page.locator('select[name="format"]').select_option("geojson")
@@ -122,6 +122,28 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
122
122
  expect(paths).to_have_count(3)
123
123
 
124
124
 
125
+ def test_import_invalid_data(tilelayer, live_server, page):
126
+ uncaught_errors = []
127
+ page.on("pageerror", lambda exc: uncaught_errors.append(exc))
128
+ page.goto(f"{live_server.url}/map/new/")
129
+ page.get_by_title("Open browser").click()
130
+ layers = page.locator(".umap-browser .datalayer")
131
+ markers = page.locator(".leaflet-marker-icon")
132
+ paths = page.locator("path")
133
+ expect(markers).to_have_count(0)
134
+ expect(paths).to_have_count(0)
135
+ expect(layers).to_have_count(0)
136
+ button = page.get_by_title("Import data")
137
+ expect(button).to_be_visible()
138
+ button.click()
139
+ textarea = page.locator(".umap-import textarea")
140
+ textarea.fill("invalid data")
141
+ for format in ["geojson", "csv", "gpx", "kml", "georss", "osm", "umap"]:
142
+ page.locator('select[name="format"]').select_option(format)
143
+ page.get_by_role("button", name="Import data", exact=True).click()
144
+ assert not uncaught_errors, f"Error with format {format}"
145
+
146
+
125
147
  def test_import_kml_from_textarea(tilelayer, live_server, page):
126
148
  page.goto(f"{live_server.url}/map/new/")
127
149
  page.get_by_title("Open browser").click()
@@ -134,7 +156,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
134
156
  button = page.get_by_title("Import data")
135
157
  expect(button).to_be_visible()
136
158
  button.click()
137
- textarea = page.locator(".umap-upload textarea")
159
+ textarea = page.locator(".umap-import textarea")
138
160
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml"
139
161
  textarea.fill(path.read_text())
140
162
  page.locator('select[name="format"]').select_option("kml")
@@ -158,7 +180,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page, settings):
158
180
  button = page.get_by_title("Import data")
159
181
  expect(button).to_be_visible()
160
182
  button.click()
161
- textarea = page.locator(".umap-upload textarea")
183
+ textarea = page.locator(".umap-import textarea")
162
184
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx"
163
185
  textarea.fill(path.read_text())
164
186
  page.locator('select[name="format"]').select_option("gpx")
@@ -215,7 +237,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
215
237
  button = page.get_by_title("Import data")
216
238
  expect(button).to_be_visible()
217
239
  button.click()
218
- textarea = page.locator(".umap-upload textarea")
240
+ textarea = page.locator(".umap-import textarea")
219
241
  path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json"
220
242
  textarea.fill(path.read_text())
221
243
  page.locator('select[name="format"]').select_option("osm")
@@ -235,7 +257,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
235
257
  button = page.get_by_title("Import data")
236
258
  expect(button).to_be_visible()
237
259
  button.click()
238
- textarea = page.locator(".umap-upload textarea")
260
+ textarea = page.locator(".umap-import textarea")
239
261
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
240
262
  textarea.fill(path.read_text())
241
263
  page.locator('select[name="format"]').select_option("csv")
@@ -254,7 +276,7 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap)
254
276
  expect(layers).to_have_count(1)
255
277
  page.get_by_role("button", name="Edit").click()
256
278
  page.get_by_title("Import data").click()
257
- textarea = page.locator(".umap-upload textarea")
279
+ textarea = page.locator(".umap-import textarea")
258
280
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
259
281
  textarea.fill(path.read_text())
260
282
  page.locator('select[name="format"]').select_option("csv")
@@ -275,7 +297,7 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap):
275
297
  expect(layers).to_have_count(1)
276
298
  page.get_by_role("button", name="Edit").click()
277
299
  page.get_by_title("Import data").click()
278
- textarea = page.locator(".umap-upload textarea")
300
+ textarea = page.locator(".umap-import textarea")
279
301
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
280
302
  textarea.fill(path.read_text())
281
303
  page.locator('select[name="format"]').select_option("csv")
@@ -296,7 +318,7 @@ def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap):
296
318
  expect(layers).to_have_count(1)
297
319
  page.get_by_role("button", name="Edit").click()
298
320
  page.get_by_title("Import data").click()
299
- textarea = page.locator(".umap-upload textarea")
321
+ textarea = page.locator(".umap-import textarea")
300
322
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
301
323
  textarea.fill(path.read_text())
302
324
  page.locator("select[name=format]").select_option("csv")
@@ -342,7 +364,7 @@ def test_should_remove_dot_in_property_names(live_server, page, settings, tilela
342
364
  }
343
365
  page.goto(f"{live_server.url}/map/new/")
344
366
  page.get_by_title("Import data").click()
345
- textarea = page.locator(".umap-upload textarea")
367
+ textarea = page.locator(".umap-import textarea")
346
368
  textarea.fill(json.dumps(data))
347
369
  page.locator('select[name="format"]').select_option("geojson")
348
370
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -403,7 +425,7 @@ def test_import_geometry_collection(live_server, page, tilelayer):
403
425
  button = page.get_by_title("Import data")
404
426
  expect(button).to_be_visible()
405
427
  button.click()
406
- textarea = page.locator(".umap-upload textarea")
428
+ textarea = page.locator(".umap-import textarea")
407
429
  textarea.fill(json.dumps(data))
408
430
  page.locator('select[name="format"]').select_option("geojson")
409
431
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -437,7 +459,7 @@ def test_import_multipolygon(live_server, page, tilelayer):
437
459
  button = page.get_by_title("Import data")
438
460
  expect(button).to_be_visible()
439
461
  button.click()
440
- textarea = page.locator(".umap-upload textarea")
462
+ textarea = page.locator(".umap-import textarea")
441
463
  textarea.fill(json.dumps(data))
442
464
  page.locator('select[name="format"]').select_option("geojson")
443
465
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -469,7 +491,7 @@ def test_import_multipolyline(live_server, page, tilelayer):
469
491
  button = page.get_by_title("Import data")
470
492
  expect(button).to_be_visible()
471
493
  button.click()
472
- textarea = page.locator(".umap-upload textarea")
494
+ textarea = page.locator(".umap-import textarea")
473
495
  textarea.fill(json.dumps(data))
474
496
  page.locator('select[name="format"]').select_option("geojson")
475
497
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -478,13 +500,77 @@ def test_import_multipolyline(live_server, page, tilelayer):
478
500
  expect(paths).to_have_count(1)
479
501
 
480
502
 
503
+ def test_should_not_import_empty_coordinates(live_server, page, tilelayer):
504
+ data = {
505
+ "type": "FeatureCollection",
506
+ "features": [
507
+ {
508
+ "type": "Feature",
509
+ "properties": {"name": "An empty polygon"},
510
+ "geometry": {
511
+ "type": "Polygon",
512
+ "coordinates": [],
513
+ },
514
+ },
515
+ {
516
+ "type": "Feature",
517
+ "properties": {"name": "An empty linestring"},
518
+ "geometry": {
519
+ "type": "LineString",
520
+ "coordinates": [],
521
+ },
522
+ },
523
+ {
524
+ "type": "Feature",
525
+ "properties": {"name": "An empty point"},
526
+ "geometry": {
527
+ "type": "Point",
528
+ "coordinates": [],
529
+ },
530
+ },
531
+ {
532
+ "geometry": {
533
+ "type": "Point",
534
+ "coordinates": [6.922931671142578, 47.481161607175736],
535
+ },
536
+ "type": "Feature",
537
+ "properties": {"name": "A point"},
538
+ },
539
+ {
540
+ "geometry": {
541
+ "type": "LineString",
542
+ "coordinates": [
543
+ [2.4609375, 48.88639177703194],
544
+ [2.48291015625, 48.76343113791796],
545
+ [2.164306640625, 48.719961222646276],
546
+ ],
547
+ },
548
+ "type": "Feature",
549
+ "properties": {
550
+ "name": "A linestring",
551
+ },
552
+ },
553
+ ],
554
+ }
555
+ page.goto(f"{live_server.url}/map/new/")
556
+ page.get_by_title("Open browser").click()
557
+ page.get_by_title("Import data").click()
558
+ textarea = page.locator(".umap-import textarea")
559
+ textarea.fill(json.dumps(data))
560
+ page.locator('select[name="format"]').select_option("geojson")
561
+ page.get_by_role("button", name="Import data", exact=True).click()
562
+ page.locator("#map").click(button="right")
563
+ page.get_by_role("button", name="browse data").click()
564
+ expect(page.locator("li.feature")).to_have_count(2)
565
+
566
+
481
567
  def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page):
482
568
  page.goto(f"{live_server.url}/map/new/")
483
569
  page.get_by_title("Open browser").click()
484
570
  layers = page.locator(".umap-browser .datalayer")
485
571
  markers = page.locator(".leaflet-marker-icon")
486
572
  page.get_by_title("Import data").click()
487
- textarea = page.locator(".umap-upload textarea")
573
+ textarea = page.locator(".umap-import textarea")
488
574
  textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2")
489
575
  page.locator('select[name="format"]').select_option("csv")
490
576
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -501,7 +587,7 @@ def test_import_csv_with_commas_in_latlon(tilelayer, live_server, page, settings
501
587
  layers = page.locator(".umap-browser .datalayer")
502
588
  markers = page.locator(".leaflet-marker-icon")
503
589
  page.get_by_title("Import data").click()
504
- textarea = page.locator(".umap-upload textarea")
590
+ textarea = page.locator(".umap-import textarea")
505
591
  textarea.fill("lat;lon;foobar\n12,24;48,34;mypoint\n12,23;48,35;mypoint2")
506
592
  page.locator('select[name="format"]').select_option("csv")
507
593
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -549,14 +635,14 @@ def test_create_remote_data(page, live_server, tilelayer):
549
635
  page.route("*/**/ajax-proxy/**", handle)
550
636
  page.goto(f"{live_server.url}/map/new/")
551
637
  expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
552
- page.get_by_role("link", name="Import data").click()
638
+ page.get_by_role("button", name="Import data").click()
553
639
  page.get_by_placeholder("Provide an URL here").click()
554
640
  page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
555
641
  page.locator("[name=format]").select_option("geojson")
556
642
  page.get_by_role("radio", name="Link to the layer as remote data").click()
557
643
  page.get_by_role("button", name="Import data", exact=True).click()
558
644
  expect(page.locator(".leaflet-marker-icon")).to_be_visible()
559
- page.get_by_role("link", name="Manage layers").click()
645
+ page.get_by_role("button", name="Manage layers").click()
560
646
  page.get_by_role("button", name="Edit", exact=True).click()
561
647
  page.locator("summary").filter(has_text="Remote data").click()
562
648
  expect(page.locator('.panel input[name="url"]')).to_have_value(
@@ -586,14 +672,14 @@ def test_import_geojson_from_url(page, live_server, tilelayer):
586
672
  page.route("https://remote.org/data.json", handle)
587
673
  page.goto(f"{live_server.url}/map/new/")
588
674
  expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
589
- page.get_by_role("link", name="Import data").click()
675
+ page.get_by_role("button", name="Import data").click()
590
676
  page.get_by_placeholder("Provide an URL here").click()
591
677
  page.get_by_placeholder("Provide an URL here").fill("https://remote.org/data.json")
592
678
  page.locator("[name=format]").select_option("geojson")
593
679
  page.get_by_role("radio", name="Copy into the layer").click()
594
680
  page.get_by_role("button", name="Import data", exact=True).click()
595
681
  expect(page.locator(".leaflet-marker-icon")).to_be_visible()
596
- page.get_by_role("link", name="Manage layers").click()
682
+ page.get_by_role("button", name="Manage layers").click()
597
683
  page.get_by_role("button", name="Edit", exact=True).click()
598
684
  page.locator("summary").filter(has_text="Remote data").click()
599
685
  expect(page.locator('.panel input[name="url"]')).to_have_value("")
@@ -604,7 +690,7 @@ def test_overpass_import_with_bbox(page, live_server, tilelayer, settings):
604
690
  "overpass": {"url": "https://my.overpass.io/interpreter"}
605
691
  }
606
692
  page.goto(f"{live_server.url}/map/new/")
607
- page.get_by_role("link", name="Import data").click()
693
+ page.get_by_role("button", name="Import data").click()
608
694
  page.get_by_role("button", name="Import helpers").click()
609
695
  page.get_by_role("button", name="Overpass").click()
610
696
  page.get_by_placeholder("amenity=drinking_water").fill("building")
@@ -655,7 +741,7 @@ def test_overpass_import_retains_boundary(page, live_server, tilelayer, settings
655
741
  # Intercept the route
656
742
  page.route(re.compile("https://foobar.io/api.*"), handle)
657
743
  page.goto(f"{live_server.url}/map/new/")
658
- page.get_by_role("link", name="Import data").click()
744
+ page.get_by_role("button", name="Import data").click()
659
745
  page.get_by_role("button", name="Import helpers").click()
660
746
  page.get_by_role("button", name="Overpass").click()
661
747
  page.get_by_placeholder("amenity=drinking_water").fill("building")
@@ -710,7 +796,7 @@ def test_import_from_datasets(page, live_server, tilelayer, settings):
710
796
  page.route("https://remote.org/data.json", handle)
711
797
  page.goto(f"{live_server.url}/map/new/")
712
798
  expect(page.locator(".leaflet-marker-icon")).to_be_hidden()
713
- page.get_by_role("link", name="Import data").click()
799
+ page.get_by_title("Import data").click()
714
800
  page.get_by_role("button", name="Import helpers").click()
715
801
  page.get_by_role("button", name="Datasets").click()
716
802
  page.get_by_role("dialog").get_by_role("combobox").select_option(
@@ -718,7 +804,7 @@ def test_import_from_datasets(page, live_server, tilelayer, settings):
718
804
  )
719
805
  page.get_by_role("button", name="Choose this dataset").click()
720
806
  page.get_by_label("Copy into the layer").check()
721
- page.get_by_role("button", name="Import data").click()
807
+ page.get_by_role("button", name="Import data", exact=True).click()
722
808
  expect(page.locator(".leaflet-marker-icon")).to_be_visible()
723
809
  page.get_by_role("button", name="Open browser").click()
724
810
  expect(page.locator("h5").get_by_text("Good data")).to_be_visible()
@@ -736,7 +822,7 @@ def test_import_osm_relation(tilelayer, live_server, page):
736
822
  button = page.get_by_title("Import data")
737
823
  expect(button).to_be_visible()
738
824
  button.click()
739
- textarea = page.locator(".umap-upload textarea")
825
+ textarea = page.locator(".umap-import textarea")
740
826
  file_path = Path(__file__).parent.parent / "fixtures/test_import_osm_relation.json"
741
827
  textarea.fill(file_path.read_text())
742
828
  page.locator('select[name="format"]').select_option("osm")
@@ -756,7 +842,7 @@ def test_import_georss_from_textarea(tilelayer, live_server, page):
756
842
  button = page.get_by_title("Import data")
757
843
  expect(button).to_be_visible()
758
844
  button.click()
759
- textarea = page.locator(".umap-upload textarea")
845
+ textarea = page.locator(".umap-import textarea")
760
846
  path = Path(__file__).parent.parent / "fixtures/test_upload_georss.xml"
761
847
  textarea.fill(path.read_text())
762
848
  page.locator('select[name="format"]').select_option("georss")
@@ -285,6 +285,7 @@ def test_should_display_alert_on_conflict(context, live_server, datalayer, openm
285
285
  # Change name on page one and save
286
286
  page_one.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
287
287
  page_one.locator('input[name="name"]').fill("name from page one")
288
+ page_one.wait_for_timeout(300) # Time for the input debounce.
288
289
  with page_one.expect_response(re.compile(r".*/datalayer/update/.*")):
289
290
  page_one.get_by_role("button", name="Save").click()
290
291
 
@@ -239,7 +239,7 @@ def test_can_delete_datalayer(live_server, map, login, datalayer):
239
239
  markers = page.locator(".leaflet-marker-icon")
240
240
  expect(layers).to_have_count(1)
241
241
  expect(markers).to_have_count(1)
242
- page.get_by_role("link", name="Manage layers").click()
242
+ page.get_by_role("button", name="Manage layers").click()
243
243
  page.locator(".panel.right").get_by_title("Delete layer").click()
244
244
  page.get_by_role("button", name="OK").click()
245
245
  with page.expect_response(re.compile(r".*/datalayer/delete/.*")):