umap-project 3.3.6__py3-none-any.whl → 3.4.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.
Files changed (239) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +4 -1
  3. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/cs_CZ/LC_MESSAGES/django.po +43 -33
  5. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/da/LC_MESSAGES/django.po +43 -33
  7. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/de/LC_MESSAGES/django.po +35 -29
  9. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/el/LC_MESSAGES/django.po +35 -29
  11. umap/locale/en/LC_MESSAGES/django.po +47 -41
  12. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/es/LC_MESSAGES/django.po +43 -33
  14. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/et/LC_MESSAGES/django.po +58 -54
  16. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  17. umap/locale/eu/LC_MESSAGES/django.po +43 -33
  18. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  19. umap/locale/fa_IR/LC_MESSAGES/django.po +43 -33
  20. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  21. umap/locale/fr/LC_MESSAGES/django.po +36 -30
  22. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/gl/LC_MESSAGES/django.po +43 -33
  24. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/hu/LC_MESSAGES/django.po +35 -29
  26. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/is/LC_MESSAGES/django.po +43 -33
  28. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/it/LC_MESSAGES/django.po +43 -33
  30. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/nl/LC_MESSAGES/django.po +35 -29
  32. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/pl/LC_MESSAGES/django.po +114 -103
  34. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/pt/LC_MESSAGES/django.po +43 -33
  36. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/th_TH/LC_MESSAGES/django.po +310 -109
  38. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/zh_TW/LC_MESSAGES/django.po +80 -70
  40. umap/management/commands/switch_user.py +2 -2
  41. umap/migrations/0018_datalayer_uuid.py +1 -1
  42. umap/models.py +7 -3
  43. umap/settings/local.py.sample +1 -1
  44. umap/static/umap/base.css +89 -32
  45. umap/static/umap/content.css +129 -33
  46. umap/static/umap/css/bar.css +82 -20
  47. umap/static/umap/css/browser.css +163 -0
  48. umap/static/umap/css/contextmenu.css +15 -0
  49. umap/static/umap/css/dialog.css +36 -16
  50. umap/static/umap/css/form.css +123 -33
  51. umap/static/umap/css/icon.css +46 -3
  52. umap/static/umap/css/panel.css +7 -3
  53. umap/static/umap/css/popup.css +34 -8
  54. umap/static/umap/css/tooltip.css +8 -4
  55. umap/static/umap/img/16-white.svg +26 -8
  56. umap/static/umap/img/16.svg +1 -1
  57. umap/static/umap/img/source/16-white.svg +36 -18
  58. umap/static/umap/img/source/16.svg +1 -1
  59. umap/static/umap/js/components/alerts/alert.css +69 -31
  60. umap/static/umap/js/components/alerts/alert.js +20 -2
  61. umap/static/umap/js/components/base.js +1 -1
  62. umap/static/umap/js/modules/browser.js +69 -61
  63. umap/static/umap/js/modules/caption.js +10 -7
  64. umap/static/umap/js/modules/data/features.js +85 -60
  65. umap/static/umap/js/modules/data/fields.js +446 -0
  66. umap/static/umap/js/modules/data/layer.js +78 -184
  67. umap/static/umap/js/modules/domutils.js +109 -0
  68. umap/static/umap/js/modules/filters.js +780 -0
  69. umap/static/umap/js/modules/form/builder.js +8 -5
  70. umap/static/umap/js/modules/form/fields.js +111 -221
  71. umap/static/umap/js/modules/formatter.js +24 -1
  72. umap/static/umap/js/modules/help.js +4 -3
  73. umap/static/umap/js/modules/i18n.js +1 -1
  74. umap/static/umap/js/modules/importer.js +1 -1
  75. umap/static/umap/js/modules/importers/opendata.js +15 -0
  76. umap/static/umap/js/modules/importers/openrouteservice.js +6 -1
  77. umap/static/umap/js/modules/managers.js +2 -2
  78. umap/static/umap/js/modules/permissions.js +39 -31
  79. umap/static/umap/js/modules/rendering/controls.js +11 -9
  80. umap/static/umap/js/modules/rendering/icon.js +3 -8
  81. umap/static/umap/js/modules/rendering/layers/base.js +1 -1
  82. umap/static/umap/js/modules/rendering/layers/classified.js +18 -11
  83. umap/static/umap/js/modules/rendering/layers/cluster.js +5 -3
  84. umap/static/umap/js/modules/rendering/layers/heat.js +27 -21
  85. umap/static/umap/js/modules/rendering/template.js +50 -23
  86. umap/static/umap/js/modules/rendering/ui.js +29 -23
  87. umap/static/umap/js/modules/rules.js +38 -44
  88. umap/static/umap/js/modules/schema.js +3 -6
  89. umap/static/umap/js/modules/share.js +5 -4
  90. umap/static/umap/js/modules/tableeditor.js +50 -38
  91. umap/static/umap/js/modules/templates.js +2 -3
  92. umap/static/umap/js/modules/ui/bar.js +55 -23
  93. umap/static/umap/js/modules/ui/dialog.js +38 -27
  94. umap/static/umap/js/modules/ui/panel.js +23 -8
  95. umap/static/umap/js/modules/ui/tooltip.js +6 -5
  96. umap/static/umap/js/modules/umap.js +151 -56
  97. umap/static/umap/js/modules/utils.js +24 -2
  98. umap/static/umap/js/umap.core.js +1 -110
  99. umap/static/umap/locale/am_ET.js +52 -17
  100. umap/static/umap/locale/am_ET.json +52 -17
  101. umap/static/umap/locale/ar.js +52 -17
  102. umap/static/umap/locale/ar.json +52 -17
  103. umap/static/umap/locale/ast.js +52 -17
  104. umap/static/umap/locale/ast.json +52 -17
  105. umap/static/umap/locale/bg.js +52 -17
  106. umap/static/umap/locale/bg.json +52 -17
  107. umap/static/umap/locale/br.js +48 -22
  108. umap/static/umap/locale/br.json +48 -22
  109. umap/static/umap/locale/ca.js +52 -17
  110. umap/static/umap/locale/ca.json +52 -17
  111. umap/static/umap/locale/cs_CZ.js +52 -17
  112. umap/static/umap/locale/cs_CZ.json +52 -17
  113. umap/static/umap/locale/da.js +54 -17
  114. umap/static/umap/locale/da.json +54 -17
  115. umap/static/umap/locale/de.js +51 -16
  116. umap/static/umap/locale/de.json +51 -16
  117. umap/static/umap/locale/el.js +52 -17
  118. umap/static/umap/locale/el.json +52 -17
  119. umap/static/umap/locale/en.js +53 -16
  120. umap/static/umap/locale/en.json +53 -16
  121. umap/static/umap/locale/en_US.json +52 -17
  122. umap/static/umap/locale/es.js +54 -17
  123. umap/static/umap/locale/es.json +54 -17
  124. umap/static/umap/locale/et.js +91 -56
  125. umap/static/umap/locale/et.json +91 -56
  126. umap/static/umap/locale/eu.js +84 -49
  127. umap/static/umap/locale/eu.json +84 -49
  128. umap/static/umap/locale/fa_IR.js +52 -17
  129. umap/static/umap/locale/fa_IR.json +52 -17
  130. umap/static/umap/locale/fi.js +52 -17
  131. umap/static/umap/locale/fi.json +52 -17
  132. umap/static/umap/locale/fr.js +53 -16
  133. umap/static/umap/locale/fr.json +53 -16
  134. umap/static/umap/locale/gl.js +52 -17
  135. umap/static/umap/locale/gl.json +52 -17
  136. umap/static/umap/locale/he.js +52 -17
  137. umap/static/umap/locale/he.json +52 -17
  138. umap/static/umap/locale/hr.js +52 -17
  139. umap/static/umap/locale/hr.json +52 -17
  140. umap/static/umap/locale/hu.js +59 -24
  141. umap/static/umap/locale/hu.json +59 -24
  142. umap/static/umap/locale/id.js +52 -17
  143. umap/static/umap/locale/id.json +52 -17
  144. umap/static/umap/locale/is.js +52 -17
  145. umap/static/umap/locale/is.json +52 -17
  146. umap/static/umap/locale/it.js +52 -17
  147. umap/static/umap/locale/it.json +52 -17
  148. umap/static/umap/locale/ja.js +52 -17
  149. umap/static/umap/locale/ja.json +52 -17
  150. umap/static/umap/locale/ko.js +52 -17
  151. umap/static/umap/locale/ko.json +52 -17
  152. umap/static/umap/locale/lt.js +52 -17
  153. umap/static/umap/locale/lt.json +52 -17
  154. umap/static/umap/locale/ms.js +52 -17
  155. umap/static/umap/locale/ms.json +52 -17
  156. umap/static/umap/locale/nl.js +52 -17
  157. umap/static/umap/locale/nl.json +52 -17
  158. umap/static/umap/locale/no.js +52 -17
  159. umap/static/umap/locale/no.json +52 -17
  160. umap/static/umap/locale/pl.js +53 -17
  161. umap/static/umap/locale/pl.json +53 -17
  162. umap/static/umap/locale/pl_PL.json +52 -17
  163. umap/static/umap/locale/pt.js +52 -17
  164. umap/static/umap/locale/pt.json +52 -17
  165. umap/static/umap/locale/pt_BR.js +52 -17
  166. umap/static/umap/locale/pt_BR.json +52 -17
  167. umap/static/umap/locale/pt_PT.js +52 -17
  168. umap/static/umap/locale/pt_PT.json +52 -17
  169. umap/static/umap/locale/ro.js +52 -17
  170. umap/static/umap/locale/ro.json +52 -17
  171. umap/static/umap/locale/ru.js +52 -17
  172. umap/static/umap/locale/ru.json +52 -17
  173. umap/static/umap/locale/si.js +1 -1
  174. umap/static/umap/locale/si.json +1 -1
  175. umap/static/umap/locale/sk_SK.js +52 -17
  176. umap/static/umap/locale/sk_SK.json +52 -17
  177. umap/static/umap/locale/sl.js +52 -17
  178. umap/static/umap/locale/sl.json +52 -17
  179. umap/static/umap/locale/sr.js +52 -17
  180. umap/static/umap/locale/sr.json +52 -17
  181. umap/static/umap/locale/sv.js +52 -17
  182. umap/static/umap/locale/sv.json +52 -17
  183. umap/static/umap/locale/th_TH.js +52 -17
  184. umap/static/umap/locale/th_TH.json +52 -17
  185. umap/static/umap/locale/tr.js +52 -17
  186. umap/static/umap/locale/tr.json +52 -17
  187. umap/static/umap/locale/uk_UA.js +52 -17
  188. umap/static/umap/locale/uk_UA.json +52 -17
  189. umap/static/umap/locale/vi.js +52 -17
  190. umap/static/umap/locale/vi.json +52 -17
  191. umap/static/umap/locale/vi_VN.json +52 -17
  192. umap/static/umap/locale/zh.js +52 -17
  193. umap/static/umap/locale/zh.json +52 -17
  194. umap/static/umap/locale/zh_CN.json +52 -17
  195. umap/static/umap/locale/zh_TW.Big5.json +52 -17
  196. umap/static/umap/locale/zh_TW.js +52 -16
  197. umap/static/umap/locale/zh_TW.json +52 -16
  198. umap/static/umap/map.css +63 -226
  199. umap/static/umap/unittests/utils.js +18 -0
  200. umap/static/umap/vars.css +23 -5
  201. umap/templates/umap/components/alerts/alert.html +32 -29
  202. umap/templates/umap/css.html +2 -1
  203. umap/templates/umap/login_popup_end.html +18 -9
  204. umap/templates/umap/user_map_table.html +7 -2
  205. umap/tests/integration/conftest.py +10 -6
  206. umap/tests/integration/test_anonymous_owned_map.py +90 -37
  207. umap/tests/integration/test_basics.py +25 -1
  208. umap/tests/integration/test_browser.py +37 -0
  209. umap/tests/integration/test_conditional_rules.py +107 -52
  210. umap/tests/integration/test_draw_polygon.py +6 -0
  211. umap/tests/integration/test_draw_polyline.py +11 -0
  212. umap/tests/integration/test_edit_marker.py +1 -1
  213. umap/tests/integration/test_export_map.py +19 -0
  214. umap/tests/integration/test_fields.py +541 -0
  215. umap/tests/integration/test_filters.py +616 -0
  216. umap/tests/integration/test_iframe.py +1 -1
  217. umap/tests/integration/test_import.py +38 -42
  218. umap/tests/integration/test_map_preview.py +1 -1
  219. umap/tests/integration/test_picto.py +1 -1
  220. umap/tests/integration/test_popup.py +31 -0
  221. umap/tests/integration/test_remote_data.py +60 -4
  222. umap/tests/integration/test_save.py +1 -1
  223. umap/tests/integration/test_share.py +4 -4
  224. umap/tests/integration/test_tableeditor.py +31 -7
  225. umap/tests/integration/test_websocket_sync.py +71 -20
  226. umap/tests/test_dashboard.py +11 -1
  227. umap/tests/test_statics.py +2 -2
  228. umap/tests/test_utils.py +19 -2
  229. umap/tests/test_views.py +1 -1
  230. umap/urls.py +1 -0
  231. umap/utils.py +8 -1
  232. umap/views.py +5 -0
  233. {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/METADATA +15 -15
  234. {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/RECORD +237 -233
  235. umap/static/umap/js/modules/facets.js +0 -164
  236. umap/tests/integration/test_facets_browser.py +0 -279
  237. {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/WHEEL +0 -0
  238. {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/entry_points.txt +0 -0
  239. {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -18,25 +18,24 @@ def owner_session(anonymap, context, live_server):
18
18
  key, value = anonymap.signed_cookie_elements
19
19
  signed = get_cookie_signer(salt=key).sign(value)
20
20
  context.add_cookies([{"name": key, "value": signed, "url": live_server.url}])
21
- return context.new_page()
22
21
 
23
22
 
24
- def test_map_load_with_owner(anonymap, live_server, owner_session):
25
- owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
26
- map_el = owner_session.locator("#map")
23
+ def test_map_load_with_owner(anonymap, live_server, owner_session, page):
24
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
25
+ map_el = page.locator("#map")
27
26
  expect(map_el).to_be_visible()
28
- enable = owner_session.get_by_role("button", name="Edit")
27
+ enable = page.get_by_role("button", name="Edit")
29
28
  expect(enable).to_be_visible()
30
29
  enable.click()
31
- disable = owner_session.get_by_role("button", name="View")
30
+ disable = page.get_by_role("button", name="View")
32
31
  expect(disable).to_be_visible()
33
- save = owner_session.get_by_role("button", name="Save")
32
+ save = page.get_by_role("button", name="Save")
34
33
  expect(save).to_be_visible()
35
- add_marker = owner_session.get_by_title("Draw a marker")
34
+ add_marker = page.get_by_title("Draw a marker")
36
35
  expect(add_marker).to_be_visible()
37
- edit_settings = owner_session.get_by_title("Map advanced properties")
36
+ edit_settings = page.get_by_title("Map advanced properties")
38
37
  expect(edit_settings).to_be_visible()
39
- edit_permissions = owner_session.get_by_title("Update permissions and editors")
38
+ edit_permissions = page.get_by_title("Update permissions and editors")
40
39
  expect(edit_permissions).to_be_visible()
41
40
 
42
41
 
@@ -71,35 +70,31 @@ def test_map_load_with_anonymous_but_editable_layer(
71
70
  expect(edit_permissions).to_be_hidden()
72
71
 
73
72
 
74
- def test_owner_permissions_form(map, datalayer, live_server, owner_session):
75
- owner_session.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
76
- edit_permissions = owner_session.get_by_title("Update permissions and editors")
73
+ def test_owner_permissions_form(map, datalayer, live_server, owner_session, page):
74
+ page.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
75
+ edit_permissions = page.get_by_title("Update permissions and editors")
77
76
  expect(edit_permissions).to_be_visible()
78
77
  edit_permissions.click()
79
- owner_field = owner_session.locator(".umap-field-owner")
78
+ owner_field = page.locator(".umap-field-owner")
80
79
  expect(owner_field).to_be_hidden()
81
- editors_field = owner_session.locator(".umap-field-editors input")
80
+ editors_field = page.locator(".umap-field-editors input")
82
81
  expect(editors_field).to_be_hidden()
83
- datalayer_label = owner_session.get_by_text('Who can edit "test datalayer"')
82
+ datalayer_label = page.get_by_text('Who can edit "test datalayer"')
84
83
  expect(datalayer_label).to_be_visible()
85
- options = owner_session.locator(
86
- ".datalayer-permissions select[name='edit_status'] option"
87
- )
84
+ options = page.locator(".datalayer-permissions select[name='edit_status'] option")
88
85
  expect(options).to_have_count(3)
89
- option = owner_session.locator(
86
+ option = page.locator(
90
87
  ".datalayer-permissions select[name='edit_status'] option:checked"
91
88
  )
92
89
  expect(option).to_have_text("Inherit")
93
- expect(owner_session.locator(".umap-field-share_status select")).to_be_visible()
90
+ expect(page.locator(".umap-field-share_status select")).to_be_visible()
94
91
  options = [
95
92
  int(option.get_attribute("value"))
96
- for option in owner_session.locator(
97
- ".umap-field-share_status select option"
98
- ).all()
93
+ for option in page.locator(".umap-field-share_status select option").all()
99
94
  ]
100
95
  assert options == [Map.DRAFT, Map.PUBLIC]
101
96
  # This field should not be present in anonymous maps
102
- expect(owner_session.locator(".umap-field-owner")).to_be_hidden()
97
+ expect(page.locator(".umap-field-owner")).to_be_hidden()
103
98
 
104
99
 
105
100
  def test_anonymous_can_add_marker_on_editable_layer(
@@ -180,7 +175,7 @@ def test_alert_message_after_create(
180
175
  new_map = Map.objects.last()
181
176
  expect(alert).to_be_visible()
182
177
  expect(
183
- alert.get_by_text("Your map has been created with an anonymous account!")
178
+ alert.get_by_text("Hey, you created a map without an account!")
184
179
  ).to_be_visible()
185
180
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
186
181
  expect(alert.get_by_role("button", name="Send me the link")).to_be_visible()
@@ -198,7 +193,7 @@ def test_alert_message_after_create(
198
193
  )
199
194
 
200
195
 
201
- def test_email_sending_error_are_catched(tilelayer, page, live_server):
196
+ def test_email_sending_error_are_caught(tilelayer, page, live_server):
202
197
  page.goto(f"{live_server.url}/en/map/new")
203
198
  alert_creation = page.locator('umap-alert-creation div[role="dialog"]')
204
199
  with page.expect_response(re.compile(r".*/map/create/")):
@@ -224,22 +219,22 @@ def test_alert_message_after_create_show_link_even_without_mail(
224
219
  alert = page.locator('umap-alert-creation div[role="dialog"]')
225
220
  expect(alert).to_be_visible()
226
221
  expect(
227
- alert.get_by_text("Your map has been created with an anonymous account!")
222
+ alert.get_by_text("Hey, you created a map without an account!")
228
223
  ).to_be_visible()
229
224
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
230
225
  expect(alert.get_by_role("button", name="Send me the link")).to_be_hidden()
231
226
 
232
227
 
233
- def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session):
228
+ def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session, page):
234
229
  assert Map.objects.count() == 1
235
- owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
236
- owner_session.get_by_role("button", name="Edit").click()
237
- owner_session.get_by_role("button", name="Map advanced properties").click()
238
- owner_session.get_by_text("Advanced actions").click()
239
- expect(owner_session.get_by_role("button", name="Delete")).to_be_visible()
240
- owner_session.get_by_role("button", name="Delete").click()
241
- with owner_session.expect_response(re.compile(r".*/update/delete/.*")):
242
- owner_session.get_by_role("button", name="OK").click()
230
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
231
+ page.get_by_role("button", name="Edit").click()
232
+ page.get_by_role("button", name="Map advanced properties").click()
233
+ page.get_by_text("Advanced actions").click()
234
+ expect(page.get_by_role("button", name="Delete")).to_be_visible()
235
+ page.get_by_role("button", name="Delete").click()
236
+ with page.expect_response(re.compile(r".*/update/delete/.*")):
237
+ page.get_by_role("button", name="OK").click()
243
238
  assert Map.objects.get(pk=anonymap.pk).share_status == Map.DELETED
244
239
 
245
240
 
@@ -251,3 +246,61 @@ def test_non_owner_cannot_see_delete_button(anonymap, live_server, page):
251
246
  page.get_by_role("button", name="Map advanced properties").click()
252
247
  page.get_by_text("Advanced actions").click()
253
248
  expect(page.get_by_role("button", name="Delete")).to_be_hidden()
249
+
250
+
251
+ def test_logged_in_user_should_have_a_message_to_attach_map(
252
+ anonymap, live_server, login, user, page, owner_session
253
+ ):
254
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
255
+ page.get_by_role("button", name="Edit").click()
256
+ expect(
257
+ page.get_by_text(
258
+ "This map is anonymous, do you want to attach it to your account?"
259
+ )
260
+ ).to_be_hidden()
261
+
262
+ page = login(user)
263
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
264
+ page.get_by_role("button", name="Edit").click()
265
+ expect(
266
+ page.get_by_text(
267
+ "This map is anonymous, do you want to attach it to your account?"
268
+ )
269
+ ).to_be_visible()
270
+ with page.expect_response(re.compile(r".*/update/owner/.*")):
271
+ page.get_by_role("button", name="OK").click()
272
+ saved = Map.objects.get(pk=anonymap.pk)
273
+ assert saved.owner
274
+
275
+
276
+ def test_can_attach_map_after_save(
277
+ live_server, user, page, tilelayer, context, settings
278
+ ):
279
+ settings.ENABLE_ACCOUNT_LOGIN = True
280
+ page.goto(f"{live_server.url}/en/map/new")
281
+ expect(page.get_by_role("button", name="Anonymous")).to_be_visible()
282
+ expect(page.get_by_role("button", name="Visibility: Draft")).to_have_class(
283
+ re.compile(r".*anonymous.*")
284
+ )
285
+ assert not Map.objects.count()
286
+ with page.expect_response(re.compile(r".*/map/create/")):
287
+ page.get_by_role("button", name="Save draft", exact=True).click()
288
+ assert Map.objects.count() == 1
289
+ saved = Map.objects.last()
290
+ assert not saved.owner
291
+ with context.expect_page() as login_page_info:
292
+ page.get_by_role("link", name="log in").click()
293
+ login_page = login_page_info.value
294
+ expect(login_page).to_have_title("Login - Online map creator")
295
+ login_page.get_by_placeholder("Username").fill(user.username)
296
+ login_page.get_by_placeholder("Password").fill("123123")
297
+ with page.expect_response(re.compile(r".*/update/owner/")):
298
+ login_page.locator('#login_form input[type="submit"]').click()
299
+ expect(page.get_by_text("Map has been attached to your account")).to_be_visible()
300
+ saved = Map.objects.last()
301
+ assert saved.owner == user
302
+ expect(page.get_by_role("button", name="Anonymous")).to_be_hidden()
303
+ expect(page.get_by_role("button", name=user.username)).to_be_visible()
304
+ expect(page.get_by_role("button", name="Visibility: Draft")).not_to_have_class(
305
+ re.compile(r".*anonymous.*")
306
+ )
@@ -79,7 +79,9 @@ def test_cannot_put_script_tag_in_datalayer_name_or_description(
79
79
  expect(page.get_by_text("before after")).to_be_visible()
80
80
 
81
81
 
82
- def test_login_from_map_page(live_server, page, tilelayer, settings, user, context):
82
+ def test_login_from_map_page_after_save(
83
+ live_server, page, tilelayer, settings, user, context
84
+ ):
83
85
  settings.ENABLE_ACCOUNT_LOGIN = True
84
86
  assert Map.objects.count() == 0
85
87
  page.goto(f"{live_server.url}/en/map/new/")
@@ -102,3 +104,25 @@ def test_login_from_map_page(live_server, page, tilelayer, settings, user, conte
102
104
  assert Map.objects.count() == 1
103
105
  # Use name should now appear on the header toolbar
104
106
  expect(page.get_by_role("button", name="Joe")).to_be_visible()
107
+
108
+
109
+ def test_login_from_unsaved_map_page(
110
+ live_server, page, tilelayer, settings, user, context
111
+ ):
112
+ settings.ENABLE_ACCOUNT_LOGIN = True
113
+ assert Map.objects.count() == 0
114
+ page.goto(f"{live_server.url}/en/map/new/")
115
+ page.locator('[data-ref="user"]').click()
116
+ with context.expect_page() as login_page_info:
117
+ page.get_by_role("button", name="Login").click()
118
+ login_page = login_page_info.value
119
+ expect(login_page).to_have_title("Login - Online map creator")
120
+ login_page.get_by_placeholder("Username").fill(user.username)
121
+ login_page.get_by_placeholder("Password").fill("123123")
122
+ login_page.locator('#login_form input[type="submit"]').click()
123
+ # Login page should be closed
124
+ page.wait_for_timeout(500) # Seems needed from time to time…
125
+ assert len(context.pages) == 1
126
+ # Save should have proceed
127
+ # Use name should now appear on the header toolbar
128
+ expect(page.get_by_role("button", name="Joe")).to_be_visible()
@@ -353,6 +353,43 @@ def test_should_redraw_list_on_feature_delete(live_server, openmap, page, bootst
353
353
  expect(buttons).to_have_count(3)
354
354
 
355
355
 
356
+ def test_should_change_feature_title_and_color_on_edit(
357
+ live_server, openmap, page, bootstrap
358
+ ):
359
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#2/19/-2")
360
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
361
+ "one point in france"
362
+ )
363
+ page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
364
+ page.locator('input[name="name"]').fill("changed name")
365
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
366
+ "changed name"
367
+ )
368
+
369
+ # Change color
370
+ expect(
371
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
372
+ ).to_have_css("background-color", "rgb(0, 0, 139)")
373
+ page.get_by_role("heading", name="Shape properties").click()
374
+ page.locator(".umap-field-color").get_by_role("button", name="define").first.click()
375
+ page.get_by_title("Crimson").click()
376
+ expect(
377
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
378
+ ).to_have_css("background-color", "rgb(220, 20, 60)")
379
+
380
+ # Undo color
381
+ page.locator(".edit-undo").click()
382
+ expect(
383
+ page.get_by_role("listitem").filter(has_text="changed name").locator("i")
384
+ ).to_have_css("background-color", "rgb(0, 0, 139)")
385
+
386
+ # Undo title change
387
+ page.locator(".edit-undo").click()
388
+ expect(page.locator(".umap-browser .feature.marker")).to_contain_text(
389
+ "one point in france"
390
+ )
391
+
392
+
356
393
  def test_should_show_header_for_display_on_load_false(
357
394
  live_server, page, bootstrap, map, datalayer
358
395
  ):
@@ -8,13 +8,6 @@ from ..base import DataLayerFactory
8
8
  pytestmark = pytest.mark.django_db
9
9
 
10
10
 
11
- def getColors(elements):
12
- return [
13
- el.evaluate("e => window.getComputedStyle(e).backgroundColor")
14
- for el in elements.all()
15
- ]
16
-
17
-
18
11
  DATALAYER_DATA1 = {
19
12
  "type": "FeatureCollection",
20
13
  "features": [
@@ -96,6 +89,9 @@ DATALAYER_DATA2 = {
96
89
 
97
90
 
98
91
  def test_simple_equal_rule_at_load(live_server, page, map):
92
+ map.settings["properties"]["fields"] = [
93
+ {"key": "mytype", "type": "String"},
94
+ ]
99
95
  map.settings["properties"]["rules"] = [
100
96
  {"condition": "mytype=odd", "properties": {"color": "aliceblue"}}
101
97
  ]
@@ -103,13 +99,18 @@ def test_simple_equal_rule_at_load(live_server, page, map):
103
99
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
104
100
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
105
101
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
106
- markers = page.locator(".leaflet-marker-icon .icon-container")
102
+ markers = page.locator(".leaflet-marker-icon")
107
103
  expect(markers).to_have_count(5)
108
- colors = getColors(markers)
109
- assert colors.count("rgb(240, 248, 255)") == 3
104
+ markers = page.locator(
105
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
106
+ )
107
+ expect(markers).to_have_count(3)
110
108
 
111
109
 
112
- def test_simple_not_equal_rule_at_load(live_server, page, map):
110
+ def test_simple_not_equal_rule_at_load(live_server, page, map, wait_for_loaded):
111
+ map.settings["properties"]["fields"] = [
112
+ {"key": "mytype", "type": "String"},
113
+ ]
113
114
  map.settings["properties"]["rules"] = [
114
115
  {"condition": "mytype!=even", "properties": {"color": "aliceblue"}}
115
116
  ]
@@ -117,13 +118,19 @@ def test_simple_not_equal_rule_at_load(live_server, page, map):
117
118
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
118
119
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
119
120
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
120
- markers = page.locator(".leaflet-marker-icon .icon-container")
121
+ wait_for_loaded(page)
122
+ markers = page.locator(".leaflet-marker-icon")
121
123
  expect(markers).to_have_count(5)
122
- colors = getColors(markers)
123
- assert colors.count("rgb(240, 248, 255)") == 3
124
+ markers = page.locator(
125
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
126
+ )
127
+ expect(markers).to_have_count(3)
124
128
 
125
129
 
126
130
  def test_gt_rule_with_number_at_load(live_server, page, map):
131
+ map.settings["properties"]["fields"] = [
132
+ {"key": "mynumber", "type": "Number"},
133
+ ]
127
134
  map.settings["properties"]["rules"] = [
128
135
  {"condition": "mynumber>10", "properties": {"color": "aliceblue"}}
129
136
  ]
@@ -133,11 +140,16 @@ def test_gt_rule_with_number_at_load(live_server, page, map):
133
140
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
134
141
  markers = page.locator(".leaflet-marker-icon .icon-container")
135
142
  expect(markers).to_have_count(5)
136
- colors = getColors(markers)
137
- assert colors.count("rgb(240, 248, 255)") == 2
143
+ markers = page.locator(
144
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
145
+ )
146
+ expect(markers).to_have_count(2)
138
147
 
139
148
 
140
149
  def test_lt_rule_with_number_at_load(live_server, page, map):
150
+ map.settings["properties"]["fields"] = [
151
+ {"key": "mynumber", "type": "Number"},
152
+ ]
141
153
  map.settings["properties"]["rules"] = [
142
154
  {"condition": "mynumber<14", "properties": {"color": "aliceblue"}}
143
155
  ]
@@ -147,8 +159,10 @@ def test_lt_rule_with_number_at_load(live_server, page, map):
147
159
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
148
160
  markers = page.locator(".leaflet-marker-icon .icon-container")
149
161
  expect(markers).to_have_count(5)
150
- colors = getColors(markers)
151
- assert colors.count("rgb(240, 248, 255)") == 4
162
+ markers = page.locator(
163
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
164
+ )
165
+ expect(markers).to_have_count(4)
152
166
 
153
167
 
154
168
  def test_lt_rule_with_float_at_load(live_server, page, map):
@@ -161,8 +175,10 @@ def test_lt_rule_with_float_at_load(live_server, page, map):
161
175
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
162
176
  markers = page.locator(".leaflet-marker-icon .icon-container")
163
177
  expect(markers).to_have_count(5)
164
- colors = getColors(markers)
165
- assert colors.count("rgb(240, 248, 255)") == 4
178
+ markers = page.locator(
179
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
180
+ )
181
+ expect(markers).to_have_count(4)
166
182
 
167
183
 
168
184
  def test_equal_rule_with_boolean_at_load(live_server, page, map):
@@ -175,8 +191,10 @@ def test_equal_rule_with_boolean_at_load(live_server, page, map):
175
191
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
176
192
  markers = page.locator(".leaflet-marker-icon .icon-container")
177
193
  expect(markers).to_have_count(5)
178
- colors = getColors(markers)
179
- assert colors.count("rgb(240, 248, 255)") == 2
194
+ markers = page.locator(
195
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
196
+ )
197
+ expect(markers).to_have_count(2)
180
198
 
181
199
 
182
200
  def test_equal_rule_with_boolean_not_true_at_load(live_server, page, map):
@@ -189,8 +207,10 @@ def test_equal_rule_with_boolean_not_true_at_load(live_server, page, map):
189
207
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
190
208
  markers = page.locator(".leaflet-marker-icon .icon-container")
191
209
  expect(markers).to_have_count(5)
192
- colors = getColors(markers)
193
- assert colors.count("rgb(240, 248, 255)") == 3
210
+ markers = page.locator(
211
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
212
+ )
213
+ expect(markers).to_have_count(3)
194
214
 
195
215
 
196
216
  def test_equal_rule_with_boolean_false_at_load(live_server, page, map):
@@ -203,8 +223,10 @@ def test_equal_rule_with_boolean_false_at_load(live_server, page, map):
203
223
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
204
224
  markers = page.locator(".leaflet-marker-icon .icon-container")
205
225
  expect(markers).to_have_count(5)
206
- colors = getColors(markers)
207
- assert colors.count("rgb(240, 248, 255)") == 1
226
+ markers = page.locator(
227
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
228
+ )
229
+ expect(markers).to_have_count(1)
208
230
 
209
231
 
210
232
  def test_equal_rule_with_boolean_not_false_at_load(live_server, page, map):
@@ -217,8 +239,10 @@ def test_equal_rule_with_boolean_not_false_at_load(live_server, page, map):
217
239
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
218
240
  markers = page.locator(".leaflet-marker-icon .icon-container")
219
241
  expect(markers).to_have_count(5)
220
- colors = getColors(markers)
221
- assert colors.count("rgb(240, 248, 255)") == 4
242
+ markers = page.locator(
243
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
244
+ )
245
+ expect(markers).to_have_count(4)
222
246
 
223
247
 
224
248
  def test_empty_rule_at_load(live_server, page, map):
@@ -231,8 +255,10 @@ def test_empty_rule_at_load(live_server, page, map):
231
255
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
232
256
  markers = page.locator(".leaflet-marker-icon .icon-container")
233
257
  expect(markers).to_have_count(5)
234
- colors = getColors(markers)
235
- assert colors.count("rgb(240, 248, 255)") == 3
258
+ markers = page.locator(
259
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
260
+ )
261
+ expect(markers).to_have_count(3)
236
262
 
237
263
 
238
264
  def test_not_empty_rule_at_load(live_server, page, map):
@@ -245,8 +271,10 @@ def test_not_empty_rule_at_load(live_server, page, map):
245
271
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
246
272
  markers = page.locator(".leaflet-marker-icon .icon-container")
247
273
  expect(markers).to_have_count(5)
248
- colors = getColors(markers)
249
- assert colors.count("rgb(240, 248, 255)") == 2
274
+ markers = page.locator(
275
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
276
+ )
277
+ expect(markers).to_have_count(2)
250
278
 
251
279
 
252
280
  def test_can_create_new_rule(live_server, page, openmap):
@@ -263,14 +291,18 @@ def test_can_create_new_rule(live_server, page, openmap):
263
291
  page.locator("input[name=condition]").fill("mytype=odd")
264
292
  page.locator(".umap-field-color .define").first.click()
265
293
  page.get_by_title("AliceBlue").first.click()
266
- colors = getColors(markers)
267
- assert colors.count("rgb(240, 248, 255)") == 3
294
+ markers = page.locator(
295
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
296
+ )
297
+ expect(markers).to_have_count(3)
268
298
  page.locator(".edit-undo").click()
269
- colors = getColors(markers)
270
- assert colors.count("rgb(240, 248, 255)") == 0
299
+ markers = page.locator(
300
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
301
+ )
302
+ expect(markers).to_have_count(0)
271
303
 
272
304
 
273
- def test_can_deactive_rule_from_list(live_server, page, openmap):
305
+ def test_can_deactivate_rule_from_list(live_server, page, openmap):
274
306
  openmap.settings["properties"]["rules"] = [
275
307
  {"condition": "mytype=odd", "properties": {"color": "aliceblue"}}
276
308
  ]
@@ -280,20 +312,36 @@ def test_can_deactive_rule_from_list(live_server, page, openmap):
280
312
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}#6/48.948/1.670")
281
313
  markers = page.locator(".leaflet-marker-icon .icon-container")
282
314
  expect(markers).to_have_count(5)
283
- colors = getColors(markers)
284
- assert colors.count("rgb(240, 248, 255)") == 3
315
+ markers = page.locator(
316
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
317
+ )
318
+ expect(markers).to_have_count(3)
285
319
  page.get_by_role("button", name="Edit").click()
286
320
  page.get_by_role("button", name="Map advanced properties").click()
287
321
  page.get_by_text("Conditional style rules").click()
288
322
  page.get_by_role("button", name="Toggle rule").click()
289
- colors = getColors(markers)
290
- assert colors.count("rgb(240, 248, 255)") == 0
323
+ markers = page.locator(
324
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
325
+ )
326
+ expect(markers).to_have_count(0)
291
327
  page.get_by_role("button", name="Toggle rule").click()
292
- colors = getColors(markers)
293
- assert colors.count("rgb(240, 248, 255)") == 3
328
+ markers = page.locator(
329
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
330
+ )
331
+ expect(markers).to_have_count(3)
294
332
 
295
333
 
296
334
  def test_autocomplete_datalist(live_server, page, openmap):
335
+ openmap.settings["properties"]["fields"] = [
336
+ {"key": "myboolean", "type": "String"},
337
+ {"key": "mytype", "type": "String"},
338
+ {"key": "mynumber", "type": "String"},
339
+ {"key": "mydate", "type": "String"},
340
+ {"key": "name", "type": "String"},
341
+ {"key": "maybeempty", "type": "String"},
342
+ {"key": "onlyinone", "type": "String"},
343
+ ]
344
+ openmap.save()
297
345
  DataLayerFactory(map=openmap, data=DATALAYER_DATA1)
298
346
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.948/1.670")
299
347
  page.get_by_role("button", name="Map advanced properties").click()
@@ -335,10 +383,12 @@ def test_can_combine_rules(live_server, page, map):
335
383
  drops = page.locator(".umap-drop-icon .icon-container")
336
384
  expect(markers).to_have_count(5)
337
385
  expect(drops).to_have_count(2)
338
- colors = getColors(markers)
339
- assert colors.count("rgb(240, 248, 255)") == 3
340
- colors = getColors(drops)
341
- assert colors.count("rgb(240, 248, 255)") == 2
386
+ markers = page.locator(
387
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
388
+ )
389
+ expect(markers).to_have_count(3)
390
+ drops = page.locator('.umap-drop-icon [style*="background-color: aliceblue"]')
391
+ expect(drops).to_have_count(2)
342
392
 
343
393
 
344
394
  def test_first_matching_rule_wins_on_given_property(live_server, page, map):
@@ -352,8 +402,10 @@ def test_first_matching_rule_wins_on_given_property(live_server, page, map):
352
402
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
353
403
  markers = page.locator(".leaflet-marker-icon .icon-container")
354
404
  expect(markers).to_have_count(5)
355
- colors = getColors(markers)
356
- assert colors.count("rgb(240, 248, 255)") == 3
405
+ markers = page.locator(
406
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
407
+ )
408
+ expect(markers).to_have_count(3)
357
409
 
358
410
 
359
411
  def test_rules_from_datalayer(live_server, page, map):
@@ -370,11 +422,14 @@ def test_rules_from_datalayer(live_server, page, map):
370
422
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
371
423
  markers = page.locator(".leaflet-marker-icon .icon-container")
372
424
  expect(markers).to_have_count(5)
373
- colors = getColors(markers)
374
425
  # Alice Blue should only affect layer 1
375
- assert colors.count("rgb(240, 248, 255)") == 1
426
+ markers = page.locator(
427
+ '.leaflet-marker-icon [style*="background-color: aliceblue"]'
428
+ )
429
+ expect(markers).to_have_count(1)
376
430
  # Dark Red as for map global rules
377
- assert colors.count("rgb(139, 0, 0)") == 2
431
+ markers = page.locator('.leaflet-marker-icon [style*="background-color: darkred"]')
432
+ expect(markers).to_have_count(2)
378
433
 
379
434
 
380
435
  def test_rules_in_caption(live_server, page, map):
@@ -176,6 +176,7 @@ def test_can_draw_hole(page, live_server, tilelayer):
176
176
  expect(polygons).to_have_count(1)
177
177
  expect(vertices).to_have_count(4)
178
178
 
179
+ page.wait_for_timeout(300) # Time for the panel animation to finish
179
180
  # First vertex of the hole will be created here
180
181
  map.click(position={"x": 180, "y": 120}, button="right")
181
182
  page.get_by_role("button", name="Start a hole here").click()
@@ -373,6 +374,7 @@ def test_can_clone_polygon(live_server, page, tilelayer, settings):
373
374
  map.click(position={"x": 100, "y": 100})
374
375
  # Click again to finish
375
376
  map.click(position={"x": 100, "y": 100})
377
+ page.wait_for_timeout(300) # Time for the panel animation to finish
376
378
  expect(polygons).to_have_count(1)
377
379
  polygons.first.click(button="right")
378
380
  page.get_by_role("button", name="Clone this feature").click()
@@ -399,6 +401,7 @@ def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings):
399
401
  map.click(position={"x": 100, "y": 100})
400
402
  expect(polygons).to_have_count(1)
401
403
  expect(paths).to_have_count(1)
404
+ page.wait_for_timeout(300) # Time for the panel animation to finish
402
405
  polygons.first.click(button="right")
403
406
  page.get_by_role("button", name="Transform to lines").click()
404
407
  # No more polygons (will fill), but one path, it must be a line
@@ -426,6 +429,8 @@ def test_can_draw_a_polygon_and_invert_it(live_server, page, tilelayer, settings
426
429
  page.get_by_text("Advanced properties").click()
427
430
  page.get_by_text("Display the polygon inverted").click()
428
431
  data = save_and_get_json(page)
432
+ # Close save message
433
+ page.get_by_role("dialog").get_by_role("button", name="Close").click()
429
434
  assert len(data["features"]) == 1
430
435
  assert data["features"][0]["geometry"]["type"] == "Polygon"
431
436
  assert data["features"][0]["geometry"]["coordinates"] == [
@@ -469,6 +474,7 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
469
474
  settings.UMAP_ALLOW_ANONYMOUS = True
470
475
  page.goto(f"{live_server.url}/en/map/new/#15/48.4395/3.3189")
471
476
  page.get_by_title("Import data").click()
477
+ page.wait_for_timeout(300) # Time for the panel animation to finish
472
478
  page.locator(".umap-import textarea").fill(geojson)
473
479
  page.locator('select[name="format"]').select_option("geojson")
474
480
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -261,6 +261,9 @@ def test_can_extract_shape(live_server, page, tilelayer):
261
261
  map.click(position={"x": 200, "y": 200})
262
262
  # Click again to finish
263
263
  map.click(position={"x": 200, "y": 200})
264
+ # Let the panel fully open, not to close the contextmenu (when
265
+ # refocus on panel input)
266
+ page.wait_for_timeout(300)
264
267
  expect(lines).to_have_count(1)
265
268
  lines.first.click(position={"x": 10, "y": 1}, button="right")
266
269
  extract_button.click()
@@ -279,6 +282,9 @@ def test_can_clone_polyline(live_server, page, tilelayer, settings):
279
282
  map.click(position={"x": 100, "y": 200})
280
283
  # Click again to finish
281
284
  map.click(position={"x": 100, "y": 200})
285
+ # Let the panel fully open, not to close the contextmenu (when
286
+ # refocus on panel input)
287
+ page.wait_for_timeout(300)
282
288
  expect(lines).to_have_count(1)
283
289
  lines.first.click(position={"x": 10, "y": 1}, button="right")
284
290
  page.get_by_role("button", name="Clone this feature").click()
@@ -304,6 +310,8 @@ def test_can_transform_polyline_to_polygon(live_server, page, tilelayer, setting
304
310
  map.click(position={"x": 100, "y": 200})
305
311
  # Click again to finish
306
312
  map.click(position={"x": 100, "y": 200})
313
+ page.wait_for_timeout(300) # Time for the panel animation to finish
314
+
307
315
  expect(paths).to_have_count(1)
308
316
  expect(polygons).to_have_count(0)
309
317
  paths.first.click(position={"x": 10, "y": 1}, button="right")
@@ -324,6 +332,9 @@ def test_can_delete_shape_using_toolbar(live_server, page, tilelayer, settings):
324
332
  map.click(position={"x": 100, "y": 100})
325
333
  map.click(position={"x": 100, "y": 200})
326
334
  map.click(position={"x": 100, "y": 200})
335
+ # Let the panel fully open, not to close the contextmenu (when
336
+ # refocus on panel input)
337
+ page.wait_for_timeout(300)
327
338
 
328
339
  # Now split the line
329
340
  map.click(position={"x": 100, "y": 100}, button="right")