Corrige la régression du correctif overlay : /elements/<id>/geometry plantait (500)

Le correctif précédent (81c31a9) retirait TOUTE position/taille du cadre
.canvasElement/.playElement d'une "superposition" pour ne plus piéger son
propre z-index:9999 dans un contexte d'empilement local — mais ce même
cadre sert aussi, dans l'ÉDITEUR, de prise pour le glisser-déposer/
redimensionnement de ce widget (screen_edit.html). Sans
position:absolute + left/top/width/height, ce cadre s'effondre à 0×0 (son
contenu réel est en position:fixed, hors flux) : le calcul de geometrie
divise alors par une dimension nulle, produit NaN, et
JSON.stringify(NaN) envoie littéralement "null" au serveur — qui plantait
sur float(None) dans routes/elements/element_geometry.py (500, reproduit
par l'utilisateur en posant un template lié à un objet et en essayant de
repositionner l'overlay dans l'éditeur).

Correctif plus ciblé : le cadre garde position/left/top/width/height comme
n'importe quel widget (l'éditeur redevient fonctionnel) — SEUL le z-index
est omis pour ce widget précis. position:absolute SANS z-index explicite
(donc z-index:auto) ne crée PAS de nouveau contexte d'empilement CSS :
le z-index:9999 posé plus profond (render_overlay.py) continue donc de se
comparer directement aux autres éléments de l'écran, et gagne toujours —
le bug de superposition visuelle (81c31a9) reste corrigé, sans regression
sur l'éditeur cette fois.

test_confort.py mis à jour (position:absolute attendu, plus d'assertion
"position:static") + nouveau test qui appelle directement la route
/geometry sur une superposition pour confirmer qu'elle répond 200.
137 tests au vert au total.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-08-28 06:07:08 +02:00
co-authored by Claude Sonnet 5
parent 5c069ae1fe
commit 7c0f1ed427
2 changed files with 61 additions and 27 deletions
+34 -11
View File
@@ -184,15 +184,19 @@ def test_overlay_widget_renders_fullscreen_fixed_box(client, game):
def test_overlay_wrapper_does_not_trap_its_own_z_index(client, game):
"""Régression : le cadre .playElement/.canvasElement partagé par TOUS
les widgets (voir filters/element_style_filter.py) posait quand même
"position:absolute; z-index:<sa place dans le canevas>" sur la
superposition, MÊME SI son propre contenu (render_overlay.py) ignore
x/y/width/height et pose déjà position:fixed + z-index:9999 lui-même.
Un élément positionné avec un z-index explicite crée un NOUVEAU contexte
d'empilement CSS : le 9999 posé plus profond ne se comparait alors plus
qu'AU SEIN de ce contexte, et perdait face au z-index (plus grand) d'un
élément normal ajouté APRÈS l'overlay sur le canevas — qui s'affichait
donc PAR-DESSUS le dialogue censé tout couvrir. Le cadre ne doit donc
plus poser aucune position/z-index pour ce widget."""
"z-index:<sa place dans le canevas>" sur la superposition, MÊME SI son
propre contenu (render_overlay.py) ignore x/y/width/height et pose déjà
position:fixed + z-index:9999 lui-même. Un élément positionné avec un
z-index EXPLICITE crée un NOUVEAU contexte d'empilement CSS : le 9999
posé plus profond ne se comparait alors plus qu'AU SEIN de ce contexte,
et perdait face au z-index (plus grand) d'un élément normal ajouté
APRÈS l'overlay sur le canevas — qui s'affichait donc PAR-DESSUS le
dialogue censé tout couvrir. Le cadre garde position/left/top/width/
height comme tout widget (l'éditeur en a besoin pour glisser-déposer/
redimensionner ce cadre — les retirer a fait planter element_geometry
en régression), mais n'écrit plus DU TOUT de z-index pour ce widget :
position:absolute avec z-index:auto (omis) ne crée pas de contexte
d'empilement, donc le 9999 se compare directement aux autres éléments."""
screen_id = _create_screen(client, game)
overlay_id = _add_element(client, game, screen_id, "superposition")
# Ajouté APRÈS l'overlay -> z_index plus grand que le sien.
@@ -204,8 +208,27 @@ def test_overlay_wrapper_does_not_trap_its_own_z_index(client, game):
assert idx != -1
tag_start = html.rfind("<div", 0, idx)
wrapper_tag = html[tag_start:idx + 200]
assert "position:static" in wrapper_tag
assert "position:absolute" not in wrapper_tag
assert "position:absolute" in wrapper_tag
assert "z-index" not in wrapper_tag
def test_overlay_geometry_can_still_be_saved_from_the_editor(client, game):
"""Régression : la première version du correctif ci-dessus retirait
AUSSI position/left/top/width/height du cadre d'une superposition, ce
qui effondrait ce cadre à 0×0 dans l'ÉDITEUR (son contenu réel est en
position:fixed, hors flux) — le calcul de glisser-déposer/
redimensionnement (screen_edit.html) divise alors par une dimension
nulle, produit NaN, et JSON.stringify(NaN) envoie "null" : le serveur
plantait sur float(None) dans element_geometry.py. Le cadre doit donc
continuer à porter une position/taille en % normale pour ce widget."""
screen_id = _create_screen(client, game)
overlay_id = _add_element(client, game, screen_id, "superposition")
resp = client.post(
f"/game/{game}/elements/{overlay_id}/geometry",
data=json.dumps({"x": 12.5, "y": 20, "width": 55, "height": 45}),
content_type="application/json",
)
assert resp.status_code == 200
def test_overlay_starts_hidden_by_default(client, game):